Case Study — SaaS Product Engineering

Polling on the ETA, Not the Clock

Meridian is a multi-tenant ocean-container tracking platform — 11 carriers normalized into one canonical schema, PostgreSQL Row-Level Security on every table, credit-ledger billing, and an adaptive polling scheduler that anchors every vendor API call to the vessel's predicted arrival instead of a cron clock.

~6×
Fewer vendor API calls
11
Carriers, one normalizer
12
Postgres tables, 100% RLS
~10
Polls per voyage (was ~60)
Role Architect & Lead Engineer
Stack Node.js / PostgreSQL 16 / Redis / React
Product Meridian — meridianintel.co
01 — The Problem

The Cheapest Poll Is the One You Don't Make

A maritime logistics operator needed real-time visibility into ocean containers — where is the vessel, when does the box land, has anything slipped. The data exists: commercial tracking data providers expose it through clean APIs. The catch is the billing model. Those providers charge per API call, not per shipment. Every status check costs money whether or not anything changed.

The naive design — poll every active shipment on a flat 2×/day cron — burns roughly 60 polls over a 30-day voyage. And almost all of them are wasted. Container status is coarse: a box sits in IN_TRANSIT for the entire crossing and flips to ARRIVED exactly once. Fifty-nine of those sixty polls return the same answer as the poll before. Per-call vendor billing made flat polling uneconomical — the tracking data would have cost more than the tracking product could charge for it.

But you cannot simply poll less. Miss the arrival window and the customer's first notification of their own cargo landing comes from the port, not from you — which is the one failure mode a tracking product cannot survive. The problem, precisely stated: minimize vendor API calls without ever being late to an arrival.

The key observation is that the arrival isn't random. The provider's own payload carries a predicted ETA for the final destination, and it's the only event that matters. So instead of polling on a clock, Meridian polls on the ETA.

02 — Architecture

A Multi-Tenant Platform Built for Untrusted Boundaries

Meridian is not a script wrapped around a vendor API — it's a tenanted SaaS with database-enforced isolation, append-only billing, and a normalization layer that makes eleven heterogeneous carrier feeds look like one.

React 18 SPA Keycloak PKCE tenant-scoped JWT God View (admin) HTTPS MERIDIAN API Node 20 · Express + Helmet ① tenant context → RLS session ② credit ledger debit (append-only) ③ provider router + circuit breaker ④ normalize → canonical schema ⑤ adaptive scheduler → next_poll_at ⑥ HMAC-SHA256 webhook sign ⑦ Prometheus /metrics Tracking Providers commercial data feeds per-call billing fallback chain PostgreSQL 16 12 tables · FORCE RLS credit_ledger append-only next_poll_at per MBL Tenant Webhooks HMAC-SHA256 signed Redis 7 tracking cache dedupe repeat lookups Observability Prometheus /metrics Grafana dashboards poll-phase counters

Tenant isolation is not enforced in application code — it's enforced by the database. All twelve tables carry Row-Level Security policies with FORCE applied, so even a query written without a tenant filter physically cannot read another tenant's rows. The API resolves the tenant from the authenticated session and sets it as the Postgres session context; from that point the database is the guard, not the ORM. The admin "God View" console — full cross-tenant visibility for operations — sits behind Keycloak with a separate role, and is the only path that legitimately crosses the boundary.

Billing follows the same discipline. Every trackable action debits a credit ledger that is append-only by design: balances are derived, never mutated, so a billing dispute is answered by replaying the ledger rather than trusting a counter. Upstream, an 11-carrier normalization layer maps each carrier's idiosyncratic feed — different field names, date formats, milestone vocabularies — into one canonical shipment schema, with a provider router that falls back across commercial tracking data providers behind a circuit breaker: five consecutive failures open the breaker and fast-fail for a cooldown window instead of hammering a degraded vendor. Outbound, every tenant webhook is HMAC-SHA256 signed so consumers can verify payload origin before acting on it.

"Tenant isolation you enforce in application code is a convention. Tenant isolation you enforce in the database is a guarantee."
03 — The Adaptive Scheduler

Every Poll Is Scheduled Against the Vessel's Predicted Arrival

The scheduler is a pure, dependency-free function: give it the shipment's status and the provider's final-destination ETA, it returns the next poll timestamp. Sparse mid-ocean, dense on approach, relentless when overdue — and never more than five days silent.

DAY 0 DAY 10 DAY 20 DAY 30 ETA ETA − 3d FLAT 2×/DAY ~60 polls ADAPTIVE ~10 polls baseline cruise — every 5 days daily
01
Register
Baseline
1 poll — status + ETA
02
No ETA yet
Probe
every 2 days
03
ETA > 3d away
Cruise
every 5 days
04
ETA ≤ 3d away
Approach
daily
05
ETA passed
Overdue
daily until terminal
1

Phase Model Keyed to Status + ETA

Each poll returns the shipment's status and the provider's eta_final_destination. A pure function maps that pair to a phase: cruise (ETA more than 3 days out) polls every 5 days as a cheap heartbeat that keeps the ETA fresh and catches big schedule slips; approach (within 3 days of ETA) polls daily to catch the arrival flip; overdue (ETA passed, still in transit — a delayed vessel) stays daily until resolution. Terminal states — arrived, delivered, unresolvable — stop polling entirely. A shipment with no usable ETA yet probes every 2 days until the carrier data catches up.

2

The Cruise Clamp — Never Overshoot the Approach Window

The subtle bug in any phase scheduler: if the ETA is 4 days out and the cruise cadence is 5 days, a naive implementation schedules the next poll after the vessel has already arrived — skipping the entire daily approach phase. Meridian clamps the cruise interval so the next poll lands exactly at the approach boundary (ETA − 3d), floored at one day so it is never sub-daily. The scheduler can be sparse, but it can never be late.

3

The 5-Day Hard Backstop

The scheduler trusts the provider's ETA — but only so far. A wildly wrong ETA (a vessel rerouted, a data glitch reporting arrival months out) could otherwise defer a shipment indefinitely. A hard backstop guarantees no active shipment is ever deferred more than 5 days, whatever the ETA claims. Worst case, a bad ETA costs a few extra heartbeat polls — it can never strand a customer's cargo in the dark.

4

Shadow Mode Before Enforcement

The scheduler shipped behind an ADAPTIVE_POLLING flag with a shadow default: the system kept polling everyone exactly as before — zero behavior change — while logging what the adaptive scheduler would have done on every cycle: how many shipments were due, how many would have been deferred, and the projected call savings. Only after the shadow numbers validated against real arrivals over live poll cycles was the flag flipped to enforce. Rollback is unsetting an environment variable — no redeploy, no migration.

5

Pure Function, Unit-Tested, Observable

The entire cadence logic is a dependency-free pure module — status and ETA in, next poll timestamp out — which makes every phase transition unit-testable without a database or a mock vendor. The persisted next_poll_at column makes the scheduler's decisions inspectable in SQL, and phase labels flow into Prometheus counters so the cruise/approach/overdue distribution is visible on a Grafana dashboard, not inferred from logs.

"Fifty-nine of sixty polls return the same answer as the poll before. The engineering problem was never fetching the data — it was refusing to fetch it."
04 — Proof

What Shipped, and What It Changed

The adaptive scheduler restored the product's unit economics without sacrificing a single arrival notification — and it shipped with the guardrails a production billing system demands.

~6×
Fewer vendor API calls
~10
Polls per voyage (was ~60)
100%
Tables under Force RLS
5d
Max unchecked — hard backstop

Eleven Carriers, One Schema

The normalization layer collapses eleven heterogeneous carrier feeds — divergent field names, milestone vocabularies, date formats — into one canonical shipment shape. Every downstream consumer, from the React dashboard to tenant webhooks, codes against a single contract regardless of which carrier moved the box.

Isolation the Database Enforces

All twelve Postgres tables run Row-Level Security with FORCE applied, so tenant isolation holds even against queries that forget the tenant filter. The credit ledger is append-only — balances are replayed, never mutated — making every billed action auditable.

CI-Gated on Every Push

A Newman-driven Postman collection exercises the API end-to-end in CI on every push — auth flows, tenant boundaries, tracking registration, webhook contracts. The scheduler's phase logic carries its own unit suite, so a cadence regression fails the build before it ever burns a vendor call.

Observable by Default

A Prometheus /metrics endpoint exposes poll counts, phase distribution, provider errors, and circuit-breaker state to Grafana. When a provider degrades or a cadence drifts, the dashboard shows it before a customer does.

Node 20 Express + Helmet PostgreSQL 16 (Force RLS) Redis 7 React 18 + Vite Keycloak (PKCE) n8n Docker / Coolify / Traefik Prometheus + Grafana OpenAPI 3

Building a Product Where the API Bill Is the Business Model?

I design systems where the economics are engineered, not hoped for — metered vendors, multi-tenant isolation, and rollouts that can be reversed with a flag.

Let's Work Together
VIEW LIVE → VERIFIED DELIVERY RECORD →