22 min

Clearing versus settlement

Clearing is agreeing who owes what; settlement is the ledger commit that makes it final; every rail is a different answer to when each happens.

Where you are. Module 1 left you driving miniledger v1 through a full day: submit validating and queueing, settle committing, finality stamped at a moment you can point at, every invariant re-asserted as it happens. The last lesson pinned the map of the rails - a country’s handful of them, each a different trade of speed, cost and size - and set up the workbench this module builds on. This lesson adds the pair of words the whole module is spelled in. You have owned both since module 0 without being told they were a pair: the clearing house that totalled all day and squared up once, and the API that splits promise from fact. Today the room and the API turn out to be the same idea, and the join is permanent.

The room and the API

Hold two scenes side by side. The first is module 0’s clearing room: clerks arriving all morning with stacks of cheques, every obligation totalled against every other across one table, and not a coin moving for hours. The coin crosses once, at the appointed hour, and only the differences. The second is module 1’s milestone day: three payments submitted by noon with every balance frozen exactly where it started, then one call to settle, and every promise became fact at once, in order, atomically.

Two centuries apart, the same shape. A long phase of agreeing - checking, totalling, holding - and a short, sharp phase of committing. The room spent its whole day in the first phase and one hour in the second; your miniledger spends exactly the gap between your submit and your settle. Finance has names for the two phases, and you have met both words without meeting the pair: the first phase is what the clearing house did, and it is called clearing; the second is settlement, the word module 0 coined and lesson 7 built. This lesson locks the vocabulary together, then asks the question the rest of the module answers rail by rail: when does each phase happen?

The idea in one paragraph

Clearing is agreeing who owes what. It is every step between an instruction arriving and money moving: validate the payment - the account exists, the amount is positive, the payer is good for it on top of everything already promised - then tot the agreed obligations into positions ready to move. Settlement is the ledger commit: the edits land, reserves relabel at the central bank, finality arrives. Clearing produces agreement; settlement produces facts; between them, a cleared payment is a promise both sides have accepted and no ledger shows. Neither phase is optional - every rail on the map runs both - but nothing forces them to happen together, and a rail is, at heart, a policy for when: settle each payment the instant it clears, or clear all day and settle once, or anything between. The whole module is that one sentence, rail by rail.

Four stations, one line that matters

Every payment, on every rail this module builds, passes the same four stations.

Initiate is arrival: an instruction enters the rail. Module 0’s card tap, a wire request, your call to submit. The instruction travels as a message, and module 0 taught you the carrier holds none of the money. Nothing has been judged yet.

Clear is the agreement phase, and it is wider than one check. Validation lives here: lesson 7’s three refusals happen at this station, before anything moves. So does the totting-up: obligations against obligations, module 0’s netting, positions computed and held. A payment can wait at this station for a heartbeat or a whole banking day - agreed, binding on its payer, and invisible to every ledger.

Settle is the commit. Lesson 8’s three balanced postings, reserves relabelled one tier up, the stamp that reads "final". The finality line sits at this station’s exit: cross it and no party can unwind you.

Reconcile is the audit after the fact: do the books agree? You have run this station too - assert_world comparing each bank’s own reserves line against the central bank’s telling is a reconciliation job, and lesson 8 called it exactly that. Real rails run it as end-of-day file comparison. Note where it sits: past the finality line. A mistake found in reconciliation is repaired with new entries, never by unwinding old ones, and two later lessons in this module live on that side of the line.

cleared payments hold here not one balance moves initiate an instruction arrives clear agree who owes what settle the ledger commit reconcile do the books agree finality no unwinding past this line
The payment pipeline as four boxes left to right, initiate then clear then settle then reconcile, with a dashed gold holding loop above clear where cleared payments wait without a balance moving, and the green finality line crossed between settle and reconcile

Wider than the screen; scroll it sideways.

Ten payments cleared, none settled

The exercise file makes the phase gap executable by putting the room in front of your miniledger. ClearedQueue wraps a World, and its clear method takes the same route a payment would - amount, payer bank, payer, payee bank, payee:

queue = ClearedQueue(world)
for payment in TEN_PAYMENTS:
    queue.clear(*payment)

clear validates exactly as submit would - positive amount, payee exists, payer can cover on top of everything already cleared - and then does something submit never did: it records the promise in its own list, beside the ledger, and asks the world for nothing. The starter asserts the claim in three parts: ten payments cleared; every balance in the world untouched; and world.queue empty - in the starter’s own words, clearing happens beside the ledger, and the world has not even been asked. The room in Lombard Street stood in exactly this relation to the banks’ books. It validated, it totalled, it held. It never paid.

Clearing’s product is the totting-up, printed before anything settles:

cleared: ten payments agreed, zero balances moved
  net position Alder  -10
  net position Birch  -20
  net position Cedar  +30

Then the commit. commit walks the cleared list into world.submit, calls world.settle() once for the whole batch, and stamps every payment final. Deliberately, it settles gross and in cleared order - every payment at face value, the plainest settlement possible - because this lesson is about holding the phases apart, not yet about what the totting-up buys. And the asserts pin a quiet punchline: settled gross, the balances land at 990, 980 and 1030, exactly where the net positions promised. Settle everything, or settle only the differences: the ledgers end the same. Module 0 told you netting shrinks the movement, never the owing; here it is as an assert.

Every rail is a timetable

Both phases are mandatory; their timing is not. Here is the module ahead, read as answers to when - descriptions only, since each rail gets its own lesson:

RailClearsSettles
the heavy-duty rail (lesson 3)payment by payment, on arrivalthe same instant, full value, in reserves
batch rails (lesson 7)all day, totted into positionsat fixed cutoffs, differences only
instant rails (lesson 9)in seconds, any hourseconds later, with finality
the card rail (lesson 11)at the tapdays later, in a batch

No cell in that table is a matter of taste; each is a price paid somewhere. Hurry settlement and every payment must be backed by its full value in reserves at the moment it commits - lesson 4 measures that bill. Delay settlement and the system fills with cleared promises, which are only as good as the parties behind them - the question module 0 left standing, of who stands behind the total when a member cannot pay. Hurry a phase and you pay in liquidity; slack it and you pay in trust.

Review

Agreement, then facts

Clearing is agreeing who owes what. It is every step between an instruction arriving and money moving: validate the payment, checking that the account exists, the amount is positive and the payer is good for it on top of everything already promised, then total the agreed obligations into positions ready to move. Settlement is the ledger commit: the edits land, reserves relabel at the central bank, and finality arrives. Clearing produces agreement, settlement produces facts, and between them a cleared payment is a promise both sides have accepted and no ledger shows.

A rail is a policy for when

Neither phase is optional, and every rail runs both. But nothing forces them to happen together, and that freedom is what a rail actually is: a policy for when. Settle each payment the instant it clears, or clear all day and settle once, or anything in between. Gross settlement fuses the two into every single payment. The batch rail pulls them hours apart on purpose. The instant rail settles per payment but pre-pays the liquidity so it can do it at any hour. Once you can see the two phases separately, every rail in the system is the same four stations with the commit moved to a different place, and the differences between them stop looking like different technologies.

Check yourself

1. After ten calls to clear, the starter asserts that every balance is untouched - and also that world.queue is empty. What is the second assert teaching?

That clearing lives beside the ledger, not inside it. The ClearedQueue is module 0’s room in code: it validated, totalled and held ten promises without once calling the world’s API - the ledger machinery has not even been asked. Untouched balances show settlement has not happened; the empty queue shows something stronger: the agreement phase is a separate system, and only commit turns its output into ledger work.

2. Money only moves at settlement, so why must clear - a mere agreement phase - refuse anything at all?

Lesson 7’s rule, moved one system out: the only cheap no is the earliest one. Let a bad payment clear and it enters the day’s positions; the refusal still comes, but at the commit, after the payee has watched the amount as incoming and after it has been totted against other people’s obligations. clear even counts its own cleared list as pending - a promise binds the payer the moment it is agreed, ledger or no ledger - so every payment that clears is one the batch can actually keep.

3. commit settles the ten payments gross, in cleared order - yet net_positions computed three numbers it never uses. Why compute them at all?

Because positions are clearing’s product, whether or not this rail consumes them. This lesson’s commit is deliberately the plainest settlement - everything, full value, in order - to keep the two phases cleanly apart. But the positions show what the agreement phase manufactures: a 550 day that could settle as 30 moving. Lesson 7’s batch rail settles the positions instead of the payments, and the balances land identically either way - the asserts already proved that.

4. Module 0’s clerks totalled cheques all day, and coin crossed the table once, at the appointed hour. Name each half in this lesson’s vocabulary, and place the finality line.

The all-day totalling is clearing; the once-a-day squaring in coin is settlement. Every cheque in the room spent its day as a cleared promise - agreed, binding, on no ledger. The finality line sat at the appointed hour: only when the differences were paid did any of the day’s obligations become fact, which is why a member failing mid-afternoon was a real danger, and why every hour of clearing-without-settlement is an hour of trust.

Do this

Fifteen minutes, from module-02-domestic-rails. Open code/cleared_queue.py. The clearing half of ClearedQueue is written: clear validates as submit would and records promises beside the ledger; net_positions tots them up. commit is yours - the TODO(you): world.submit each cleared payment (amount first, then payer bank, payer, payee bank, payee), then one world.settle() for the whole batch, mark every payment’s status "final", empty the cleared list, and return settle’s count. Run the starter as shipped and it performs the whole clearing phase - ten payments agreed, net positions printed, every balance proved untouched - then stops at NotImplementedError, exactly where settlement should begin.

python code/cleared_queue.py

The asserts are the spec: settle’s count is ten, the cleared queue empties, and the balances land at 990, 980 and 1030 - where the net positions promised. Green ends with the line

clearing agreed who owes what; only the settlement commit moved money

If the count assert fires at 1, you settled inside the loop: each settle drains the queue as it stands, so submit all ten first and commit the batch with one call - one commit act is what makes it a batch. If the “committed batch leaves the cleared queue empty” assert fires, you stamped the statuses but kept the list; after commit, the batch survives only as "final" stamps on the payment objects, not as entries still waiting. The completed version is solutions/cleared_queue.py; compare when you are green.

What you can now do. You can hold the two phases of every payment apart and name them with the words the industry uses: clearing agrees who owes what - validation, totting-up, positions - and settlement is the ledger commit that makes the agreement final. You can run a whole clearing phase beside a ledger that never hears about it, prove not one balance moved, and then commit the batch in a single act. And you can read any rail as a timetable: which phase it hurries, which it delays, and where the price lands. The next lesson boards the rail that hurries everything - each payment settled the instant it clears, one by one, full value, in reserves - the heavy-duty rail every other rail in this module ultimately leans on.

What you can now do

You can hold validated payments cleared without moving a balance, and say which phase each rail hurries.