BOOK DEEP-READ · CHAOS ENGINEERING · CH 4
Chaos Engineering: System Resiliency in Practice · Ch 4 · Richard Crowley (Slack) · 2020
The previous chapter settled the rules: stop relying on inspection, go cause real failures. Which raises the obvious next question — so what tool do I install?
This chapter's answer is a surprise: the first step isn't a tool. It's writing a script, booking a rehearsal, and getting people into one room. The author is an engineer at Slack, and the things he needed to shake were not shiny cloud-native services. They were the old, critical parts nobody had designed to break in the first place.
Suppose a play calls for flying an actor on a wire. No company does this: opening night, full house, let's hoist someone up and see what happens.
The normal way: first a script — who does what at which minute, and what counts as going wrong. Then a walk-through in an empty house, where you get the embarrassing mistakes out of the way: wrong rope length, bad lighting cue, someone standing in the wrong spot. And on the night itself: the safety line stays clipped, someone stands at the switch, and the whole cast agrees in advance on the word that stops everything.
That rehearsal discipline is this chapter. The author calls it Disasterpiece Theater.
The previous chapter mentioned the monkey that kills machines at random, on the assumption that traffic routes around them. It works well, but it carries a hidden precondition: those machines were built to die. Something takes over automatically; nobody has to go prop anything up.
Run a company for a few years, though, and the parts that matter most rarely look like that. They are more like an old house: pull one wall and the whole thing leans, and straightening it requires a person on a ladder. Throwing a monkey at an old house isn't a drill. It's a collapse. So teams get stuck. Don't touch it, and that layer stays an unverified black box forever. Touch it carelessly, and your first drill becomes a real outage — and the reputation of the whole practice dies on the spot.
The concrete win: you can finally touch the oldest, most critical parts, and the first touch doesn't turn into an incident. There's also a counterintuitive finding — the thing you hit most often isn't "it didn't hold up", it's "it held up and not one person knew": everything fine, not a single alert. One honest cost: this way of rehearsing is expensive in people. You get a handful per quarter, never one a day.
For systems nobody designed to break, the first step in chaos engineering isn't installing a tool — it's writing the script, rehearsing in an empty house, and showing up with both the people and the stop switch in place. That's how you demote a potential outage into a rehearsal with a safety line.
Want the mechanisms, the numbers and the diagrams? → Switch to the deep read
You'd think step one of adopting chaos engineering is picking a fault-injection tool. Slack's answer: step one is a document, a review, a dry run in a non-production environment, and an abort plan whose latency you have actually measured. Because the Chaos Monkey route carries a hidden precondition — the thing being shaken was designed to die — and in any company more than a few years old, the systems that matter most are precisely the ones that weren't. This chapter doesn't hand you a tool. It hands you a process that lets a legacy system be shaken for the first time and produce knowledge instead of an incident.
Chapter 4 of 21, and the opening of Part II, "Principles in Action" — Ch4 through Ch8 are five companies bending the previous chapter's five principles to their own constraints, and this is the first and most accessible bend: principle three (run in production) is kept; principle four (automate, run continuously) temporarily yields to a human in the loop. Downstream, Ch5 is Google's DiRT (the same posture at company scale), Ch7 is LinkedIn's ethical limits on blast radius, Ch8 is Capital One's gradual path under compliance, and Ch16 returns to full automation. In the real world it speaks to teams with a pile of services written years ago, no unified platform, and a mandate to start verifying resilience — which is to say, most teams.
The previous chapter's five principles carry an unstated assumption: the system under experiment was designed for failure. Chaos Monkey can terminate instances at random only because those instances are stateless, orchestrated by one platform, and routed around automatically once dead.
But real infrastructure is sedimentary. The dividing line this chapter draws inside Slack is blunt: newer systems are built on "failure is normal" — no local state, restartable at will, traffic routes around them. Older systems are built on "infrastructure is reliable" — local state, failover that needs a human, sometimes a dependency on the identity of one specific machine. Unhelpfully, the older systems tend to be exactly the critical layer: databases, service discovery, message routing, identity. For scale: Slack at the time had daily actives in the millions, and every connected client holds a long-lived WebSocket connection, so a wobble in the connection layer means every online user reconnecting at once.
So the question becomes: how do you experiment on a system that was never designed for failure, without the experiment itself becoming the outage?
What happens if you don't answer it? Either you don't dare — the most critical layer stays an unverified black box and your confidence rests entirely on "it hasn't failed yet", which the previous chapter just disqualified as evidence. Or you barge in — the first exercise becomes a real incident. The technical damage is bounded; the political damage is fatal, and the credibility of chaos engineering at that company goes to zero on the spot. Half of this chapter's process is engineering design; the other half is protecting the practice's political life.
This is the most actionable sentence in the chapter; go ask it of every system you own. "Routes around" means the consequences are bounded and known: instance dies, health check pulls it out, the rest absorb the load. You can compute the worst case, so you can hand the judgment to a machine and let it shake things at random. "A human has to act" means the consequences are not bounded in advance: after injection the system enters a state nobody has seen, and recovery time depends on who's around, how well they know it, and whether the runbook is current. Random automated injection there isn't an experiment. It's a lottery ticket.
This also explains why Chaos Monkey isn't a general answer — it hard-requires a platform that already manages your applications (see the evidence in §6): a system without that platform isn't "not onboarded yet", it fails the precondition architecturally.
This pipeline is the body of the chapter: it looks heavy, but every stage eliminates one specific class of failure.
1. The document (the most important step). The exercise's host writes a short document up front that has to answer: which system, which fault, which commands, which instances; which dashboards, alerts and logs to watch; and the hypothesis — what you expect to happen, including which alerts will fire and whether customers will feel it.
One question in that document is beautifully designed: "how confident are you that fault tolerance in the dev environment predicts fault tolerance in production?" It converts the abstract argument behind principle three into something the host must answer in writing, and the answer changes the design: "very confident" lets the production run be brisk; "not confident at all" demands a smaller radius, a shorter window, and more people watching.
2. Review. The document circulates among the relevant teams. This step is routinely undervalued: many problems get thought of during circulation, with nothing injected — the cheapest experiment on the whole pipeline.
3. Dry run outside production. Run it once in dev. It does not substitute for production (that would be quietly abandoning principle three); its only job is to get the embarrassing errors unrelated to your hypothesis out of the way: wrong command, missing permission, broken tooling, a dependency that won't start. Left in, those kill you somewhere irrelevant and burn a production window.
4. The production exercise. Book a window and gather the experts in one place to watch together. Why not let alerts summon them? Because the alerting is itself under test — you can't guarantee the verification process with the thing being verified. Scheduling it in business hours has a second benefit: the people who know the system best are awake, rather than the on-call being dragged out of bed at 3 a.m.
5. Record and follow up. Write down what actually happened, where it diverged from the hypothesis, and file the fixes. Skip this and the output of the first four steps decays into "everyone knew at the time" and is gone in three months.
Most teams' abort plan is one line: "roll back if there's a problem." That is not a plan. The chapter wants three specifics:
reach × (time injected + abort latency), and if you never measure the second term, squeezing the first to 1% means nothing.Ordered by value, and the most valuable one is the least expected:
Automated injection has a precondition: you already know the consequences of this fault are bounded. The first time you shake an old system you specifically don't — so having people present isn't timidity, it's supplying the missing precondition.
That also gives the direction of travel: the marginal value of humans in the room is highest the first time and lowest the Nth. Once the same experiment has run a few rounds, the consequences are understood and the criteria can be written as code, hand it to a machine to run daily (Ch16). The process is the entrance, not the destination.
And one by-product automation can never produce: education. An exercise puts five to ten engineers in one place, looking at one set of graphs, correcting their own guesses in the same minute — forcibly stitching together the partial mental models of Ch1. A pipeline produces a green light; an exercise produces five updated understandings.
The first table applies the dividing line: which approach each of your systems deserves.
| System shape | Take one machine away | Automated injection? | The right approach | Cost / failure mode |
|---|---|---|---|---|
| Stateless + platform-orchestrated | health check pulls it; the rest absorb | Yes | random automated injection, continuously | presupposes the orchestration platform |
| Stateful + automatic failover (consensus cluster, auto-promote) | it fails over, with seconds of wobble and a data cost | Semi | a few human-in-the-loop rounds first, confirming failover actually happens and takes an acceptable time | failover itself may lose the last sliver of writes |
| Stateful + manual failover | enters a state nobody has seen | No | Disasterpiece Theater: document, review, dry run, humans present | expensive in people; frequency stays low |
| A genuine single point | straight to unavailable | No | don't experiment — go build redundancy | shaking it only confirms what you already know |
One criterion: when this machine vanishes, does traffic route around it or does a human act? That decides whether the judgment can go to a machine.
The second table is the "where to run it" trade-off, and the point is to be clear about what each tier cannot catch.
| Where | Catches | Cannot catch | When to use it |
|---|---|---|---|
| Dry run outside production | wrong commands, missing permissions, broken tooling, absent dependencies | anything that depends on scale: pool exhaustion, retry storms, cache collapse | before every production exercise, always |
| Production, human in the loop (this chapter) | behaviour at real scale, whether alerts fire, whether recovery is safe | rare fault combinations — frequency stays at a handful per quarter | the first time you shake a legacy system |
| Production, automated (Ch16) | frequency and coverage, plus regression: does last month's conclusion still hold? | anything needing live human judgment; it only checks criteria already encoded | once the same experiment has run a few rounds |
Concretely:
Three sentences from this chapter can change a design review outright. One: before asking "which system do we shake first", ask "when it vanishes, does traffic route around it or does a human act" — the answer picks the method, rather than the tool picking it for you. Two: an exercise first verifies not whether the system survives, but whether you'd know. Three: an abort plan has to report a number — how many seconds until the undo takes effect.
Asked in an interview how you verify failure behaviour in production, "we use tool X" is the tool layer. "Our critical systems weren't designed for failure, so we run document, review, dry run, humans in the loop, and the abort latency has to be measured" is a different level — it shows you know what automation's preconditions are.
Evidence from industry
1 · The claim: step one of adopting chaos engineering is a process, not a tool — because the systems that matter most were never designed to break, and automated injection against them isn't an experiment, it's an outage.
2 · The dividing line: when a machine vanishes, does traffic route around it or must a human act? Human → consequences unbounded → human in the loop. It also explains why Chaos Monkey isn't general: it hard-requires an orchestration platform.
3 · Five stages: document → review → non-production dry run → human-in-the-loop production exercise → record and follow up; each eliminates a class of failure, and earlier failures are cheaper.
4 · The best question in the document: "how confident are you that dev fault tolerance predicts prod fault tolerance?" It turns "staging isn't production" from an abstract argument into something answered in writing and acted on.
5 · Gather the experts in one place for the production run, because "will the alert fire?" is itself under test — you can't guarantee the verification with the thing being verified. Business hours mean the people who know it best are awake.
6 · The abort plan needs three specifics: the undo action, how long the undo takes, and who may call a stop. Real blast radius = reach × (time injected + abort latency).
7 · Three typical findings, the first most counterintuitive: it held up and nobody knew (alerts silent); survived the fault and died on recovery; the fault wouldn't go in at all (your mental model was wrong).
8 · A human in the loop isn't backwardness — it supplies automation's missing precondition, and produces what automation can't: five to ten mental models updated at once. But frequency stays low, so the destination is still Ch16's continuous verification.
9 · The moment exercises are used to assign blame they degrade into theatre: nobody hosts, nobody writes down a pessimistic hypothesis.