Why Fast Systems Fail When They Treat Every Step Like a Final Answer
Hatched by Kai Nguyen
Jul 01, 2026
10 min read
3 views
86%
The Hidden Cost of Moving Fast
What if the biggest performance problem in a distributed system is not speed, but certainty? Teams often chase throughput, add more services, and split databases to reduce contention, only to discover that the real bottleneck is no longer compute or storage. It is coordination. Once a system is no longer one database, one transaction, one source of truth, every “simple” business action becomes a negotiation among independent actors.
That is where many systems quietly break down. A customer places an order, payment succeeds, inventory drops, shipping is prepared, and then one service fails halfway through. In a monolith, a transaction either commits or rolls back. In a distributed architecture, reality is messier. You do not get perfect atomicity for free, and pretending otherwise leads to brittle logic, long locks, and invisible data drift.
There is a surprising connection here to SQL optimization. A slow query and a fragile distributed transaction look different on the surface, but they reveal the same deeper lesson: systems perform best when they can narrow uncertainty early and avoid work that must later be undone. In one case, that means helping the database use indexes, filters, and execution order efficiently. In the other, it means structuring business processes so each local step is valid on its own, while compensations handle failure gracefully.
The common enemy is unnecessary global commitment.
The Deeper Question: Can a System Stay Correct Without Central Control?
A traditional transaction answers yes by force. It keeps all relevant state inside one consistency boundary and refuses to proceed unless every part can be committed together. That is elegant, but only when the world is small enough to fit inside a single lockable unit.
Microservices break that illusion. Different services own different databases because that ownership improves autonomy, scaling, and deployability. But the tradeoff is profound: global truth becomes a coordination problem. No single service can simply declare success for the whole business process, because no single service owns the whole process.
The Saga pattern is an answer to this question. Instead of one large transaction, it breaks a business operation into local transactions. Each service does what it can inside its own boundary, and if the chain fails, earlier services execute compensating transactions to restore a valid state. This is not rollback in the database sense. It is more like unwinding a story by writing new chapters that cancel the consequences of earlier ones.
That distinction matters. Rollback assumes the past can be erased. Compensation assumes the past remains visible, and the present must adapt. In many real systems, that is the only honest model.
The mature distributed system does not promise that nothing bad ever happens. It promises that when bad things happen, the system knows how to remain coherent.
This is the same instinct behind writing queries that are SARGable. When a WHERE clause can use an index, the database does not have to inspect every row and then discard most of them. It filters early, narrows the search space, and avoids needless work. In both cases, performance and correctness improve when the system is designed to avoid broad, expensive commitments.
Local Truth Beats Global Guessing
A useful way to think about both database tuning and saga design is this: every system becomes faster and safer when it makes the smallest correct decision possible at each step.
In SQL, that means allowing the optimizer to do what it is good at. If you wrap an indexed column in arithmetic, apply negation in the wrong place, or start a pattern with a leading wildcard, the database often loses the ability to use the index efficiently. Suddenly it must scan more rows, sort more data, and calculate more than necessary. The query still works, but it works the hard way.
The same pattern shows up in service coordination. If every service waits for a perfect, system-wide answer before acting, throughput collapses. If every service publishes events without a clear model for how downstream state should evolve, consistency becomes accidental. The best design is not maximal synchronization. It is well-scoped responsibility with explicit recovery paths.
Consider an online store.
- The Order service creates an order record locally.
- The Payment service reserves or captures funds.
- The Inventory service decreases stock.
- The Shipping service creates a shipment task.
If the shipping step fails after payment and inventory have succeeded, the system needs a compensation plan. Payment may be refunded, stock may be restored, and the order status may become canceled. That is not a failure of design. It is the design. The mistake would be to believe the whole process must behave like a single SQL transaction when it is actually a chain of independent agreements.
Now compare this to a query that asks for the first 50 orders matching a real, selective condition. If the filter is indexed and applied early, the database returns quickly. If the filter is hidden inside a function or expressed in a way that prevents index use, the engine may scan millions of rows just to produce the same 50. In both cases, the system suffers because it is forced to act before it can rule out irrelevant work.
The deeper principle is not just optimization. It is epistemic humility. Each component should claim only the certainty it actually possesses.
Orchestration and Choreography Are Two Ways of Managing Uncertainty
Saga implementations usually come in two forms: orchestration and choreography. These are not only architectural choices, but also philosophies about where knowledge should live.
In orchestration, a central controller decides what happens next. It invokes services, waits for outcomes, and directs compensations if needed. This resembles a conductor guiding an orchestra. The advantage is clarity. You can see the process in one place, trace the flow, and enforce business rules consistently.
In choreography, each service reacts to events and emits the next event when its local work is done. There is no single boss, only a network of participants responding to shared signals. This creates looser coupling and often better resilience, but the flow is harder to visualize. Responsibility is distributed, and emergent behavior replaces explicit command.
SQL query tuning offers an oddly similar tradeoff. Sometimes a well-chosen query plan feels orchestral: filters first, join next, sort last, all in an orderly execution path. Other times the optimizer must work more like choreography, combining indexes, statistics, cardinality estimates, and execution operators in response to data distribution and query shape. In both cases, the system is trying to answer the same question: How do we minimize work while preserving correctness?
A central insight emerges here: centralization is not the same as control. A monolithic query can still be slow if it forces the wrong execution order. A choreography-based saga can still be disciplined if event contracts are precise and compensations are well-defined. The real issue is not whether there is one brain or many. It is whether the system can preserve meaning as it decomposes work.
Think of a restaurant.
The waiter is the orchestrator. You place one order, and the waiter coordinates kitchen, bar, and dessert. But the kitchen staff also choreograph among themselves: one prepares sauces, another plates, another times the heat. Neither model is inherently better. The point is to keep the meal moving without requiring the chef to personally stir every pot.
Distributed systems need the same pragmatism. They should centralize only the decisions that truly require global awareness, and localize everything else.
Compensation Is Not Failure, It Is Design for Reality
Compensating transactions are often described as if they are second best, a fallback for when the ideal fails. That framing is misleading. In a distributed environment, compensation is not a patch on failure. It is the mechanism by which the system admits that some actions are irreversible in practice, even if they are reversible in business terms.
This is a powerful shift in thinking. A payment may be captured, an email may be sent, a seat may be reserved, a container may be shipped. Some of these actions cannot truly be undone. You can refund, apologize, rebook, or cancel, but you cannot pretend the original event never existed. Compensation is therefore a business-level reconciliation, not a magical reversal.
That is exactly why local transactions matter. They keep each step narrow, explicit, and measurable. The system does not ask one giant question, “Did the whole world work?” It asks many smaller ones: “Did this service complete its job?” “Can the next service safely proceed?” “If not, what restores a valid state?”
This mindset also improves SQL performance engineering. A query written with care does not ask the database to do speculative work that may be discarded later. It uses the right index, filters early, limits rows, avoids unnecessary sorting, and skips calculations that do not change the result. The database is most efficient when it does not have to clean up after its own overreach.
Good architecture is often the art of making undo paths explicit before you need them.
That is true in transactions, and it is true in queries. A graceful failure path is not a sign of weakness. It is what makes speed sustainable.
The Unified Mental Model: Narrow the Blast Radius
If there is one framework that ties these ideas together, it is this: good systems reduce blast radius.
In SQL, the blast radius is the amount of data the engine must examine, transform, sort, or group before it can answer the question. SARGable predicates, proper indexes, and early filtering reduce that radius. The engine touches fewer rows, spends less time on irrelevant data, and returns results faster.
In distributed transactions, the blast radius is the scope of uncertainty created by any step. If a service can fail after another service has already committed, the system must know exactly what is affected, what can be compensated, and what must be communicated downstream. Sagas work because they keep the uncertainty local and make the consequences traceable.
This idea suggests a broader architectural principle:
- Make decisive steps small.
- Keep state boundaries clear.
- Prefer explicit recovery to implicit hope.
- Filter early, commit locally, compensate intentionally.
Seen this way, SQL tuning and saga design are not separate specialties. They are expressions of the same engineering instinct. Both ask: How can we build systems that are fast because they are disciplined, not fast because they are lucky?
A query that avoids a full table scan is not merely optimized. It is respecting the shape of the data. A saga that compensates cleanly is not merely resilient. It is respecting the shape of reality. That is why these topics belong together. They teach the same lesson in different dialects.
Key Takeaways
- Narrow uncertainty early. Whether in a query or a distributed workflow, remove irrelevant work before it compounds.
- Treat local correctness as sacred. Each service or database step should make sense on its own, not only as part of a larger hope.
- Use compensation as a first-class design tool. Do not wait for failure to invent a rollback story.
- Prefer SARGable, index-friendly queries. Avoid wrapping indexed columns in functions, arithmetic, or leading wildcards when you want fast retrieval.
- Choose orchestration or choreography intentionally. Central control improves visibility, while event-driven coordination improves flexibility. Pick the model that matches the uncertainty of the domain.
The Real Lesson: Speed Comes From Respecting Limits
The seductive myth in software is that speed comes from doing more in parallel, or from removing every boundary, or from making every component smarter. In practice, fast systems are usually the opposite. They are systems that respect what each component can know, do, and undo.
A well-tuned SQL query is fast because it refuses to ask the database to inspect the world. A well-designed saga is robust because it refuses to pretend the world can be changed atomically across independent services. Both are forms of engineering maturity: they replace brute force with structure.
So the next time a system feels slow or fragile, do not ask only where the bottleneck is. Ask a deeper question: Where is the system forcing certainty too early? Sometimes the fix is an index. Sometimes it is a compensation step. Sometimes it is an orchestration boundary. But almost always, the answer is the same: stop treating every step like a final answer, and start designing for the reality that good systems move through uncertainty one local truth at a time.
Sources
Hatch New Ideas with Glasp AI 🐣
Glasp AI allows you to hatch new ideas based on your curated content. Let's curate and create with Glasp AI :)
Start Hatching 🐣