Engineering
· 9 min read

How we built atomic label purchases

A deep dive into the SQL function that guarantees you’re never charged for a label that didn’t print.

A label purchase touches three things: an external API (EasyPost), a wallet ledger, and a label record. Get the order wrong and you have impossible state — money deducted but no label, label exists but no charge.

The order matters

We always call EasyPost FIRST. If EasyPost returns success, then we run a single Postgres function that does the wallet deduction and label insertion in one transaction.

The function

purchase_label_atomic locks the wallet row with SELECT FOR UPDATE, validates balance, decrements, inserts the wallet_transactions row, inserts the label row with the void window expiry, and returns the label id. If any step fails the entire transaction rolls back — and the caller voids the EasyPost label.

Why a SQL function and not application code

Three reasons. (1) Single source of truth — the wallet/label invariant lives in the database, not scattered across services. (2) Lock granularity — a SECURITY DEFINER function holds the row lock for milliseconds, not the round-trip duration of an API call. (3) Auditability — RLS still applies, every change is logged.

Ready to ship faster?

Start with a free trial — no credit card needed for sandbox mode.