What we build
Payment & real-time systems
We build the systems that move money and state in real time - settlement, collection, credit, order flow, execution. The architecture is event-driven by default: messages that arrive once, state that reconciles, and a hot path kept clear of anything that can block it. We have shipped it at national banking scale and at a million users.
Settlement & payment flows
Real-time gross settlement, enforced collection, and credit services - built for a national banking system that processes millions of transactions a day.
Bank & partner integration
We integrated the 22 banks that make up a national banking system onto those services end to end - rollout, partner onboarding, and training included.
Real-time platforms
Event-driven platforms on Kafka, RabbitMQ, and DynamoDB - one carrying more than a million users, one executing trades inside 100ms of a price change.
Correctness under load
Idempotency, retries, and reconciliation designed in per flow - so a retry is not a double payment and a slow consumer is not a lost order.
The path
Where exactly-once stops holding.
One writer commits the state change and its event together, the log carries them in order per account, and past the boundary a retry is answered by a key rather than a promise.
An instruction arrives carrying an idempotency key supplied by the caller and derived from the business event. A single writer commits the state change and the outgoing outbox row in one local transaction, so both land or neither does; a second arrival with the same key returns the stored response. A relay publishes the outbox to Kafka, partitioned by account so order holds per account. Two consumers read the log: a ledger that posts one entry per instruction and derives the balance from those entries, and a settlement consumer that records the attempt before it calls out. That outbound call crosses the boundary. Inside the boundary exactly-once can hold, because the effect and the record of it land in the same commit. Past it only at-least-once holds, so the same key travels on the request and the acknowledgement may be lost. Reconciliation reads our entries and the counterparty's own statement independently and compares them.
01
instruction
idempotency key, supplied by the caller
derived from the business event, not from the retry
02
single writer
one local transaction
state change
+ idempotency key
outbox row
the outgoing event
both rows land, or neither
same key again → stored response
03
kafka
partition key: account, so order holds per account
producer id + sequence drops a retried batch
04
ledger
one entry per instruction
balance = sum of entries, replayable from the log
05
settlement
records the attempt before it calls out
a crash asks what happened to the key, it does not refire
06
counterparty
past the boundary
at-least-once only. no transaction spans both.
- card network, bank core, or a partner api
- the same key travels on the request
- the ack may be lost, so the retry has to be free
07
reconciliation
our entries against their own statement
independent inputs, breaks classified and owned
What you get
Yours to keep, and to run.
- ✓A production system you own outright - code, infrastructure, and event model
- ✓Message contracts and schemas your team can extend without us
- ✓Idempotency, retry, and reconciliation documented per flow
- ✓Dashboards, alarms, and a runbook covering failure, replay, and rollback