Learning from Production Incidents
Learning from production incidents is the feedback loop that turns a failure seen by real users into a lasting improvement. An incident is an unplanned event in production that harms users or the business: an outage, wrong data, a payment taken twice. After the service is restored, the team reviews the incident in a postmortem, finds which tests or checks should have caught the problem, and adds them, usually as regression tests.
Example: some customers were charged twice after a release. The fix stops the double charges; the learning is asking why no test ever ran against a slow payment provider, then adding one that does.
Why it matters
A production incident is the most expensive way to find a defect: users are harmed, support and finance spend time on it, and the team works under pressure. If the only outcome is a hotfix, the conditions that let the defect escape stay in place, and a similar incident follows.
For a tester, every incident is evidence about the test approach that no review can provide: it shows exactly where the test basis, test levels, environments or oracles did not match reality. Using that evidence without blame keeps the regression suite tied to real risks rather than guesses.
From incident to prevention: the feedback loop
This lesson starts where detection ends. The order matters: restore the service first, investigate second, and change tests and process last, once the facts are known.
In ISTQB terms, what users experience in an incident is a failure: the system does not do what it is required to do. The cause may be a code defect, but also configuration, data, capacity or a third-party service, so establish what failed and why before deciding that a fix and a new test are the answer.
- Detect and declare: an alert, a synthetic check or a customer report opens an incident record with time, impact and owner.
- Mitigate: stop the harm with a rollback, a feature flag or a configuration change. Mitigation buys time; it is not the fix.
- Reconstruct the timeline: deployments, configuration changes, alerts, logs and decisions, all in one time zone.
- Hold a blameless postmortem: impact, timeline, contributing causes and action items.
- Analyse the test gap: which test, check or review could have caught it, at which level, and why it did not.
- Prevent and verify: add regression tests and other actions, each with an owner and a due date, and confirm they are done.
- 1Detect and declaretime, impact, ownerAn alert, a synthetic check or a customer report opens the incident record
- 2Mitigatenot yet the fixA rollback, a feature flag or a configuration change stops the harmservice first
- 3Reconstruct the timelineDeployments, configuration changes, alerts, logs and decisions, in one time zone
- 4Blameless postmortemimpact, timeline, causes, action itemsContributing causes in the system and the process, not a person to punish
- 5Test gap analysisWhich test or check could have caught it, at which level, and why it did nottester leads
- 6Regression tests and other actionsTests, requirement, environment, monitoring: each with an owner and a due date
- 7VerifyThe new test fails on the faulty version and passes on the fix; every action is closed
Throughout steps 3–5 Blameless: ask what and why, not who
Then:Into the regression suite and the risk analysis for the next release
Blameless postmortems
The lesson on quality culture introduced the postmortem as a written record of an incident: its impact, detection, mitigation, causes and follow-up actions. Here you run one. The Google SRE book recommends agreeing the triggers in advance, for example user-visible downtime or degradation beyond a threshold, any data loss, a manual intervention such as a rollback, a long resolution time, or a failure that monitoring did not detect.
Blameless means the review looks for contributing causes in the system and the process, not for a person to punish, and assumes everyone acted in good faith with the information they had. This is practical, not polite: people who fear blame leave out details, and the review misses the real causes. Blameless does not mean unaccountable; every action item has a named owner.
- Blaming: "The developer forgot the timeout case." Blameless: "The retry path had no test, and the code review checklist has nothing on slow responses."
- Blaming: "QA missed it." Blameless: "The payment mock in the test environment always answers in under a second, so the timeout path never ran."
- "Human error" is never a root cause on its own: ask what made the error easy to make and hard to notice.
From postmortem to test gaps and regression tests
The tester's main contribution to a postmortem is the test gap analysis. Trace the failure back through the test process: was there a requirement, a test condition and a test case for this behaviour, and did the test run against this build in an environment like production? Each "no" marks a gap, and one incident often has several. Each kind of gap calls for a different action.
- Missing test condition or test case: neither the requirement nor the risk analysis named the situation, or the test design never reached it, for example no boundary values at the edge. Add the condition, the acceptance criterion or the test case.
- Wrong test level: only an end-to-end happy-path test existed; a unit or API test reaches the faulty branch more easily.
- Unrealistic data or environment: test data, mocks, time zone, configuration or volumes differ from production.
- Weak oracle: the test ran but did not assert what went wrong, for example it checked the HTTP status but not the number of charges.
- Test not run: skipped, quarantined as flaky, or left out of the regression selection for this change.
- Detection gap: users found the problem before monitoring did. That action belongs to monitoring, not to the test suite.
Try it: Regression Scenario Generator Try it: Test Case Generator
Worked example: a double charge after a release
A fictional incident in an online store. Release 7.3 lowered the payment client's timeout from 30 to 10 seconds. Under load the provider sometimes answered after more than 10 seconds; the client then retried with a new payment reference, which the provider treated as a new payment, so some customers were charged twice.
In the postmortem excerpt below, customers rather than monitoring detected the problem, 67 minutes after the first duplicate charge, and most action items are tests and checks, not the code fix.
- Once the incident was declared, mitigation took twenty minutes; prevention needed a requirement, two tests, a new test-environment capability and an alert.
- Before the fix, the API test was run against release 7.3 and failed with two charges; with the fix it passed. A regression test that has never failed against the defect proves nothing about it.
- The tests target the condition, a slow provider followed by a retry, not the exact orders from the incident, so they also protect every other flow that uses the same payment client.
INC-0412 Customers charged twice for one order after release 7.3 (fictional)
Impact 37 orders charged twice; all refunded the same day; no data lost
Timeline all times UTC+3
09:40 Release 7.3 deployed: payment client timeout 30 s -> 10 s
09:58 First duplicate charge (found later in the payment logs)
11:05 First customer complaint to support
11:30 Incident declared; payments team and QA join
11:50 Mitigated: timeout back to 30 s by configuration; no new duplicates
15:00 All duplicate charges refunded
Detection by customers, 67 minutes after the first duplicate; no alert fired
Contributing causes (no individuals named)
- A retry after a timeout sends a new payment reference, so the provider
cannot recognise it as the same payment.
- The payment requirement said nothing about retries.
- The payment mock in every test environment answers in under 1 s,
so the timeout-and-retry path never ran in any test.
- No monitoring signal for "more than one successful charge per order".
Action items owner due
1 Acceptance criterion: a retried payment never charges twice PO 7.4
2 Unit test: a retry reuses the original payment reference dev 7.4
3 API test: the mock answers the first call after 12 s, the
retry at once; exactly one charge, order status PAID QA 7.4
4 Payment mock simulates slow answers and, like the provider,
treats a repeated payment reference as the same payment QA 7.4
5 Alert on any order with more than one successful charge ops 7.4Try it: Timestamp Converter Try it: Date Difference Calculator
Common mistakes
- Writing the postmortem around a person ("the developer forgot") instead of the conditions that made the error possible.
- Adding a regression test that replays the customer's exact order instead of the condition behind the failure.
- Never running the new test against the faulty version, so nobody knows whether it would have caught the incident.
- Putting every new check into a slow end-to-end UI test when a unit or API test reaches the faulty branch faster.
- Treating "add more tests" as the only action when the gap is in the requirement, the environment or the monitoring.
- Leaving action items without an owner and a due date, so they are never done.
The QA perspective
The tester usually joins after mitigation but can prepare at once: which tests ran against the release, where, and with which data. In the postmortem, ask the gap questions calmly and include the test process; "our tests could not see this because the mock never times out" is a finding about the system, not a confession.
Afterwards, link the incident, the defect, the new test cases and the changed requirement in the tracker, and check at the next release that the action items are closed. Review escaped defects every few months: repeated gaps of one kind, such as time zones or retries, feed the risk analysis and the test strategy.
Practice exercise
Turn a flash-sale time-zone incident into tests
Incident (fictional): a flash sale was announced to run until the end of 30 September, Riyadh time (UTC+3). The server compared the end time with the current time in UTC, so the sale price stayed on three hours too long, until 02:59:59 on 1 October in Riyadh. Finance noticed the next morning. All automated tests run on CI machines set to UTC, and the sale tests used dates a day before and a day after the end.
The draft postmortem says: "The developer forgot to convert to Riyadh time." and "QA should have tested it." Rewrite both sentences blamelessly, classify the test gaps, design the regression tests and name at least one action that is not a test.
- Rewrite the two blaming sentences as statements about the system and the process.
- Classify the test gaps using the categories from this lesson.
- Design at least two regression tests with the level, the exact input times and the expected results.
- Add the actions that are not tests, and say how you will prove that the new tests detect the defect.
Show the model answer
Blameless rewrites: "The sale-end check compared an end time meant in Riyadh time with the server clock in UTC; no requirement or checklist names the time zone for sale dates." and "The sale tests used dates a full day from the end, and all tests run in UTC, so the three-hour gap could not appear."
Test gaps: missing test condition, because the requirement does not state the time zone; missing test case, because no boundary values were tested around the moment the sale ends; unrealistic environment, because every test runs in UTC; detection gap, because finance, not monitoring, found the problem.
Regression tests: a unit test with a fixed clock (the test sets the current time instead of reading the real one), where 30 September 20:59:59 UTC (23:59:59 in Riyadh) gets the sale price and 21:00:00 UTC (midnight in Riyadh) gets the regular price; an API test that sets the test environment's clock to 30 September 21:00:00 UTC, prices the product and expects the regular price; and one more run of the suite with the machine time zone set to Asia/Riyadh, whose results must match the UTC run, which shows they do not depend on the server's zone.
Other actions: state the time zone in the sale requirement, alert on orders charged a sale price after the sale's end time, and check other date rules, such as coupons and delivery cut-offs, for the same pattern. Prove the tests by running them against the faulty version, where 21:00:00 UTC still gets the sale price and they fail, then against the fix, where they pass.
Frequently asked questions
Does every incident need a full postmortem?
No. Agree the criteria in advance, such as user-visible impact beyond a threshold, any data loss, a rollback or other manual intervention, a long resolution time, or a problem that monitoring did not detect. Smaller incidents can get a short written review, but several similar small incidents together deserve a full postmortem.
Does blameless mean nobody is responsible?
No. Nobody is punished for an honest mistake made with the information they had, but every action item has a named owner and a due date, and the team is accountable for finishing them. The absence of blame is what lets people describe their decisions honestly, and the analysis depends on that.
Must every incident end with a new automated test?
An incident caused by a defect should normally get at least one regression test at the lowest level that can detect it. When the cause is capacity, a third-party outage or a configuration change, the better action may be an alert, a configuration check or a release checklist item. Record the decision either way.
How does a postmortem relate to root cause analysis?
Root cause analysis, such as the 5 whys or a fishbone diagram described in the defect triage guide, is a technique used inside a postmortem to get from the failure to its causes. The postmortem is wider: it also records impact, timeline, detection and mitigation, it usually finds several contributing causes rather than a single one, and it ends with owned actions.
References
- Postmortem Culture: Learning from Failure — Site Reliability Engineering (John Lunney and Sue Lueder)Blameless postmortems: which incidents call for one, what it records — impact, root causes and follow-up actions — and why blame is kept out of it.
- ISTQB Certified Tester Foundation Level (CTFL) v4.0The foundation syllabus of software testing: test levels and types, test design techniques, test management and tools.
- ISTQB GlossaryThe standard definitions of testing terms — test case, regression testing, severity, priority, boundary value analysis and the rest.
Practise with Mutqan tools
Generate regression scenarios from a change description and a list of affected and related modules.
Generate structured test cases (id, title, preconditions, steps, expected result, priority) from a feature description and field list.
Convert a date and time between timezones (Riyadh, Amman, Delhi, UTC, New York, London…).
Convert timestamps (seconds, milliseconds, microseconds) to human dates and back, in any timezone.
Calculate the exact difference between two dates in years, months, days, hours and total units.
Go deeper
Your progress on this topic
Not started
Mark the topic complete when you have studied it and done the exercise.
Sign in to track your progress
Mark topics complete, continue where you left off and unlock specialisation exams.