Build1 distinct publisher3 min readPublished
In a six-service checkout path, the fallback policy turns on a single question about undo, which is why the same gateway belongs in both columns depending on whether the token in hand is already signed.
The Engineer · Build desk

Compiled by The EngineerSomething wrong?How this is made
Reversibility is mostly something you build, not something the domain hands you. Settlement is the clean case. The only coupling between order and settlement is order publishing `order-paid`, `sub-order-delivered`, and `sub-order-refunded` to Kafka and moving on [9]. Take settlement down and those events queue unconsumed while checkout, payment, and fulfillment carry on untouched [10]. What makes that late rather than lost is two properties the author names explicitly: Kafka retains the backlog, and settlement's consumer is idempotent, so consuming a day of queued events produces the same end state as consuming them on time [11]. Drop the retention window or the idempotence and the same business event, a vendor payout, stops being recoverable and belongs in the other column [17].
The inventory reservation goes the other way, and the reason is visible in a WHERE clause. The conditional update either commits or it does not [8], and `order.create()`'s synchronous call to the reserve endpoint has no fallback path, deliberately [5]. The fallback on offer would be to let the order through and reconcile inventory later, which means selling the last unit of a scarce SKU to five buyers and discovering it when four of them cannot be shipped what they paid for [6]. So checkout answers 503 and asks the buyer to retry [7]. That is the invariant declining to guess, and it is the cheaper of the two errors [6].
That cached-token path is only half of the gateway. A brand-new login does have to reach auth, and it has to fail rather than accept a token it cannot verify; the author calls the alternative "a security regression wearing a resilience costume" [14]. So one component sits in both columns, which means the deciding unit is the request path and not the service [16]. Any table drawn per service has at least one row that is really two.
A single global rule fails for a mechanical reason: the columns differ in whether a later correction can still reach the damage, and services on the same diagram do not carry the same kind of risk [3][2]. Settlement is the newest row in that table, and it exists only because milestone M3 added a sixth service [15]. This is one engineer's system, so the transfer conditions matter. For the degrade column to hold, your retention has to cover your worst outage and your consumer has to survive replay [11]. For the fail-fast column to mean anything, your reservation has to be a conditional update rather than a read followed by a write [8]. Sorting the table is cheap. Earning the invariant that lets a service sit in the degrade column is the work [11].
Ranked by verification strength, evidence, and original report placement.
Six services sit between a buyer clicking "buy" and a vendor eventually getting paid: auth, gateway, catalog, inventory, order, and settlement, and any one of them can be slow, restarting, or fully down at any moment.
The author states the criterion is not "how important is this service" but whether the business cost of guessing wrong is reversible.
The author argues a single global rule, either "always degrade gracefully" or "always fail fast", is wrong the moment it is applied uniformly across services that do not carry the same kind of risk.
order.create()'s call to inventory's reserve endpoint is synchronous and has no fallback path, deliberately.
If the fallback were to let the order through and reconcile inventory later, the failure mode is overselling the last unit of a scarce SKU to five buyers at once, discovered only when four of them cannot be shipped what they paid for.
Checkout returning a 503 and telling the buyer to retry is described as strictly better than checkout succeeding and lying.
Distinct publishers with included, body-backed reporting in this cluster.
dev.to
1 article · August 28, 2026
Follow any of these and your For You feed starts watching them — no settings page required.
build
Nobody chose retry-by-default, and the bill arrives as your customer's timeout1 distinct publisher
build
Three services you can delete: queue, cache and search in one Postgres1 distinct publisher
build
Jenkins static AWS keys work from anywhere; the OIDC replacement fails in four known ways1 distinct publisher
build
Four control planes, one Postgres: a team's case against polyglot persistence1 distinct publisher
Evidence-backed comparisons of source perspectives and observed adoption signals. Read the methodology
Which Builder, Operator, and Investor concerns the observed source mix emphasized—not a truth score.
Evidence, demonstrated adoption, hype gap, incentives, and confidence are assessed independently, each on its own current evidence. How these are measured.
Specific, self-attested, unverified
Every checkable detail here — the synchronous reserve call, the WHERE available >= ? update, the three topic names, the cached key set at the gateway — comes from the person who wrote the code, published on dev.to with no repository link, no gate output and no second reader. These are details that would be strange to invent and cheap to confirm if the code were shown, which is why this sits above the middle rather than below it; the M3 gate in particular is described as having been run, and described is as far as it gets.
One stack, its own author
The mechanisms are entirely orthodox — Kafka retention, an idempotent consumer, JWKS caching, Resilience4j at the edge — but the only place any of this is shown running is the author's own six-service project, freshly grown to six by milestone M3. Nobody else is reported using this sorting rule, and no team, traffic level or production incident appears anywhere in the account.
Careful writing, one system's worth of proof
This post polices itself more than most: it names what the framework is not saying, refuses to conclude that settlement doesn't matter, and separates reversibility from stakes on purpose. What tips it slightly past even is scope — "that's the whole rule" is a great deal of generality drawn from one six-service project, offered without a single case where the rule sorted a service wrongly, and the gate that would settle the settlement claim is asserted rather than shown.
Reputation, not revenue
Nothing is being sold. dev.to hosts this for free, no vendor is named except the library the author happens to run, and the payoff on offer is credibility plus a pointer back to his earlier inventory-reservation piece. That still shapes the writing: a clean, generalizable rule with a memorable line about a security regression in a resilience costume travels further than a messy one, and the messy parts — retention limits, breaker numbers, an outage that went badly — are exactly what's absent.
Believable, uncorroborated
One publisher, one author, one system, and no contradictions — because there is no second account capable of contradicting anything. The engineering described is standard enough that a reader can sanity-check it from experience, which is why this lands at the midpoint rather than lower; it stays at the midpoint because sanity-checking from experience is all anyone can do with it.