Skip to content
owen/richards
All writing
7 min read

In Postgres, COMMIT is final. On a blockchain, a transaction becomes final in stages. Here's how I'd map Solana's and Ethereum's commitment levels onto ledger states, written from the reconciler side.

Learning in public. I haven’t shipped anything on-chain yet. These posts map what I know from production payments and ledgers onto how blockchains handle the same problems.

The FieldDay ledger lives in Postgres, and Postgres gives me a gift I didn't appreciate until I started learning how blockchains work: when COMMIT returns, the row is there. There's no "probably committed", no waiting for more commits to stack on top before I trust it.

Blockchains don't work that way. A transaction becomes final in stages, and the job of anyone building a ledger on top is deciding which stage is good enough for which action. I'm self-taught here, and this is how I've come to think about it from the reconciliation side, which is the side I know.

Solana: processed, confirmed, finalized.

When you ask a Solana RPC node about a transaction, you also pick a commitment level:

  • Processed. The node you asked has executed it in a block. That block might still be skipped by the rest of the cluster, so this is one machine's opinion.
  • Confirmed. Validators holding more than two-thirds of the stake have voted on the block. That's a supermajority, and on mainnet a confirmed block being rolled back would take a serious failure. It's the level most apps treat as "done" for display.
  • Finalized. The block has reached maximum vote lockout, roughly 31 more confirmed blocks built on top. At that point it's effectively irreversible.

Since Solana moved to 200ms slots on October 9, 2026, finalized arrives in a handful of seconds rather than the ten-plus it used to take. A larger change is coming: Alpenglow, a new consensus design targeting finality in around 150ms. As I write this, it's running on devnet and testnet but has no mainnet date, so I'm treating it as future work, not something to design around.

Ethereum: latest, safe, finalized.

Ethereum's RPC exposes the same idea as block tags:

  • Latest is the newest block. It can still be reorganized out.
  • Safe is backed by a justified checkpoint, meaning two-thirds of validators have attested to it. Reverting it would take something going badly wrong.
  • Finalized typically takes about two epochs, around 13 minutes, and reverting it would require a third of all staked ETH to be destroyed. It can take longer if validator participation drops, so poll the finalized tag rather than hard-coding a duration.

Thirteen minutes versus a few seconds is a large product difference, and it's one reason payments-shaped apps keep landing on fast-finality chains.

The ledger states I'd use.

My instinct as a ledger person is to make finality an explicit column, not something each caller decides for itself. An incoming on-chain deposit would move through three states:

Ledger stateChain signalWhat the user seesWhat they can do
seenprocessed"Incoming"Nothing yet
pendingconfirmed / safeBalance shown as pendingLow-risk, reversible actions
settledfinalizedAvailable balanceWithdraw, pay out, anything irreversible

The rule underneath is the one I already use for payouts: the irreversibility of the action decides the finality you wait for. Showing a number on screen can use a weak signal. Releasing money can't. The RPC docs I've read land in the same place: safe for small or reversible actions, finalized for settlement and withdrawals.

Reorgs are compensating entries, not deletes.

The scary case is a block you recorded at processed or confirmed that never becomes finalized, because the cluster moved on without it. The tempting fix is to delete the row. In an append-only ledger you don't delete rows. You write the correction.

So a dropped deposit becomes a reversal entry pointing at the original, with the reason recorded. The balance comes out the same as a delete, and the history still shows that the system believed something for a few seconds and then corrected it. That's the audit trail you want when someone asks why a balance flickered.

That only works if every on-chain row carries enough to check it later: the transaction signature (or hash), the slot or block number, and the commitment level it was recorded at. Those three columns are what make a reorg a query instead of an investigation.

The reconciler is the real finality.

The part of FieldDay's ledger work I'd carry over first isn't the schema. It's the reconciler: a daily job that recomputes the transfers it expects from one record, diffs them against the other, and reports every orphan by class. It's detection-only. It never fixes anything, because a reconciler that auto-heals is one you've stopped trusting.

On-chain, I'd point the same shape at the chain. The chain is the source of truth, and the reconciler walks finalized blocks for the accounts I care about and diffs them against my ledger:

  • On-chain but not in my ledger: an indexer or webhook dropped it. The ingestion path, not the reconciler, re-ingests it, keyed on the signature.
  • In my ledger but never finalized on-chain: a reorg or a dropped transaction. The deposit pipeline should already have written the reversal when the commitment check failed. If the reconciler finds one first, that pipeline has a bug.
  • Present in both but different: a parsing bug. Page someone.

Indexers and webhooks deliver at least once, at best. A deposit consumer that isn't idempotent on the transaction signature will eventually credit someone twice, which is the same lesson as replay protection from the other side.

What carries over.

Very little of this is new to anyone who has run a payments ledger. Card payments already have authorized versus settled, ACH has returns days after the money "arrived", and Stripe has webhooks that arrive late and out of order. Blockchains name the stages more honestly and move through them faster. The discipline is the same: make the state explicit, wait for the finality the action deserves, and reconcile against the source of truth instead of trusting the happy path.

Owen

Thanks for reading. Cheers.

If you spot something wrong in this post, or you’d have done it differently, tell me. I’d rather be corrected than confidently wrong. owenlrichards2000@gmail.com

— Owen