Case Study

Financial Transaction Processing and Balance Management

A specialised ledger database for ordered transfers, reservations and recoverable storage.

This payment ledger architecture keeps the ledger engine apart from the application around it. The engine applies debits and credits. Applications see a model of accounts and the transfers between them. The application around it keeps customer profiles, supplies authorization and groups requests into batches. Every transfer runs through a replicated state machine, which fixes its order and its effect on balances.

The challenge

Losing a response does not tell the caller whether its transfer ran. A resend must not create a second transfer. An old insufficient-funds request must not quietly succeed just because the money arrived later. That decision has to hold across replicas, and damaged local storage needs a way back to a good state.

What we built

A transfer names a debit account, a credit account and an amount, and the two accounts must differ while belonging to the same ledger. Fixed operations create, look up and query these records. A pending transfer first reserves funds.

A later record can post all or part of a reservation or void it, and it keeps a link back to the original instruction. A set timeout can expire the reservation. Linked transfers can form an atomic group that shares one outcome.

Load the batch before changing balances

The primary replica checks and journals a batch, then replicates the batch to the other replicas. Before it runs, the engine loads the accounts and transfers it will need. The operations then run in order, with no pause for disk or network access partway through a balance update. Balances are stored as unsigned integers. Every change runs through an overflow check before it is applied. A transfer record cannot be changed after it is created.

Keep the request's identity

Callers generate and keep a transfer identifier before they submit the request to the engine. Matching details under that identifier return the existing record, while other details flag a mismatch. A failed attempt can keep its identifier marked as failed, which is what stops an old insufficient-funds request from succeeding later. Session numbers and checksums catch in-flight repeats. Stored replies then let the caller recover cleanly after a lost response.

Repair from matching replicated state

Viewstamped Replication uses a hash-chained journal, checkpoints and checksummed blocks. Because every replica builds the same deterministic physical state, a damaged block can be rebuilt from any peer that holds a matching copy. Reservation expiry is a consensus operation, which means the replicas agree on when a hold ends.

Project success

Applications can post transfers, reserve funds and follow the records that resolve those reservations. Retry responses are defined, and damaged storage has a peer-repair path. Customer management and public access stay outside the engine, while the application around it submits its work in batches.

Technology stack

Implementation

Zig

Replication

Viewstamped Replication

Storage

Hash-chained journal, checksummed blocks, LSM structures

Client protocol

Batched binary requests

Integration options

C, Go, Java, .NET, Node.js, Python, Ruby and Rust clients

Recognize the pattern?

If one of these looks like your situation, the discovery call is where we find out how close.