A single ISO 20022 switch that clears money on both FedNow and RTP in under 800 milliseconds, at scale, and without ever paying the same dollar twice.
Instant-payment rails do not forgive latency. FedNow and RTP both expect a participant to accept or reject within a hard window, and a miss means a timeout that the customer feels as a failed transfer. The switch treats 800ms as a budget, not a target, every hop is metered.
The dominant cost is the liquidity check. Rather than calling the rail optimistically and reconciling later, the switch reserves funds in PostgreSQL under serializable isolation before submission. That single decision moves correctness upstream of the network and keeps the tail latency flat under load.
Two defenses stack. Inbound messages carry an end-to-end ID that becomes an idempotency key at the Kafka edge, so a redelivered pacs.008 collapses to a no-op. Below that, the ledger reservation is an atomic debit-with-check, a second attempt against already-reserved funds fails as a constraint violation rather than a lost race.
The result is that 'zero double-spends' is not a monitoring statistic we got lucky on; it is a property the data model enforces. The rail can retry, Kafka can replay, and a pod can crash mid-flight without a single dollar settling twice.
| Component | Technology | Why |
|---|---|---|
| Message core | Java + ISO 20022 | Strong typing and mature JVM tooling for pacs/camt schema handling |
| Event backbone | Kafka | Ordered, replayable streams with idempotent producers for exactly-once intent |
| Ledger | PostgreSQL (serializable) | ACID balance reservations that make double-spend a constraint violation, not a race |
| Runtime | Kubernetes | Horizontal scale of stateless adapters with rail-isolated failure domains |
| Rail adapters | FedNow + RTP clients | Pluggable submission/ack handling behind one internal clearing contract |
FedNow and RTP sit behind one internal clearing contract, so business logic never branches on the rail.
End-to-end IDs deduplicate redelivered messages at the Kafka edge before they ever touch the ledger.
Funds are atomically reserved in PostgreSQL before clearing, making duplicate settlement a constraint violation.
Full pacs.008 / pacs.002 / camt.054 lifecycle handled with strongly typed Java message models.
Kafka retains the settlement stream so reconciliation and audit can rebuild state deterministically.
Kubernetes keeps FedNow and RTP adapters independently scalable so one rail's incident never starves the other.
“Zero double-spends isn't a lucky metric, it's a database constraint.”
The result is a single ISO 20022 switch that fronts both FedNow and RTP, clears at sub-800ms p99, and has moved 50M+ transactions with not one double-spend. By pushing correctness upstream, idempotency at the edge, serializable reservations in the ledger, the system makes the dangerous failure modes of instant payments structurally impossible rather than merely unlikely. It scales horizontally on Kubernetes, isolates each rail's blast radius, and gives downstream consumers a clean, replayable event stream. It is the kind of infrastructure you only notice when it is absent: fast, exact, and quietly correct under load.