Inspiration

Usage-based billing is the part of the stack every B2B SaaS company dreads building — and for good reason. Get it wrong in one direction and you drop events (lost revenue you can never recover). Get it wrong in the other and you double-bill customers (churn and chargebacks). The hard part was never the UI; it's the database. A billing meter has to be strongly consistent, never double-count, and agree with itself everywhere, always.

That's exactly the guarantee Aurora DSQL offers: serverless, strongly-consistent, active-active, Postgres-compatible, with no primary/replica to manage and no failover to babysit. So we set out to test a thesis: the database is the product. Build the billing ledger that DSQL makes possible, and the rest of a billing platform falls out of it.

What it does

Ledgerline is usage-based billing infrastructure for B2B SaaS, built on Aurora DSQL. It meters usage events, buffers them so they're never dropped, records them so they're never double-counted, accrues per-customer running costs, and rolls them up into invoices — all on a single, strongly-consistent ledger.

It sells two guarantees:

  • Never dropped — every billable event is buffered on Amazon SQS, decoupled from the database, so a traffic spike or a momentary DB hiccup never loses revenue.
  • Never double-counted — each event carries an idempotency_key with a unique constraint, so a re-delivered message lands at most once:

$$\bigl|{\text{rows with key } k}\bigr| \le 1 \quad \forall\, k$$

On top of the meter, Ledgerline grew into a full billing surface:

  • Tiered / volume pricing, plans & subscriptions (base fee + included allowance + overage), and minimum-commitment true-ups
  • Prepaid credit drawdown, credits & corrections (append-only, never an edit)
  • Spend-threshold alerts via Amazon SNS, a live pipeline-health panel, and a revenue-analytics dashboard
  • A pricing simulator that replays the entire event ledger through a draft rate card to show the exact revenue delta
  • Time-travel — recompute every customer's meter as of any past instant
  • Hosted/printable invoices and outbound webhooks with a live delivery log

How we built it

  • Aurora DSQL is the single source of truth — an eight-table ledger (customers, usage_events, pricing, plans, credit_grants, invoices, webhook_endpoints, webhook_deliveries). DSQL's one real gotcha is auth: the database "password" is a short-lived IAM token, so we isolated an async token-minting connection layer.
  • Ingest pipeline: POST /api/ingest enqueues to Amazon SQS → a drainer Lambda performs the idempotent write (INSERT … ON CONFLICT (idempotency_key) DO NOTHING) → DSQL.
  • Roll-up: an Amazon EventBridge Scheduler fires a roll-up Lambda that aggregates a cycle into an invoice (upsert per customer + period, so re-running never duplicates).
  • Frontend & API: Next.js (App Router) on Vercel, with all billing math in one shared TypeScript engine so the meter, charts, and invoices can never disagree. Graduated pricing is computed as a banded sum:

$$\text{cost}(q)=\sum_{i} p_i\cdot\bigl(\min(q,u_i)-u_{i-1}\bigr)^{+}$$

  • Security: a shared-secret write guard delivered to reviewers via a magic link, least-privilege IAM per component, and an SSRF-hardened webhook sender.

Challenges we ran into

  • DSQL is Postgres, but a deliberate subset. No foreign keys, indexes must be CREATE INDEX ASYNC, only one DDL per transaction, and ALTER TABLE … ADD COLUMN can't carry a DEFAULT. We learned these the way everyone does — one error message at a time — and encoded them into our DDL.
  • Optimistic concurrency control. Our stress test fires hundreds of concurrent writes with overlapping keys; DSQL correctly raises serialization conflicts (SQLSTATE 40001). We added retry-with-jittered-backoff — and then turned it into a feature, surfacing "concurrency conflicts serialized" as proof the database is doing its job.
  • Keeping every view consistent. When we added volume tiers and then plan overage, we had to make the breakdown and the cumulative daily series tier-aware, so the live meter, the spend chart, and the issued invoice always reconcile to the same number.
  • Security, iteratively. Automated reviews caught a same-origin auth bypass (fixed to key-only) and an SSRF hole in webhooks (string denylists are bypassable via DNS rebinding, redirects, and numeric IP encodings). We hardened it with real DNS resolution, ipaddr.js range checks, and manual redirect re-validation.

Accomplishments that we're proud of

  • Proving the thesis on camera. A built-in consistency test fires 250 concurrent writes with deliberate duplicates and lands 0 double-counts — while DSQL catches and serializes real write conflicts. That's the whole pitch in fifteen seconds.
  • Two features only a strongly-consistent, complete ledger makes possible: the pricing simulator (re-derive revenue under any rate card, exactly) and time-travel (reconstruct the meter at any instant).
  • Depth at zero cost. ~20 billing features, end-to-end, on a single-region DSQL ledger — and the entire AWS footprint (DSQL, SQS, Lambda, SNS, EventBridge) ran inside the free tier for ≈ \$0.
  • Every security finding resolved, with least-privilege IAM throughout.

What we learned

  • DSQL is a genuinely great fit for a ledger. Strong consistency + serverless + Postgres compatibility removed an entire category of "is the meter actually right?" anxiety. The IAM-token auth and a handful of subset quirks are the only real learning curve.
  • A complete, append-only, strongly-consistent event log is a superpower. Because every event is recorded exactly once and never mutated, you can re-price history under any rate card (the simulator) and reconstruct state at any past instant (time-travel) — exactly, not approximately. The ledger isn't just storage; it's the product.
  • With OCC, you design for retries, not locks. Embracing that made the system both correct and demonstrably so.

What's next for Ledgerline - Usage-based billing infrastructure for B2B SaaS

  • Multi-region DSQL — the narrated design intent made real: "same totals everywhere" with active-active writes across regions.
  • S3 raw-event archive for long-term replay and audit, closing the loop on durability.
  • Payments & finance — Stripe collection, dunning, tax, and revenue-recognition schedules.
  • Developer platform — per-customer API keys, typed SDKs, signed webhooks with retries + a dead-letter queue, and more pricing models (matrix, package).
  • Real multi-tenant auth to take it from a strongly-consistent meter to a production billing system.

Built With

Share this project:

Updates