learn-data-reliability-with-phoebe / Leader session 4 of 6
Learn Data Reliability with Phoebe · Leader session 4 of 6

Postmortems that change something

Most postmortems are a story with a villain and a moral, and the moral is "be more careful". They are read once, filed, and the same incident arrives again in a different month wearing a different name. A postmortem exists for one reason: the system change that makes the same incident impossible or cheaper. Blameless is how you get in the door, because a document that names a person produces one fewer honest account next time. What matters once inside is three things: a timeline in budget terms, the conditions that combined rather than a single root cause, and actions that carry an owner and a date. Harborlight's five incidents each point at one change, and read together they point at a sixth that no single postmortem could see.

🟡 Core Data and analytics leaders 45 min
0-3 · Welcome 3-22 · Blameless, and then what 22-40 · Build-along: rewrite one postmortem 40-45 · Q&A
Part 0

Where session 4 sits in the leader track

Six sessions, one running example: the orders pipeline at Harborlight, 24 hourly partitions a night, 720 a month, feeding the settlement report that pays sellers. Session 1 measured it at 95.14 percent. Session 2 turned the shortfall into an error budget: 21.6 bad partitions a month at a 97 percent target, gone by night 15. Session 3 redesigned the on-call that carried the 35 bad partitions and their 35 pages. Tonight is the morning after each of the five incidents, and what gets written down so that the next month is different. Session 5 takes up the backfills and the debt the incidents leave behind, and session 6 reports the whole month upward in three numbers. The builder track assembles the incident package in its session 6; the leader track decides what a postmortem is allowed to conclude.

Live = presented in the 45 minutes Self-study = the full depth, after class 🔍 Every diagram zooms

★ What you walk out with tonight. The test that separates a postmortem from an incident report: does it end in a change to the system, with a name and a date on it. The three parts that carry all the weight, and the one part that carries none and does damage. For one real postmortem, a rewrite with every personal name struck, the impact stated in budget terms, and every action converted to owner-plus-date or deleted. And the habit of reading the last three together, which is where the shared gap lives.

LiveWhy a postmortem that names a person produces one fewer honest account next time3 min▶

A postmortem depends entirely on people telling you what actually happened: what they saw, what they assumed, which alert they dismissed and why. That information exists in exactly one place, the memory of the person who was there, and they hand it over voluntarily. The moment a document says "the on-call failed to notice", every engineer who reads it learns the price of being noticed. Next time, the account arrives later, shorter, and with the awkward part left out. The document was accurate once and made every future document less so.

Blameless is therefore not kindness and not a culture initiative. It is the condition under which the information the postmortem needs continues to arrive. The rule is mechanical: describe what the system did and what the people knew at the time, never what a person should have done. "The alert fired at 02:10 and its title matched the previous six false pages" is blameless and more useful than "the on-call ignored the alert", because it points at a fix. The second sentence points at a person, and people are not a system change.

Real world

Harborlight's night 15 postmortem, first draft, contained the sentence "the on-call did not check the currency column". The on-call had no check to run, no runbook, and a pager that had fired six times for a corrupt batch that looked, from the alert title, like the late load of night 4. The second draft replaced the sentence with the three facts. Two of the three became actions. The first sentence would have become a quieter engineer.

Self-studyThe five incidents, in one table3 min▶

Thirty nights, 720 partitions, 35 bad. Every number tonight comes from these five rows, and the budget column assumes the 97 percent target from session 2, which allows 21.6 bad partitions a month.

NightIncidentBad partitionsShare of a 97 percent budgetWhat the reader saw
4Late load3about 14 percentThree hours missing at nine, backfilled by ten
9Upstream outage14about two thirdsReport unsignable; the outage was on the source's side
15Corrupt batch6about 28 percentOn time and wrong: a currency column arrived as text
21Flapping connector8, scatteredabout 37 percentEight hours each briefly missing, each backfilled within the hour
27Partial load4about 19 percentOn time, one of three shards missing in each

The shares add to more than one budget because the month spent more than one budget. Night 15 is where 21.6 ran out, and every partition after it was a promise already broken.

Part 1 · covers blameless postmortems and actions with owners

Blameless is the entry condition, not the outcome

10 min live

Getting the blame out of the document is where the work starts, not where it finishes. A blameless postmortem that ends in "we will be more careful" has protected the people and changed nothing. The outcome that counts is a change to the system, and three parts of the document carry it: the timeline in budget terms, the contributing conditions, and the actions with an owner and a date. Everything else is narrative, and narrative is what gets read once.

Timeline, in budget terms 02:10 first bad hour, paged 02:25 source outage confirmed 06:40 source resumed 09:30 backfill complete cost: 14 partitions two thirds of a 97 percent budget (21.6), one night not "a bad night": a number Contributing conditions source stopped publishing no dependency SLO agreed no path to page the source settlement told at 08:50 14 pages, 0 fixable here several, not one remove any and the night is cheaper Actions: owner and date communication runbook: tell settlement by 08:00 owner: on-call lead, 20th dependency SLO with the source team, paged once owner: platform lead, 30th no owner or no date: it is a wish, delete it Who who was on call who missed the alert who approved the change who should have known struck before it is read a name is not a system change, and it costs the next honest account Three panels change the system. The fourth changes only who stays quiet at the next one.
🔍 Click to zoom - the three parts of a postmortem that carry weight, and the one that is struck before it is read.
LiveWhat a postmortem is for: the system change, not the narrative2 min▶

The test is one question asked of the finished document: what is now different about the pipeline, the alert, the runbook or the contract with the source, such that the same incident either cannot happen or costs less when it does. If the answer is a sentence about the system, the postmortem worked. If the answer is a sentence about people trying harder, the document is an incident report with a moral attached, and the incident will be back.

The narrative is not useless; it is how the room reconstructs what happened. But the narrative is the input, not the output, and postmortems fail when the story is so satisfying that the room mistakes having understood the night for having changed the next one.

LiveThe timeline, in budget terms3 min▶

A timeline is a list of times and facts, and every postmortem has one. What most lack is the line that converts the facts into the currency the leader track has been building since session 2. Night 9 was not "a bad night" or "a major outage". It cost 14 partitions, which against a 97 percent target and its budget of 21.6 is about two thirds of the month's allowance in one night. That one line does three things a narrative cannot.

  • It ranks the incident without an argument. Fourteen partitions against three for the late load on night 4. The room does not need to agree about how bad it felt.
  • It tells the reader what was left. After night 9, about a third of the budget remained for twenty-one more nights. Night 15's six partitions spent it. That is why the settlement lead was told the promise was broken in the middle of the month, not at the end.
  • It sets the size of the action. An incident that spent two thirds of the budget earns a change with a real owner. An incident that spent a fortieth earns a line in a backlog. The budget decides which, and it decides it before anybody has to defend a feeling.
LiveContributing conditions, not a single root cause3 min▶

"Root cause" is a comfortable phrase because it promises there is one thing to fix. There almost never is. Night 9 had a root cause, the source stopped publishing, and it was entirely outside Harborlight's control. A postmortem that stops there concludes "nothing to do", which is false. The night was as expensive as it was because several conditions were true at once: no dependency SLO with the source, so the outage was not the source team's problem until nine; no path to page the source, so the on-call could only wait; a policy that paged fourteen times for a failure nobody on this side could fix; and a settlement lead who learned about it at 08:50 from the report itself.

Remove any one of those conditions and the night costs less. That is the test for whether something belongs in the list: not "did it cause the incident" but "if this had been otherwise, would the incident have been cheaper". Four conditions produce four candidate actions. One root cause produced none.

LiveAn action against a wish2 min▶

The last section of every postmortem is a list called actions, and most of what is in it is wishes. The difference is structural, not stylistic: an action names a change to the system, a person who owns making it, and a date by which it is done. A wish names a behaviour and hopes.

✕ A wish, from Harborlight's night 27 first draft Be more careful with shard counts during the load, and double-check partitions before the settlement run.
★ The same line as an action Add a coverage check on shard count to every orders partition; a partition with fewer than three shards is marked bad and pages once. Owner: Devi. Done by the 20th.

The good line can be checked on the 21st. Either the check exists or it does not, and if it does not, the conversation is with Devi about what blocked it, which is a useful conversation. The wish cannot be checked on any date by anybody, which is what makes it comfortable to write and worthless to have written.

Self-studyWhat to strike, and what to keep, in the first draft3 min▶
  • Strike every personal name in the narrative. Replace with a role and what that role knew at the time: "the on-call, holding a pager that had fired six times with the same title". Names survive only in the owner column of the actions, where they are a commitment rather than an accusation.
  • Strike "should have". It is always a person and always hindsight. Rewrite as the condition that made the better choice invisible at the time.
  • Strike "human error" as a cause. It is a description of the fact that a person was involved. The condition that made the error easy to make is the cause, and it is fixable.
  • Keep every timestamp. The gap between the first bad hour and the first human awareness is the detection cost; the gap between awareness and the reader being told is the communication cost. Both become actions.
  • Keep what the reader experienced, in the reader's words. The settlement lead's "I found out from the report" is worth more than any internal metric, and it is the line that justifies the communication runbook.
  • Keep the budget line. Partitions spent, share of the month's allowance, what remained. It is the sentence that gets quoted upward in session 6.
Part 2 · covers what the five incidents teach

What Harborlight's five incidents would each change

9 min live

Five nights, five postmortems, five system changes. Each is small enough to have an owner and a date. Read one at a time they are five separate fixes. Read together, two of them are the same missing indicator, and that finding is the reason postmortems are reviewed as a set rather than filed one by one.

Night 4 Late load 3 bad partitions system change: a freshness alert that pages once builder session 3 Night 9 Upstream outage 14 bad partitions system change: comms runbook, and a dependency SLO with the source fix was never here Night 15 Corrupt batch 6, on time and wrong system change: correctness check settlement already computes by hand the budget ran out here Night 21 Flapping connector 8, scattered system change: slow-window alert, so 8 page once retry with backoff no coverage signal Night 27 Partial load 4, a shard missing system change: coverage check on shard count no coverage signal same gap: no coverage indicator Five postmortems, five actions. Only the review that reads all five sees two of them share a missing indicator.
🔍 Click to zoom - five incidents, five system changes, and the pair that turned out to be one gap.
LiveNight 4, late load: a freshness alert that pages once1 min▶

Three partitions landed after their hour and were backfilled by ten. The reader saw three hours missing at nine and had them by the time she signed. The conditions: the alert fired three times for one delay, and the on-call learned of the delay from the first page and nothing from the next two. The change is a freshness alert on the burn-rate policy that pages at the first late hour and then holds, which is builder session 3's work. About 14 percent of a 97 percent budget, an action with a one-line scope.

LiveNight 9, upstream outage: a communication runbook and a dependency SLO2 min▶

Fourteen partitions, two thirds of the budget, and not one of them fixable from Harborlight's side. The fix was never here, which is exactly why this postmortem is the one most teams write as "nothing to do". Two conditions were on this side and both become actions.

  • A communication runbook. When an upstream outage is confirmed, the settlement lead is told before 08:00 which hours are missing and when the backfill will land. She learned it at 08:50 from the report. Owner the on-call lead, date the 20th.
  • A dependency SLO with the source team. A written expectation of the source's freshness, a path to page them once when it is missed, and the outage on their budget rather than only on Harborlight's. Owner the platform lead, date the 30th, because it involves another team and a conversation.

Neither action makes the next outage impossible. Both make it cheaper: fifteen minutes of communication instead of a morning of surprise, and a source team that knows before nine.

LiveNight 15, corrupt batch: a correctness check the settlement team already had2 min▶

Six partitions landed on time with a currency column that had arrived as text. Every freshness signal said perfect. The report was wrong for six hours and the finance analyst caught it against the bank file. The budget of 21.6 ran out on this night, so this is the postmortem written in the knowledge that the month's promise was already broken.

The change is almost embarrassing in its size: the control total that caught the fault was already being computed by hand in a spreadsheet every morning by the settlement team. Turning it into a correctness check on the pipeline, so a partition whose totals do not reconcile is marked bad and pages once, was one column and one comparison. The condition that mattered was not a missing capability. It was that the check lived on the reader's side of the boundary and the pipeline never saw it.

Real world

The most valuable correctness check in most data organisations already exists in a spreadsheet owned by whoever signs the report. It is rarely in the pipeline, because nobody asked the reader what they check by hand. That question is the cheapest postmortem action there is.

LiveNight 21, flapping connector: a slow-window alert and retry with backoff1 min▶

Eight partitions, scattered across the night, each briefly missing and each backfilled within the hour by the connector reconnecting on its own. The reader may not have noticed at all. The on-call was paged eight times. Two conditions: the connector retried immediately and failed immediately, so each flap was a full failure, and each flap was a separate page. Two actions: retry with backoff on the connector, owner the platform engineer who owns it, and a slow-window alert so eight scattered failures burn the budget visibly and page once rather than eight times.

LiveNight 27, partial load: a coverage check on shard count1 min▶

Four partitions landed on time, with totals that reconciled for the rows present, and each missing one of three shards. Freshness passed. Correctness, as written, passed. The job exited cleanly four times. The reader saw a report that was a third light for four hours. The single condition: nothing measured whether a partition had processed the amount of data it should have. The action is the one already written as a line in Part 1: a coverage check on shard count, a partition with fewer than three shards marked bad and paged once, owner Devi, by the 20th.

LiveThe review that reads all five together2 min▶

Each postmortem above is correct on its own. The finding none of them produces appears only when the five are read as a set: nights 21 and 27 are the same gap. A flapping connector that drops a partition and a load that lands two shards of three are both failures of coverage, the indicator that asks whether a partition processed as much data as it should have, and Harborlight had no coverage indicator at all. Two incidents, twelve partitions, more than half of a 97 percent budget, one missing measurement.

  • A single postmortem cannot see it. Night 21's document is about a connector. Night 27's is about shards. The word coverage appears in neither because the people writing each were, correctly, looking at their own night.
  • The review is a standing meeting, not a reaction. Monthly, all postmortems since the last one, read for repeated conditions rather than repeated incidents. Repeated incidents are obvious. Repeated conditions hide behind different names.
  • It changes the size of the action. Two small actions, a retry and a shard check, become one indicator that would have counted both nights and any future night that looks like neither. That is the change the review earns, and it is the one that gets reported upward in session 6 as "the month found a missing indicator", which is a sentence a steering committee can act on.
Build-along

Rewrite one postmortem

★ 18 min · everyone builds

No code, one document, one pass with a pen. Bring the postmortem, incident report or long chat thread for the worst night you brought from session 3. If you have nothing to hand, use Harborlight's night 9 first draft, which named the on-call twice, called the cause "upstream outage, nothing to do", and listed one action: "monitor the source more closely". The output is the same document, shorter, with a budget line and actions that can be checked on a date.

Take one real postmortem. The most recent one is fine; the one that still stings is better. Print it or open it where you can strike lines. Read it once straight through and write down, in one sentence, what is now different about the system because of it. If the sentence is about people, that is the finding, and the rest of the steps are the fix.

Strike every sentence that names a person. In the narrative, replace the name with a role and what that role knew at the time. "Ana ignored the alert" becomes "the on-call held a pager that had fired six times with this title that week". Names survive only in the owner column of the actions. Count what you struck; it is usually more than the room expects.

Rewrite the impact line in budget terms. Bad events, as a share of the month's allowance, and what was left afterwards. Harborlight's night 9: 14 partitions, about two thirds of a 97 percent budget of 21.6, about a third left for twenty-one nights. If your pipeline has no target yet, write the events and "against no agreed budget", which is itself a finding for session 2's homework.

Convert each action into owner-plus-date, or delete it. Every line in the actions list gets a named owner and a date, or it is struck. "Monitor the source more closely" has no owner, no date and no check that can be run on any morning; it goes. "Communication runbook, settlement told before 08:00, owner on-call lead, by the 20th" stays. Expect to lose half the list and to have a better list.

Read the last three postmortems together and write the one gap they share. Not the incidents, the conditions. Lay the three condition lists side by side and look for a condition, an indicator, a runbook, a contract, that is missing in at least two. Harborlight's answer was "no coverage indicator" from nights 21 and 27. Write it as an action, with an owner and a date, and it becomes the first line of session 6's report.

✕ Harborlight's night 9 first draft, actions section Root cause: upstream outage. Nothing we could have done on our side. Actions: monitor the source more closely. On-call to be more proactive about communicating with settlement.
★ The same section after the pass Impact: 14 partitions, about two thirds of the 97 percent budget (21.6), about a third remaining for 21 nights. Contributing conditions: source stopped publishing 02:10 to 06:40; no dependency SLO with the source; no path to page the source team; settlement learned of the gap at 08:50 from the report; 14 pages for one incident. Actions: (1) communication runbook, settlement told before 08:00 with missing hours and backfill time. Owner: on-call lead. Done by the 20th. (2) Dependency SLO with the source team, one page to them on breach. Owner: platform lead. Done by the 30th. (3) Burn-rate policy replaces per-partition paging. Owner: Devi. Done by the 15th.

Do not add a "lessons learned" section. If a lesson is real it is a condition in the list or an action with an owner. If it is neither, it is a moral, and morals are what get filed. The shortest postmortem that ends in a checkable change beats the most thorough one that ends in an insight.

Homework

Before session 5

30 min
  1. Finish the rewrite of the one postmortem and share it with the person who was on call that night. Write down whether they added anything to the account that the first draft did not have. That difference is what blameless buys.
  2. Pull the last three postmortems for one pipeline and write the shared gap in one sentence, as an action with an owner and a date. If there is no shared gap, write that down too; three genuinely unrelated incidents is a finding.
  3. For every action in those three documents, mark whether it was done by its date, done late, or never had a date. The proportion in the last column is the number to bring to session 6.
  4. List every backfill the five incidents required and how long each took. Night 9's took until 09:30 and night 21's eight happened by themselves. Session 5 is about what those hours cost and where they belong in the budget.
Check yourself

Three questions

A postmortem's actions list reads: "Be more careful with shard counts during the load." What is wrong with it?

An action names a change to the system, who owns making it and when it is done: "coverage check on shard count, owner Devi, by the 20th". A wish names a behaviour and hopes. Naming a person in the narrative costs the next honest account.

Night 9's outage was entirely on the upstream source's side. The first draft concluded "root cause: upstream outage, nothing to do". Why is that the wrong conclusion?

A single root cause outside your control produces no actions. Contributing conditions, tested by "would the night have been cheaper without this", produced a communication runbook and a dependency SLO, both with owners and dates.

Harborlight's night 21 postmortem proposed retry with backoff on a connector. Night 27's proposed a shard-count check. Each was correct. What did reading them together add?

Repeated incidents are obvious. Repeated conditions hide behind different names. The set review found the shared gap and turned two small fixes into one indicator that counts both nights and any future night like neither.

Sources covered

What tonight maps to

✓ Blameless postmortems as professional norm Why a named person costs the next honest account, what to strike and what to keep, and blameless as the entry condition rather than the outcome.
✓ Actions with owners and dates, against wishes The structural test: system change, named owner, date, checkable on a morning. Contributing conditions in place of a single root cause.
✓ What Harborlight's five incidents teach Nights 4, 9, 15, 21 and 27, each to its system change; night 9 at 14 partitions as two thirds of a 97 percent budget of 21.6; the shared coverage gap between nights 21 and 27.
◐ The incident package: timeline, impact, actions as a written template Builder session 6 assembles it. Here a leader decides what the document is allowed to conclude.
◐ Backfills and the debt the incidents leave Session 5, next. Tonight only counts the hours each backfill took.
◐ Vendor incident tooling Named as a category. Any tool that stores a timeline, an owner and a date will do; none of them writes the actions.
· Traces, spans and incident review for AI services Not covered by design. The AI observability course owns those; the objects here are tables, partitions and the people on call for them.

Session 4 cheat sheet

Blameless is the doorA named person costs the next honest account. Strike names from the narrative; keep them only as owners.
The outcome is a system changeSame incident impossible or cheaper. If the answer is people trying harder, it is an incident report.
Timeline in budget termsNight 9: 14 partitions, two thirds of a 97 percent budget of 21.6, a third left for 21 nights.
Conditions, not a root causeTest each: would the night have been cheaper without it. Several conditions, several actions.
Action against wishSystem change, owner, date, checkable on a morning. "Be more careful" is deleted.
Five nights, five changesFreshness alert once; comms runbook and dependency SLO; correctness check; slow-window alert and backoff; coverage check.
Read them as a setNights 21 and 27 were one gap: no coverage indicator. No single postmortem sees a shared condition.
Ask the reader what they check by handThe settlement team's spreadsheet was the correctness check. Cheapest action there is.