25 min

RTGS: the heavy-duty rail

RTGS settles each payment one by one, instantly and irrevocably, in central-bank reserves; it moves trillions a day in a tiny number of transfers.

Where you are. Module 1 left you holding miniledger v1, and this module is wiring rails onto it. Lesson 1 built the workbench: six banks, five customers each, and one seeded day of 300 payments that every rail in the module replays. Lesson 2 split a payment’s life into clearing - agreeing who owes what - and settlement, the ledger commit that makes it final, and left a question hanging: every rail is a different answer to when each happens. This lesson builds the first rail, the one lesson 1’s map has been calling the heavy-duty rail, and its answer to lesson 2’s question is the shortest possible one: both, now.

The payment that cannot wait

On the morning your flat purchase completes, two payments leave your bank. One buys a coffee. The other buys the flat. The coffee payment can take its time: it will be cleared during the day, netted against millions of opposing flows, and settled as a small residue tonight, and nobody minds, because the worst case is a free coffee. The flat is different. The seller’s solicitor will not release the keys against a promise that tonight’s batch will probably contain the money, and the seller’s bank has no appetite for spending the afternoon owed a flat-sized IOU by your bank, hoping it is still solvent at the cutoff. This payment is too big to wait and too big to net. What it needs is the opposite of a batch: settle this one payment, alone, right now, in money that cannot bounce, and let everyone see it is done. Every serious currency runs a rail that does exactly that, and today the heavy-duty rail gets its real name.

The idea in one paragraph

RTGS stands for real-time gross settlement, and the name is a specification. Real-time: the payment settles the moment it arrives, not at a cutoff, so lesson 2’s gap between cleared and settled closes to nothing. Gross: it settles individually and in full, its own face value moving on the ledger, never netted against opposing flows. Settlement: what moves is reserves at the central bank, tier 1 money, so the payment is final - individually, irrevocably - the instant the central bank’s ledger writes. That combination buys maximum safety: there is no interval in which the payee’s bank holds an unsettled promise, and no pile of cleared-but-unsettled obligations for a failing bank to leave behind. It also charges maximum liquidity: every payment needs its full value in reserves, at its bank, at the moment it settles. The whole rail is one wrapper around the submit/settle API you built in module 1: try to settle now; else queue.

Three words, three refusals

Read the name as three refusals, one per word.

Real-time refuses the cutoff. In lesson 2’s pipeline the interesting question was how long a payment sits between cleared and settled. Here it does not sit at all: the instruction arrives, cover is checked, reserves move, done. There is nothing scheduled about it; arrival is the schedule.

Gross refuses netting. Module 0’s clearing house taught you the compaction trick: cancel opposing flows, settle only residues. This rail declines the trick entirely. Two banks that owe each other similar amounts all day still push every payment, full value, both directions. Nothing waits around to be offset, because waiting is exactly what this rail exists to eliminate.

Settlement in reserves refuses every lesser settlement asset. The move happens at tier 1, on the central bank’s own ledger, in its own IOUs. A reserve balance cannot bounce, and its issuer cannot fail the way a commercial bank can, which is why a payment settled here is as final as money gets.

Try to settle, else queue

Before the rail can make sense, the exercise world sharpens one distinction. Each of the six banks holds 1,500 of reserves, posted by endowing an idle treasury account so they sit untouched; every customer’s spending money arrives as a loan - deposits created without reserves, exactly as module 1 lesson 9 taught. That split is deliberate, because it makes two cover questions come apart. “Does alice have the deposit?” is miniledger’s own submit check from module 1. “Does alice’s bank have the reserves, right now, in full?” is a new question, and it is the rail’s question:

def reserves_cover(self, payment: dict) -> bool:
    """Can the payer's bank pay in central-bank money, right now, in full?"""
    bank = self.world.banks[payment["payer_bank"]]
    return bank.balance("reserves") >= payment["amount"]

A customer’s deposit can be perfectly good while their bank is momentarily short one tier up. On this rail, that is the only shortage that matters.

The rail itself is the offer method, and its whole logic is try-settle-else-queue. A payment arrives. If the payer bank’s reserves cover its full amount, it settles immediately - submit then settle, the same two calls as module 1, run back to back with no pause between them - and offer returns True: final, individually, now. If reserves fall short, the payment does not fail and does not shrink; it joins a first-in-first-out queue and waits for reserves to arrive.

And reserves do arrive, because every settlement moves them somewhere:

def drain(self) -> None:
    """Retry the queue head for as long as freed reserves keep covering it."""
    while self.fifo and self.reserves_cover(self.fifo[0]):
        self._settle_now(self.fifo.pop(0))
        self.settled_from_queue += 1

Each settlement credits some payee bank’s reserves, and the queue’s head might belong to exactly that bank - so after every settlement the rail retries the head. Strict first-in-first-out, head only: fair, simple, and carrying a failure mode you will cause and then cure in lesson 6.

Trillions before lunch

The rail you just built is a stylised miniature of the systems that settle the world’s major currencies: the dollar’s Fedwire, run by the Federal Reserve; the euro’s T2, run by the Eurosystem; sterling’s CHAPS, run by the Bank of England.

image/svg+xml Matplotlib v3.11.1, https://matplotlib.org/ 100 200 300 400 500 600 700 800 900 1000 payments per day, thousands (2024 average) 1 0 3 4 × 1 0 2 6 × 1 0 2 2 × 1 0 3 3 × 1 0 3 4 × 1 0 3 value per day, USD bn equivalent (2024) Fedwire $4.5tn/day T2 EUR 1.8tn/day CHAPS GBP 344bn/day
three RTGS systems, value against volume

Look at the shape, not just the size. Divide value by volume - arithmetic on the figures above, not new data - and the average Fedwire payment is a little over $5 million, the average T2 payment around €4 million, the average CHAPS payment about £1.7 million. Nobody’s coffee is in these numbers. This is the wholesale layer: banks settling obligations with banks, the money legs of large trades, and the payments too big to wait or to net. The everyday traffic will reach this rail anyway, invisibly: when lesson 7 builds the batch rails, their netted residues will settle across this one at fixed cutoffs. The heavy-duty rail is not a competitor to the everyday rails; it is what they stand on.

Review

The name is a specification

Real-time gross settlement is three refusals, one per word. Real-time refuses the cutoff: the payment settles the moment it arrives, so the gap between cleared and settled closes to nothing. Gross refuses netting: each payment settles individually and in full, its own face value moving, never cancelled against an opposing flow. And settlement in reserves refuses every lesser settlement asset: the move happens on the central bank’s own ledger, in its own IOUs, which is why a payment settled here is as final as money gets. Read the name that way and the rail’s behaviour follows from it.

Try to settle, else queue

The whole rail is one wrapper around the submit and settle calls you already built. A payment arrives. If the paying bank’s reserves cover its full amount right now, it settles immediately, and it is final. If the reserves fall short, the payment does not fail and does not shrink; it joins a queue and waits for reserves to arrive. Notice which shortage matters here. A customer’s deposit can be perfectly good while their bank is momentarily short one tier up, and on this rail that is the only shortage that counts. Maximum safety, bought with maximum liquidity.

Check yourself

1. Name the convenience each of “real-time” and “gross” refuses, in lesson 2’s vocabulary.

Real-time refuses the cutoff: settlement follows clearing in the same breath, so a payment never sits in the cleared-but-unsettled state where the payee’s bank holds an unsettled promise. Gross refuses netting: each payment moves its own full face value in reserves, never a residue left after opposing flows cancel. Together they collapse lesson 2’s pipeline to a point: on this rail, arrived, cleared, settled and final are the same moment.

2. Why must the settling asset be reserves at the central bank rather than deposits at some very large commercial bank?

Because the rail’s whole product is finality without exposure, and a commercial-bank deposit is the IOU of an institution that can fail. Settle in Big Bank deposits and every payment leaves the payee’s bank holding Big Bank risk - the waiting exposure the rail exists to eliminate, moved rather than removed. Reserves are the central bank’s own IOU, module 1’s tier 1: the one asset every bank accepts and no failure can hollow out.

3. offer retries the queue only after a successful settlement, and drain retries only the queue head. Why is that the right moment to retry?

Because in this world reserves change only when a settlement moves them. A queued payment becomes coverable only when its bank’s reserves rise, and the only event that raises any bank’s reserves is a settlement crediting it - so retrying after each settlement checks at exactly the moments the answer can have changed, and checking at any other time would find nothing new. The head-only rule is the rail’s fairness discipline, strict first-in-first-out; what that discipline can cost is lesson 6’s subject.

4. The figure shows all three systems settling hundreds of billions to trillions daily across mere hundreds of thousands of payments. What does that shape tell you about what the rail is for?

Divide value by volume: the average payment is in the millions. This is the wholesale layer - banks settling with banks, the money legs of large trades, the payments too big to wait or to net - not the economy’s everyday traffic. The everyday traffic touches this rail anyway: lesson 7’s batch rails will collect it, net it, and settle only the residues here. The coffee never rides the heavy-duty rail, but its rail does.

5. Your run settles 12,678 of value through a world holding 9,000 of reserves in total, and total reserves finish unchanged. Reconcile the two facts.

Settlement relabels reserves across the central bank’s lines; it never creates or destroys them - module 1’s conservation, re-asserted here after every payment. The same reserves settle payment after payment as they cycle from bank to bank, which is how a day’s settled value can exceed the reserve stock many times over. What binds is never the total: it is whether the paying bank holds enough at each arriving moment. That distinction - totals versus timing - is exactly where the next lesson starts.

Do this

Fifteen minutes, from module-02-domestic-rails. The script replays lesson 1’s fixture, so fixture_day.json must sit in code/; if the run stops with no fixture_day.json here, run your lesson 1 workbench once and come back. Open code/rtgs_rail.py: the world builder, the cover check and drain are given, and the TODO(you) is offer itself, the try-settle-else-queue step. When cover holds: settle with self._settle_now(payment), then call self.drain() - that settlement just moved reserves to the payee’s bank, so the queue head may have become coverable - and return True. When cover fails: append the payment to self.fifo, raise self.peak_queue if this is the deepest the queue has been, and return False.

python3 code/rtgs_rail.py

The run offers the first 50 payments of the fixture morning and asserts three claims: every payment is final by the close with the queue empty, the settled value equals the payments’ full face value because gross settlement never shrinks anything, and every delayed payment eventually settled from the queue. Done right, it prints

settled 50 of 50 payments, value 12678; 1 delayed, peak queue length 1

and ends with the line

RTGS settles one by one, in full, in central-bank reserves - the queue forms the moment reserves lag the flow

Before you leave, read the first line against the world it ran in: 12,678 of value settled through a system holding 9,000 of reserves in total. Hold that thought into lesson 4. The completed version is solutions/rtgs_rail.py; compare after you are green, not before.

What you can now do. You can name what each word of real-time gross settlement refuses - the cutoff, the netting, the lesser settlement asset - and say why the result is the safest rail money has: each payment final, alone, in central-bank money, the moment it lands. You can read the three big systems’ 2024 numbers and see the wholesale shape in them: trillions of value, a tiny count of payments, millions per transfer. And you built the entire rail as one wrapper on your own miniledger - try to settle, else queue - which means you also built its cost, because gross settlement demands full value in reserves at every arriving moment. The safety is real and so is the bill. The next lesson prices it.

What you can now do

You can settle payments one by one in central bank money and read the three big systems' 2024 numbers.