6 posts

Writing

Notes on building software: architecture, data modelling, and the failure modes that only show up in production. A lot of it comes out of working in fintech.

  1. Optimistic locking fails on the row you care about

    Optimistic and pessimistic control aren't a performance preference, they're a claim about how writes are spread across keys. Production concentrates them on a handful of rows, which is where the optimistic bet loses, and where the better answer is often to stop having a contended row at all.

    16 min read
  2. Double-entry as a data model, not an accounting concept

    Every transaction sums to zero isn't accounting vocabulary, it's an invariant a database can enforce. What changes when the balance stops being a column you update and becomes a number you derive.

    15 min read
  3. The provider timed out after committing

    A request that never came back has three possible histories and one symptom. Why "unknown" has to be a state your system holds rather than an error it handles, and what that changes in the schema, the ledger and the timeout config.

    13 min read
  4. Reconciliation is a design input, not an ops task

    Deciding at the end how to prove your ledger matches the provider's is already too late. What changes in the schema once you assume you'll be reconciling every day, forever.

    12 min read
  5. Idempotency is not a key, it's a contract

    Adding an Idempotency-Key header is the easy part. The contract is what counts as the same request, how long the promise lasts, what a retry gets while the first attempt is still running, and which failures are worth remembering.

    13 min read
  6. Money as a data type

    A number and a currency code are not the same thing as an amount of money. What modelling money as a plain float costs, and what the alternative looks like.

    12 min read