← Back to context

Comment by tptacek

5 hours ago

I'm a broken record on how important I think this document is, and that it's hard to appreciate it until you've had extended experience with complex systems actually failing.

The most commonly cited subtext or thrust of it is that "root cause analysis", at least on complex systems, is a fools errand. Something goes wrong, say, in a distributed lock system, and your whole deployment system enters a metastable failure state. Naturally, the "root cause" seems like lock system resiliency. But definitionally a metastable failure is one that persists after the inciting condition is resolved. Now you have two "root causes", the lock failure and the metastability of the deployment system fault. Keep looking and you'll find more.

But to me the biggest brick to the forehead in this piece is further observation that random things are failing all the time in any complex system. "Complex systems run in degraded mode". Resilient components are good, but it's the resiliency of the overall process that orchestrates the whole system that determines whether things are going to blow up.

All practitioner actions are gambles. I should have that inked somewhere.

>The most commonly cited subtext or thrust of it is that "root cause analysis", at least on complex systems, is a fools errand.

It's only an issue when people take that phrase very literally. People have common sense to understand that things have multiple causes and a chain of events. NASA has "Root Cause Analysis" (singular) all over various official documentation and it doesn't stop them from understanding that the failed O-rings were not the single root cause of the Challenger explosion. Another cause was management normalizing the deviations of previous unsafe datapoints of prior launches which let them greenlight the launch in freezing temperatures. Another cause was the unrealistic flight schedules which can subconsciously pressure management into normalizing dangerous deviations. It wasn't The Rogers Commission that found the multiple causes; it was NASA engineers and management themselves explaining the multiple causes as they were interviewed by the Rogers Commission members.

For whatever reason, alternative jargon such as "Root Causes Analysis" (plural) or "Proximate and Distal Causes Analysis" isn't as widely used.

  • > Another cause was the unrealistic flight schedules which can subconsciously pressure management into normalizing dangerous deviations.

    In the case of Challenger, I think it's pretty clear this was the "root cause":

    > According to testimony by Kilminster and Boisjoly, Mason finally turned to Bob Lund and said, "Take off your engineering hat and put on your management hat." Joe Kilminster wrote out the new recommendation and went back on line with the teleconference.

    > The new recommendation stated that the cold was still a safety concern, but their people had found that the original data was indeed inconclusive and their "engineering assessment" was that launch was recommended, even though the engineers had no part in writing the new recommendation and refused to sign it.

    -- https://onlineethics.virginia.edu/cases/engineering-ethics-c...

    If you want to take the "system" view here, as is often the case, it is the organizational power structure and incentives therein that comprise the dangerous system. You had engineering experts easily predicting the disaster, but they had no decision making power. That was the problem. But if you set up an organization like that, where the egos of "get it done" managers are allowed to gamble with other people's lives to win their own accolades, the system is doomed from the start.

    • If you’re doing “five* whys” analyses correctly, you don’t stop at the technical causes. You continue further to analyze the causes that precipitated the technical errors, too. This exposes the business reasons behind them and forces management to face them.

      * the number five isn’t magical here. You don’t have to stop at five, and you often shouldn’t.

Same, I think this document is fundamental to our industry and understanding complex systems. We have it as a quarterly reminder to review in our Slack. I give it to everyone that makes it past the first couple of interviews when applying and tout its usefulness for thinking through systems design all the time. RIP Dr. Cook.

> "root cause analysis", at least on complex systems, is a fools errand.

Not when properly understood--which, to be fair, it often isn't. The proper purpose of root cause analysis is to answer the question: does this failure mean I need to change something about this system? If the answer turns out to be yes, the thing that you need to change gets called the "root cause" of the failure. Of course that's a misnomer, strictly speaking, but that doesn't mean you answered the actual question wrong.

  • Cook doesn't object to postmortems and to using hard failures as opportunities to spot interventions (though, remember, all practitioner actions are gambles). The issue is in attempting to identify a single privileged root cause.

  • I don’t blame people for being confused about the term in software — it’s a bit more straightforward in manufacturing, for example.

    That said, if you look at a system that failed and determine a root cause analysis is pointless, you may have just stumbled upon your root cause.

    • > it’s a bit more straightforward in manufacturing

      That's because manufacturing is a simpler environment where causes and consequences are more conceptually distinct.

      Until you start to pull management decisions into your analysis, of course. Then it becomes just as complex as software.

      1 reply →

  • does this failure mean I need to change something about this system?

    It's safer to say 'does this failure mean I need to change the system?'. Otherwise you're still facing the single cause trap.

    • > Otherwise you're still facing the single cause trap.

      "Something" does not have to mean "one single thing". But I would be fine with your phraseology if it ended up making it clearer to whoever was doing the analysis.

Root Cause Analysis is an organizational ritual that makes people feel like they're doing something. It's more about politics than about engineering. Not only is the process not useful- more often than not the correct root cause isn't even correctly identified.

Basically a poorly designed system is going to fail somewhere. I like to think about it either as the part of the iceberg that's visible or my other analogy is lighting doesn't strike twice at the same place. A robust/well designed system is just very different than a brittle/poorly designed system. The brittle system will exhibit random failures and trying to chase them is counterproductive.

We do have systems that are fairly complex and reliable. Take an internal combustion engine as one example or an entire car or an airplane (well, one of the well designed ones). Then we build bigger systems on top of that, a city's transportation system, where we do get to scales where things "fail" all the time. Yes, some bus somewhere or some train somewhere doesn't get to a station at the correct time, because a bus breaks down or heavy traffic or whatnot. But still a well designed system is robust to those. The parts we build the systems out of are well understood and so the resulting reliability can also be understood.

With software specifically we tend to not design and build that well. We throw stuff together. Then we're surprised when they fail. And we make excuses by saying "complex systems". I often feel it's our lack of discipline and skill vs. other domains and not really that our systems are that much more complex.

EDIT: Some might argue that mechanical systems like engines are just fundamentally simpler than software. But look at something like a bearing. Just one bearing is an incredibly complex system. Bearing failure is a statistical event, some bearings fail sooner, some fail later. There are centuries of know-how in the bearings used in said engine. Mechanical engineers generally use well understood components/designs and build in margin to meet the requirements of the engine they're designing. In software we often re-invent the "bearing" or we'll pick some new unproven design for a "bearing" and we'll generally build without a good understanding of the performance or failure modes of our "bearings" and without a known pattern as to how to use them and when to use them. And then we're surprised when our "car" fails in weird ways. We also don't test to the same standard that a mechanical engineer would use for a new design. They would have a room full of widgets doing ten million cycles before they accept the design as part of a larger system. We "yolo" it...

  • It's notable how many more engineers are paying attention to the details in mechanical systems. Take a random electrical connector in your car. Likely dozens of engineers were involved in its design and manufacturing. Dozens were involved with incorporating it into the vehicle design and installing it during manufacturing. There are entire teams who specialize in e.g. high-vacuum flange seal design. It's pretty rare to find similar teams in software.

    I will argue that mechanical systems are fundamentally simpler than software, though. Try writing a datasheet for some library as an exercise. Thoroughly documenting the interface is tedious, but straightforward. You need graphs though, so maybe performance under load? But that's assuming a lot about hardware and runtimes, so you need to characterize it under all of those possible degrees of freedom. That's a much larger space than physical components have. Imagine characterizing/qualifying parts under disparate manufacturing methods that include "some sleep-deprived rando who's never heard of a lathe needs to build this successfully in his garage" (i.e. the norm in OSS).

    And even if you successfully write a datasheet, some unrelated component elsewhere in the system can remotely interfere with your software through chained vulnerabilities, memory pressure, contention, etc. Mechanical engineers rarely worry about entirely disconnected parts interfering in undocumented ways, because reality limits how things can interact. RF engineers consider this kind of problem more regularly, and need correspondingly more animal sacrifices. The larger the software the worse this problem becomes, and small software systems are increasingly endangered these days.

  • A root cause investigation that concludes 'the system as a whole is fragile and poorly designed' sounds highly valuable - and they do happenl; I've seen them in healthcare

Check out the book called, The Logic of Failure. I think you’ll like it

  • Two other great books on failures in inevitably complex military operations are:

    1. Command in War (1985) by Martin van Creveldt. He dissects may complex but common military failure causes up to the Vietnam War.

    2. Team of Teams (2015) by Stanley McChrystal that is focused on what he and teams learned in Iraq but extrapolating to most organizations.

> I'm a broken record on how important I think this document is, and that it's hard to appreciate it until you've had extended experience with complex systems actually failing.

If you want a bit of cheese to go with that wine, this article pairs nicely with The Grug-Brained Developer: https://grugbrain.dev/

  • I am also a broken record about Grug-brainedness, but I don't need to be so repetitive about it because so many other people are too.

    • My Grug-brained hill to die on is that there are many pieces of technology like the LM741 opamp, the Rover V8, Morris A-series and Peugeot XUD engines, and a big SQL database running on a thumping great Unix box, that have remained essentially unchanged for decades, worked well when they were new, and are still a perfectly good solution today for so much of what you want to do.

      You know what they have in common? A lack of complexity. Lovely simple technology, fix it with a hammer. Drive it to the moon and back. Drive it across the desert. Bring tools though!

      1 reply →