Posted on

Embrace the Chaos

Swap the question "how do I stop this from breaking?" for "what do I do when this breaks?", because the gap you missed is structural, not a lapse in your analysis.

Filed under

Tags

How many times have you tried to prevent a problem? How many times have you mapped out every possible way something could go wrong, only to have the one scenario you missed cause the biggest damage?

For those of you who, like me, have tried to build the perfect system, the one that anticipated every failure before it happened, I have bad news.

Things will break.

Errors will happen, services will go down, data will get wiped, someone will miss the SLA they promised you. Whether you like it or not.

Those of us in tech, when we are building something, tend to try to seal off every possible path a problem could take. What we forget to measure is the effort we burn on that impossible hunt to close every gap. No matter how thorough your upfront analysis is, something will not be covered.

Obviously, when human lives are at stake, sending someone into space, running a computer-assisted surgical device, maximum precision is non-negotiable. But for nearly everything else we build, the correct stance is to assume problems will happen.

Does that mean abandoning tests, reviews, checklists? That is not what I am saying. What I am saying is that we should not get paranoid about always solving the cause of a problem before it exists.

But if we are not going to spend our lives predicting every failure, how do we keep the system whole and running while problems keep happening?

EMBRACE THE CHAOS

Embracing the chaos means accepting the uncertainty of things and moving forward. It means swapping the question “how do I stop this from breaking?” for the question “what do I do when this breaks?”.

This is not a slogan. It is a stance with a name, a theory, and documented practice behind it.

The technical name for the problem

That “unidentified scenario” you tried to predict and could not has a formal name: the Black Swan. Nassim Taleb defines it this way in The Black Swan: an outlier event that nothing in the past pointed to, with extreme impact, and one that only looks obvious and predictable after the fact, because our brains are far too good at inventing retroactive explanations (the narrative fallacy).

From the turkey’s point of view, not being fed on day one thousand and one is a Black Swan. For the butcher, it is not. He always knew what was coming. The problem is that in most of the systems we build, we are the turkey: we do not have access to the butcher’s point of view, and pretending we do is exactly what produces overconfident architectures that collapse out of nowhere.

Taleb’s answer is not “predict better”. It is to accept that you will not predict, and to organize the system to be robust to the unknown: redundancy, optionality, barbell exposure (extreme safety on one side, calculated risk on the other, no fragile middle ground).

In Antifragile, he pushes the idea one step further: there are three categories, not two. The fragile breaks under shock. The robust withstands the shock and stays indifferent. The antifragile improves under shock. In his words, the fragile wants tranquility, the antifragile grows from disorder, and the robust does not much care.

That changes the question this essay opened with. It is not “how do I build the perfect system”. It is “how do I build a system that comes out stronger, not more fragile, after it breaks”.

Why predicting everything is structurally impossible

This is not a lack of effort on your part. It is structural.

Leslie Lamport captured it in a line that Roberto Vitillo revisits in Understanding Distributed Systems: a distributed system is one in which the failure of a computer you did not even know existed can render your own computer unusable.

Any real modern system, with queues, caches, third-party services, replicas, DNS, a cloud provider, contains components you did not design, do not control, and in many cases do not even know are sitting in your dependency chain. The “uncovered gap” haunting you is not a hole in your analysis. It is a component outside your field of vision by definition.

Martin Kleppmann, in Designing Data-Intensive Applications, formalizes the distinction that separates the people who get this from the people still trying to build the perfect system: a fault is one component deviating from what it should do, a failure is the whole system no longer serving the user. A fault-tolerant system is one that absorbs faults without turning them into failures.

And the most counterintuitive practical consequence of that idea is that Kleppmann argues for triggering failures on purpose. It is the philosophy behind Chaos Monkey, the tool Netflix turned loose inside its own production infrastructure to kill instances at random, continuously, instead of waiting for the real failure to arrive unannounced.

You do not write tests to prove the problem will not happen. You write tests, and systems, that assume it will. And that trigger the problem early, with you watching, rather than late, with the customer watching.

“Fine, but how do I actually keep the system healthy?”

That is the question left hanging once you accept you will not predict everything. And the answer is not philosophical, it is engineering. There are concrete techniques, proven in production at scale, for containing the damage without betting everything on a perfect prediction.

1. Stop a local overload from becoming a total outage

A Facebook paper on serverless infrastructure describes three mechanisms that do exactly this:

Backpressure: the caller reduces its request rate when the receiver signals overload, and only ramps back up gradually. Same additive-increase/multiplicative-decrease principle as TCP.

Concurrency limits: a hard ceiling on how many requests a service handles at once, so the excess queues or gets rejected instead of degrading everything already in flight.

Slow start: a service that just recovered accepts traffic gradually, not all at once. Otherwise the recovery becomes a second collapse, a thundering herd knocking everything down again.

2. Design the undo, not the guarantee

Assume from the outset that a multi-step operation will fail halfway through.

That is what the Saga pattern solves. A distributed transaction (order, invoice, payment, shipping) does not need an impossible atomic guarantee across separate services. It needs compensating actions defined in advance for each step, to undo what already ran when a later step fails.

There are two variants: orchestration, with a central coordinator driving the flow (good for complex, tightly dependent processes), and choreography, with services communicating through events and acting autonomously (good for more dynamic, decoupled flows).

Neither one tries to predict the failure. Both assume it is coming and ship with the fallback baked into the design.

3. Have a kill switch

Feature flags of the “Ops Toggle” variety exist to turn off a non-critical feature under load, immediately, without a new deploy. Degrading part of the system on purpose to keep the rest standing.

The counterexample, when that mechanism does not exist or exists badly managed, is Knight Capital’s $460 million loss: an incomplete deploy left old test code live in production, with no reliable flag to shut it off in time, and the firm burned half a billion dollars in 45 minutes.

That was not a failure of upfront analysis. It was the absence of a mechanism to contain the damage after the analysis, inevitably, missed something.

Embracing chaos at industry scale

If this sounds like a nice idea but far too risky for a real company to bet on, look at an industry that already made the bet and has the numbers to show it worked: commercial aviation.

In the mid-1990s, US airlines were recording roughly one fatal accident per two million departures. The response was not a push to predict every possible failure more precisely. It was the opposite: regulators, airlines, and pilot unions built a system for voluntary, non-punitive incident data sharing. Reporting a near miss stopped meaning investigation or dismissal and started feeding a common database the entire industry studied. The result was a run of consecutive years without a single fatal domestic commercial accident in the United States, broken only in 2009.

Courtney Nash, in the essay Announcing the VOID, which documents an attempt to bring that same logic to software through a public database of technology incident reports, sums up the argument in a line that belongs on the wall of every infrastructure team: the potential for catastrophic outcomes is a hallmark of complex systems, and that potential cannot be eliminated, because it is inherent to the nature of the system itself.

The Learning From Incidents community, cited in that same essay, reinforces a point that lands directly on “do not get paranoid about always solving the cause”: incidents are products of sociotechnical systems, code, machines, and the people operating all of it under real organizational pressure, not technical faults with a single clean root cause waiting to be found.

Hunting obsessively for “the cause”, as if it were always singular and always findable, comes from the same instinct that makes you try to predict every failure before it happens. Same origin. Same ceiling.

The real damage is usually mundane

One last thing to take apart, because imagination loves to overcomplicate this. When you picture “that unidentified scenario”, you probably imagine something sophisticated: an elaborate attack, a rare race condition, a concurrency bug that only surfaces during a full moon. In practice, it is rarely that.

The Capital One breach, which exposed data on more than 100 million customers, was not high-end hacking. It was a misconfigured application firewall that let an attacker borrow credentials from inside the infrastructure itself and use them to read S3 buckets nobody imagined were reachable.

No amount of “complete” attack surface analysis would necessarily have caught that. Not because the problem was too complex to predict, but because it was too simple to attract attention. It is the kind of mundane operational detail that slips through precisely because it looks too irrelevant to deserve a spot in your risk review.

That is not a reason to give up on configuring things properly. It is a reason to admit that your list of “things that could go wrong” will always carry a bias: you pay more attention to the exotic than to the boring.

And the Black Swan is rarely exotic. It is usually boring.

Embracing the chaos means…

Embracing the chaos means accepting the uncertainty of things and moving forward. It means trading the energy spent trying to close that last impossible gap for the energy of building the mechanisms that hold the system up when the gap, inevitably, opens.

It means writing tests, yes, and also writing rollback plans. Defining the SLA, yes, and also defining the kill switch. Investigating the incident, yes, but without the fantasy that there is a single root cause that, once found, spares you from the next one.

This is not the opposite of discipline. It is the version of discipline that has accepted its own limit, and that spends whatever energy is left building what happens past that limit instead of pretending the limit is not there.

Things will break. The question left is whether, when they do, your system becomes a headline or just another day at work.

References

  • The Black Swan, Nassim Nicholas Taleb: the definition of a Black Swan, the narrative fallacy, and the turkey problem
  • Antifragile, Nassim Nicholas Taleb: fragile, robust, and antifragile
  • Leslie Lamport (1987): the classic definition of a distributed system, revisited by Roberto Vitillo in Understanding Distributed Systems
  • Designing Data-Intensive Applications, Martin Kleppmann: fault vs. failure and chaos engineering
  • Cascading failure prevention, Facebook serverless infrastructure paper: backpressure, concurrency limits, and slow start
  • Saga pattern, Saurabh Dashora: orchestration vs. choreography
  • Feature Toggles (aka Feature Flags), Pete Hodgson / Martin Fowler: Ops Toggles and the Knight Capital case
  • Announcing the VOID, Courtney Nash: the aviation analogy and the Learning From Incidents community