1. Courses
  2. System Design
  3. System Design Case Studies
  4. Stop 1

30 minIntermediate

Running a design review

A design review is where a team finds the expensive mistakes while they are still cheap to fix. This lesson turns the thinking loop from What system design really is into a meeting you can lead: what to send before it, what to ask at each step, how to disagree well, and how to write the decision down so it stays decided. The three case studies that follow in this course are each run as one of these reviews.

By the end you can

  • Run a 45 to 60 minute review with a time budget for each step
  • Write a design doc and an architecture decision record (ADR) from a template
  • Read an engineer's architecture diagram and spot what is missing
  • Pick the right question for each area: data, scale, failure, security, operations, cost
  • Turn a disagreement into a condition you can test, then decide and move on

The everyday picture

A week before a new grocery store opens, the area manager walks through it with the building contractor, the IT person and the new store manager. They do not rebuild anything. They walk the customer's path from the door to the checkout, with a checklist in hand. Where does the queue go on the eve of a big festival? What happens to the tills when the power goes out? Where does the truck from the warehouse unload, and does it block the entrance? Each question takes a minute or two.

Everything they find goes on a list, with a name and a date next to each item. The walk takes an hour. Moving a checkout counter after opening day takes a month and annoys every customer. A design review is the same walk, done on a document instead of a shop floor. You follow the user's path through the design, ask what happens when each part fails, and leave with a written list of decisions and owners.

What a review is for, and your role in it

A has three jobs. It finds the risky parts of a plan before code exists. It makes the important decisions visible, so they are made on purpose. And it gives everyone the same picture of the system. It is not a status meeting, a demo, a vote, or an exam for the person who wrote the design.

A good review has clear roles, and naming them in the invite prevents most chaos:

  • Author. Writes the and presents it. Usually the engineer who will build it.
  • Reviewers. Two to five people who read the doc before the meeting. Include someone who will run the system in production and someone from a team that the design touches.
  • Decider. One named person, usually the tech lead, who makes the call if the room does not agree. Without a , disagreements end in silence and come back next month.
  • Timekeeper and note-taker. Often the PM. The note-taker writes decisions and actions live, where everyone can see them.

If you are the product manager (PM), your role is specific. You own the problem, the requirements, the numbers and the priorities. You make sure the hour is spent on the risky parts, and that the meeting ends with a decision and owners. You do not need to be the best engineer in the room. Your strongest tool is a precise question, asked at the right moment. On requirements, speak first. On technical choices, ask questions and speak last, so engineers say what they really think before they hear what the PM prefers.

Not every ticket needs a review. Hold one when a change is hard to undo (a new data store, a core table, a public API), when it touches money or stock, when it crosses teams, or when it will take more than about two weeks to build. For smaller changes, a half-page note in the pull request is enough.

Quick check

Which of these changes most clearly needs a full design review?

Before the meeting

Most of a review's value is created before anyone enters the room. The author shares the doc one or two working days ahead. Reviewers leave comments in the doc itself. The author answers the easy comments in writing, so the meeting is spent on the hard ones.

The invite states the ask: the decision you need and the parts you want reviewed. "Decide: Postgres job table or BullMQ for report jobs. Review: what happens when the report worker crashes." An invite that says "Discuss report design" produces a discussion, and discussions do not end.

If people often arrive without reading, start the meeting with eight minutes of silent reading. Some companies, Amazon among them, start meetings this way with a written memo. It feels strange the first time, and it works better than a slide deck, because a written doc cannot hide a missing number behind a nice picture.

Quick check

Which line in an invite makes it most likely that the meeting ends with a decision?

The agenda: the thinking loop with a clock

The review follows the same loop you met in What system design really is. The difference is the clock. Each step gets a fixed budget, and the timekeeper says out loud when it runs out. The deep dives get the biggest share, because that is where designs usually fail.

Step Minutes (of 60) Before doc sent 1 to 2 days ahead 1 Requirements who, what, how well 5 min 2 Numbers users, QPS, GB 5 min 3 API and data endpoints, tables, keys 10 min 4 Big picture one request, end to end 5 min 5 Deep dives the 1 or 2 hard parts 15 min 6 Failure modes cover each box in turn 10 min 7 Trade-offs options, the decision 5 min 8 Rollout and ops migrate, monitor, cost 5 min After ADR, owners and dates
A 60-minute review. The doc goes out before the meeting, so nobody reads it for the first time in the room. A quarter of the time goes to deep dives and a sixth to failure modes. The meeting ends with written decisions and named owners.

What each step produces

  1. Requirements (5 min). The author reads back the functional requirements, the non-functional ones with numbers, and the non-goals. Ask: "Which of these is the hardest to meet?" That answer often picks the deep-dive topic.
  2. Numbers (5 min). Peak requests per second, rows per day, size in one and three years (Estimation). Ask: "Can you show me the arithmetic?" A number without its arithmetic cannot be checked.
  3. API and data (10 min). The main endpoints, the tables, their keys and indexes (APIs done right, Data modeling, Indexes). Ask: "Which unique key stops a retry from creating a duplicate?"
  4. Big picture (5 min). One diagram. The author walks one real request through it, out loud, from the phone to the database and back.
  5. Deep dives (15 min). One or two of the hardest parts, chosen by the decider before the meeting. For stock, it is usually "two people buy the last unit". For sync, "the upload succeeded but the reply was lost".
  6. Failure modes (10 min). Cover each box with your finger and ask what the user sees (Timeouts and retries). Write the answers in a table.
  7. Trade-offs (5 min). The options considered, the one chosen, and what the team gives up by choosing it. The decider decides.
  8. Rollout and ops (5 min). The migration plan (Safe migrations), the release plan and rollback (Shipping safely), the dashboards and alerts (Observability), and the monthly cost.

For a 45-minute slot, cut each step a little and keep the shape: 4, 4, 6, 4, 12, 7, 4 and 4 minutes. Never cut the deep dives and failure modes to make room for a longer presentation.

Two tools keep the clock honest. The first is a : a list on the shared screen where off-track topics go, each with an owner, to be handled after the meeting. The second is one sentence the timekeeper can always say: "We have two minutes left on this. What fact would settle it, and who can get it by Thursday?" Most stuck debates are missing a fact, and nobody in the room has it.

The design doc

A design doc is the input to the review. A good one is three to six pages. Longer docs go unread, so details belong in an appendix. The order of the sections matters: everyone reads the top, and only engineers read the middle closely.

The summary and ask is the first paragraph: what we are building, why now, and what decision we need. The goals and non-goals stop scope from growing in the meeting. The alternatives section is the one most often skipped, and the most useful. If a doc presents only one option, nobody can tell whether it was chosen or was only the first idea. The open questions section is where the author writes what they do not know yet, instead of hiding it.

Design doc Summary and ask Goals, non-goals Requirements Numbers API and data Architecture Deep dives Failure modes Alternatives Rollout and cost Open questions Everyone reads these first Engineers check the how decide ADR per decision assign Actions owner + date
Design doc anatomy. The top four sections tell everyone why, what and how much. The middle four are where engineers check the mechanism. The bottom of the doc produces outputs: each decision among the alternatives becomes an ADR, and each open question becomes an action with an owner.

How to read an engineer's diagram

Architecture diagrams look complete because boxes are neat. The risk usually hides in the arrows and in what is not drawn. Use the same routine on every diagram:

  1. Find the user and follow one request. Say it out loud: "The cashier scans, the app calls the API, the API reads Postgres, the answer comes back." If nobody can narrate it, the diagram is decoration.
  2. Ask four things about every arrow. What moves along it? How often? Does the caller wait for the answer () or not? What happens when it fails? An unlabelled arrow hides most of the risk in a design.
  3. Ask three things about every box. How many copies run? What does it keep in memory or on disk? Which team owns it at 3 am? A box that holds no state is cheap to copy (Scaling up vs scaling out). A box that holds state needs a backup and a recovery plan (Backups).
  4. Find the source of truth. For each kind of data, one place is the . If both Redis and Postgres hold stock numbers, which one wins when they disagree? (Caching, CAP and consistency)
  5. Cover each box with your finger. What does the user see now? Slower pages, an error, a stuck spinner, or wrong data? Wrong data is the worst answer, because nobody notices it.
  6. Look for what is missing. Authentication, rate limits, monitoring, backups, the dead-letter queue, and the admin screen someone will need on day two.

Quick check

You cover the Redis cache box with your finger and ask what the user sees. Which answer should worry you most?

Store app 1 API 2 SQL Postgres 3 add job Queue take job Worker HTTPS call SMS gateway 4 1 What moves? How often? 2 How many copies run? 3 Who else writes here? 4 What if it is down?
Reading a diagram. Four questions attach to four places: the unlabelled arrow (what moves, how often, sync or async?), the API (how many copies, any local state?), the database (who else writes here, and what is the source of truth?) and the outside service (what does the user see when it is down?).
Think first: the design has six boxes, no failure section, and you have ten minutes. Where do you start?

Start with the boxes that the user's main action cannot work without. Cover them one at a time, in the order a request passes through them, and ask what the user sees. Then do the outside services, such as a payment API or an SMS gateway, because the team does not control them and they fail in slow, strange ways.

For each answer, write one line in a table: box, what fails, what the user sees, what we do about it. Ten minutes is enough for six rows. The empty cells are your action items.

A question bank by area

You do not need to ask all of these. Before the meeting, pick the two areas where this design is most likely to hurt, and bring three questions from each. The lesson links let you refresh the idea behind each question.

AreaAskLessons
RequirementsWhich user action is this for? Which NFR is the hardest to meet? What is out of scope?System design, p99 and SLOs
NumbersWhat is the peak QPS on the busiest day, and how did you get it? How big is it in three years?Estimation
DataWhich unique key blocks duplicates? Which index serves each main query? How do we change this schema without downtime?Data modeling, Indexes, Safe migrations
ConsistencyHow old can this data be before it causes a wrong decision? What happens if two people change it at once?Transactions, CAP and consistency
ScaleWhat breaks first at twice the load? Is the API stateless? What do we cache, and how do we clear it?Replication, Scale up vs out, Caching
FailureWhat does the user see when this box is down? Does every call have a timeout? Where do failed jobs go?Queues and jobs, Timeouts and retries
EventsWhat happens if this message is processed twice? Is the event written in the same transaction as the data?Queues and jobs, Outbox and sagas
SecurityWho can call this, and which rows can they see? Where do the secrets live? What personal data do we store?Security
OperationsHow do we know it is broken before users tell us? Who gets the alert? How do we roll back?Backups, Observability, Shipping
CostWhat does it cost per month today and at three times the load? How many hours a month will it take to run?System design, Data stores
Stores and mobileWhat happens with no internet? Which old app versions are still in use, and do they keep working?Offline sync, Shipping

Disagreeing well

Good engineers disagree, and that is the point of a review. The problem is a disagreement with no way to end it. Five habits help.

Turn positions into conditions. Ask each side: "What would make you change your mind?" Good answers are specific: a number ("if we pass about 200 jobs a minute"), a feature ("if we need delayed jobs"), or a test result. Once both sides have named their conditions, the argument becomes a question about facts. If nobody can name a condition, the choice is a matter of taste. Let the decider pick, and move on.

Ask for the cheapest test. Many debates can be settled in two days with a , which is cheaper than another hour in a meeting room.

Know which doors lock behind you. Amazon describes decisions as one-way and two-way doors. A is hard to reverse: a public API, a core table, a new data store. A two-way door is easy to reverse: a cache TTL, a library inside one module. Spend review time on one-way doors and decide two-way doors quickly.

Disagree, then commit. When the decider decides, everyone builds it fully, including the people who argued against it. Their view goes into the ADR, with the condition that would reopen the decision. People commit more easily when they know their concern is written down and has a trigger.

Watch for bikeshedding. is a long debate on an easy topic, such as a table name or a folder layout, because everyone can have an opinion on it. When you hear it, put it in the parking lot. Keep comments about the design, never the person: "this loses the job if the worker crashes", not "you forgot about crashes".

Quick check

Which of these decisions is a one-way door that deserves slow, careful review time?

Recording the decision: the ADR

An (architecture decision record) is a one-page note about one decision. The format most teams use comes from a 2011 blog post by Michael Nygard: a title, a status, the context, the decision and its consequences. Many teams add the options considered and the conditions for revisiting it.

Keep ADRs in the code repository, numbered, next to the code they describe, for example docs/adr/0007-report-job-queue.md. Do not edit an accepted ADR when you change your mind. Write a new one that says "Supersedes ADR-0007", and mark the old one as superseded. A year later, a new engineer can read why the system looks the way it does, and the team stops having the same debate every six months.

Build it

We will make a design doc template, an invite with a clear ask, an ADR template and a filled ADR, and a one-page review checklist. The Practice section then has you fill a failure table and write an ADR of your own.

  1. Save the design doc template (top half)

    Keep it in your team's docs or in the repository as docs/design/TEMPLATE.md. The comments say what a good answer looks like. Delete them as you fill the doc.

    Markdown
    # Design: <feature or system>
    Author: <name>  Reviewers: <names>  Decider: <name>
    Status: draft | in review | accepted   Review date: <yyyy-mm-dd>
    
    ## 1. Summary and ask
    <!-- 3-5 sentences: what we build, why now, and the decision we need. -->
    
    ## 2. Context
    <!-- What exists today and what hurts. Link the requirements sheet. -->
    
    ## 3. Goals and non-goals
    - Goal:
    - Non-goal:   <!-- things a reader might expect that we will NOT do -->
    
    ## 4. Requirements
    - FR1: <role> can <action>
    - NFR: <quality> <number> measured at <where>
    
    ## 5. Numbers
    <!-- Show the arithmetic: users x actions / 86,400 x peak factor. -->
    
    ## 6. API
    <!-- Method, path, request, response, errors, idempotency. -->
    
    ## 7. Data model
    <!-- Tables, keys, unique constraints, indexes, size in 1 year. -->
    
  2. Save the bottom half

    The failure table and the alternatives are the two sections reviewers will check first, so the template makes them hard to skip.

    Markdown
    ## 8. Architecture
    <!-- One diagram. Label every arrow: what moves, how often, sync/async. -->
    
    ## 9. Deep dives
    <!-- The 1-2 hardest parts, in detail. -->
    
    ## 10. Failure modes
    | Part fails       | What the user sees | What we do         |
    |------------------|--------------------|--------------------|
    |                  |                    |                    |
    
    ## 11. Alternatives considered
    <!-- At least two real options, with why we did not pick them. -->
    
    ## 12. Security and privacy
    <!-- Who can call what, which rows they see, personal data, secrets. -->
    
    ## 13. Rollout, monitoring and cost
    - Migration steps (expand / migrate / contract):
    - Release: flag, pilot stores, rollback:
    - Dashboards and alerts (SLO):
    - Cost per month today / at 3x:
    
    ## 14. Open questions
    - [ ] <question> (owner, due date)
    
  3. Write the invite with the ask

    One short message. It names the decision, the roles, and what to read. People who read this invite arrive knowing why they are there.

    Output
    Subject: Design review: report jobs (Thu 3:00-4:00 pm)
    
    Doc: docs/design/report-jobs.md  (please comment by Wed 5 pm)
    
    Decide:  Postgres job table or BullMQ for report generation.
    Review:  what happens when a worker crashes mid-report;
             load on the main database on the 1st of the month.
    
    Decider: tech lead     Timekeeper + notes: PM
    Out of scope: report layout and Excel formatting.
    
  4. Save the ADR template

    Short on purpose. If an ADR needs more than a page, the extra belongs in the design doc, linked from the ADR.

    Markdown
    # ADR-<number>: <decision in a few words>
    Status: proposed | accepted | superseded by ADR-<n>
    Date: <yyyy-mm-dd>   Decider: <name>   Design doc: <link>
    
    ## Context
    <!-- The forces: numbers, constraints, what hurts today. -->
    
    ## Options considered
    1.
    2.
    
    ## Decision
    <!-- What we chose, in one or two sentences. -->
    
    ## Consequences
    <!-- Good, and the costs we accept. -->
    
    ## Revisit when
    <!-- Concrete conditions that reopen this decision. -->
    
  5. Fill in the ADR from the review

    This is the ADR from the Mangrove Market callout above. Notice that every claim has a number, the costs are written as clearly as the benefits, and the dissent has a trigger instead of being forgotten.

    Markdown
    # ADR-0007: Use a Postgres job table for report generation
    Status: accepted   Date: 2026-10-08   Decider: tech lead
    
    ## Context
    - Managers generate sales reports in Back office. Today the
      report is built in the HTTP request; big regions take 40-90 s, the
      load balancer cuts at 60 s, and users press Generate again.
    - About 300 reports/day; peak about 120 in the first hour of the 1st.
      Each takes 20 s to 4 min and reads the reporting replica.
    - We run Postgres and NestJS. Our only Redis is a cache with
      eviction on (allkeys-lru), so it cannot hold jobs safely.
    
    ## Options considered
    1. Postgres `job` table claimed with FOR UPDATE SKIP LOCKED.
    2. BullMQ on a new Redis with AOF and noeviction.
    3. Keep it in the request with a 5 min timeout. Rejected: holds
       connections, and retries create duplicate reports.
    
    ## Decision
    Option 1. Two worker processes, at most 4 reports at once, 3 attempts
    with backoff, dedupe_key = report type + period + zone.
    
    ## Consequences
    + No new system to run, back up and monitor.
    + Job row is inserted in the same transaction as the report row.
    - We write retries and the stale-job reaper ourselves (about 150 lines).
    - Idle polling adds about 2 tiny queries per second on the primary.
    - No built-in UI; we add a "jobs by status" panel to Grafana.
    
    ## Revisit when
    - More than about 5,000 jobs/day, or we need delayed or rate-limited
      jobs (e.g. SMS), or the claim query enters the top 10 of
      pg_stat_statements. BullMQ is then the default candidate.
    - Dissent: one backend engineer preferred BullMQ for its UI; agreed
      to the triggers above.
    
  6. Print the one-page review checklist

    Bring it to every review. Tick only what you checked in the doc or heard in the room, not what someone promised to think about.

    Markdown
    # Design review checklist
    
    ## Before
    - [ ] Doc shared 1-2 working days ahead; comments answered
    - [ ] Invite states the ask; decider, timekeeper, note-taker named
    - [ ] Deep-dive topics chosen (at most 2)
    
    ## Requirements and numbers
    - [ ] Every NFR has a number and a place it is measured
    - [ ] Peak QPS and size in 1 and 3 years, with the arithmetic
    - [ ] Non-goals written down
    
    ## API and data
    - [ ] Unique keys stop duplicates; POSTs that create things are idempotent
    - [ ] An index for each main query; schema change works with old + new code
    
    ## Architecture and failure
    - [ ] Every arrow labelled: what, how often, sync or async
    - [ ] Source of truth named for each kind of data
    - [ ] Every box covered: what the user sees, what we do
    - [ ] Timeouts, retries with backoff, dead-letter queue, alerts
    
    ## Security, ops and cost
    - [ ] Access scoped by user and site; secrets outside the code
    - [ ] Dashboards and alerts tied to an SLO; on-call owner
    - [ ] Rollout with a flag and a rollback; backups covered
    - [ ] Monthly cost today and at 3x
    
    ## After (last 5 minutes)
    - [ ] Decisions read back; an ADR owner for each
    - [ ] Actions and parking-lot items have an owner and a date
    

Bring it to your team

These questions run the meeting itself. Use them alongside the question bank above.

  • "What decision do we need to leave this room with today?"
  • "If we do not agree, who makes the final call?"
  • "Can you walk me through one request, from the phone to the database and back?"
  • "Which part of this design are you least sure about? Let's spend the deep dive there."
  • "What would make you change your mind?"
  • "Who writes the ADR, and by when?"

Red flags

  • The doc arrives an hour before the meeting, or is a slide deck with no numbers.
  • Only one option is presented, with no alternatives considered.
  • Half the hour goes to names, folders or formatting.
  • The meeting ends with "let's think about it" and no owner.
  • The same debate returns a month later because nothing was written down.
  • "We will add monitoring later."

Practice

Fill the failure table for the sample diagram

Go back to the third diagram. Here is what it does: when a click-and-collect order is ready, store staff tap "Ready" in the Store app. The API saves the new status in Postgres and adds a "send ready SMS" job to the queue. A worker takes the job and calls the SMS gateway over HTTPS. Cover each of the six boxes in turn and write one row per box: what fails, what the store staff and the customer see, and what the design should do. Add one more row for the trickiest case you can think of. Give yourself 15 minutes.

  • Every box in the diagram has a row: Store app, API, Postgres, queue, worker and SMS gateway
  • Each row says what people actually see, not only what breaks inside
  • The worker row deals with the risk of sending the same SMS twice
  • The SMS gateway row has a timeout, retries with backoff, and a place for jobs that fail every attempt
  • At least one row names the alert that tells the team before customers do
  • Any cell you could not fill is written down as an open question with an owner
Show a model answer
Markdown
| Part fails            | What staff and customer see       | What we do                                   |
|-----------------------|-----------------------------------|----------------------------------------------|
| Store app offline     | Staff see "waiting to send"       | Keep the tap locally; retry with the same    |
|                       |                                   | request id, so a retry cannot repeat it      |
| API down              | Staff see "not saved, retrying"   | Several copies behind the load balancer;     |
|                       |                                   | alert on the 5xx rate                        |
| Postgres primary down | Status not saved, no SMS          | Fail over to the replica; API answers 503    |
| Queue down            | Status saved, SMS late            | Outbox row in the same transaction as the    |
|                       |                                   | status; a relay adds the job later           |
| Worker crashes        | SMS a little late                 | Job not acked, so it runs again; the job id  |
|                       |                                   | is a dedupe key, so no second SMS            |
| SMS gateway down      | Customer's SMS is late; the order | 5 s timeout, 3 retries with backoff and      |
|                       | page still says "Ready"           | jitter, then dead-letter queue and an alert  |
| Gateway sent the SMS, | Risk: the customer gets two SMS   | Pass the job id as the gateway's reference   |
| but its reply is lost |                                   | if it supports one; if not, accept a rare    |
|                       |                                   | duplicate and say so in the doc (owner: PM)  |

The last row is the one most teams miss. It is the same "the work happened but the reply was lost" problem that the POS sales case study solves for uploads.

Write the ADR from a review's notes

Imran took these notes in a review of delivery photos for the Rider app. Turn them into ADR-0012, using the template from the Build it section. Keep it to one page. About 15 minutes.

Output
Review: delivery photos for the Rider app, 2026-10-14. Decider: Nadia (tech lead).
Numbers: about 60,000 deliveries a day, one photo each, about 200 KB after compression.
Option A: store each photo in Postgres, in a bytea column.
Option B: the Rider app uploads straight to object storage with a presigned URL;
          Postgres keeps only the object key.
Option C: keep photos on the phone and upload them overnight on Wi-Fi.
Discussion: C is too late when a customer disputes a delivery the same evening.
            A adds a lot of data to the main database, its backups and its replicas.
Decision: B. Keep photos 180 days, then delete them with a lifecycle rule.
Dissent: Ken (engineering manager) wanted A for "one system to back up";
         agreed, as long as the bucket has versioning turned on.
  • The context shows the numbers with their arithmetic, such as the gigabytes per day
  • At least two options, each with the reason it was or was not chosen
  • The decision fits in one or two sentences and includes the 180-day rule
  • The consequences list what the team gives up, not only the benefits
  • "Revisit when" has concrete conditions, never "if needed"
  • The dissent is recorded with the condition that was agreed
Show a model answer
Markdown
# ADR-0012: Store delivery photos in object storage
Status: accepted   Date: 2026-10-14   Decider: tech lead

## Context
- The Rider app takes one proof-of-delivery photo per order.
- About 60,000 deliveries/day x ~200 KB = ~12 GB/day, ~4.4 TB/year.
- Disputes come in the same evening, so photos must arrive within minutes.

## Options considered
1. bytea column in Postgres. Rejected: +12 GB/day in the main
   database, its backups and its replicas.
2. Presigned upload to object storage; Postgres stores the key.
3. Upload overnight on Wi-Fi. Rejected: too late for same-day disputes.

## Decision
Option 2. Photos are kept 180 days, then deleted by a lifecycle rule.

## Consequences
+ The main database stays small; photo bytes skip our API servers.
+ About 2.2 TB stored at steady state (12 GB x 180 days).
- One more system to secure: private bucket, short-lived URLs.
- A failed upload leaves a delivery with no photo; a nightly job
  lists them for the store.

## Revisit when
- Photos must be kept longer than 180 days, or storage cost passes
  the monthly budget agreed with finance.
- Dissent: the engineering manager preferred Postgres for a single
  backup story; agreed once bucket versioning is on.

Check yourself

It is minute 35 of a 60-minute review. The team is still debating whether the table should be called report_job or job, and nobody has discussed what happens when a worker crashes. What do you do?

Two senior engineers have argued for ten minutes: one wants Kafka for an event feed, the other wants BullMQ. What is the most useful next question?

What belongs in an ADR?

Flashcards

Open my review

Key takeaways

  • A review exists to find costly mistakes early and to leave with written decisions and owners.
  • Share the doc one or two days ahead with a clear ask, and name a decider, a timekeeper and a note-taker.
  • Follow the thinking loop with a clock. Protect the deep dives and the failure modes; they find most of the risk.
  • Read any diagram by following one request, questioning every arrow, and covering every box.
  • Turn disagreement into conditions with "what would change your mind?", then decide, commit, and record it in an ADR.

Sources

Episode transcriptThe walk before opening day · about 14 minutes · tap any line to play from there
  1. NadiaImran, think of the last design meeting that went badly. Not technically. As a meeting.
  2. ImranEasy. An hour on what to call a table, nobody talked about crashes, and it ended with great discussion, everyone. A month later we had the same argument again.
  3. NadiaThat's the meeting this lesson fixes. A design review is where a team finds the expensive mistakes while they're still cheap to fix. And as PM, you can lead it.
  4. NadiaThe picture is a new grocery store, a week before it opens. The area manager walks through it with the contractor, the IT person and the new store manager. They don't rebuild anything. They walk the customer's path from the door to the counter.
  5. ImranWith a checklist. Where does the queue go on the eve of a big festival? What happens to the tills when the power goes out? Where does the warehouse truck unload, and does it block the entrance?
  6. NadiaEach question takes a minute or two, and each finding goes on a list with a name and a date. The walk takes an hour. Moving a checkout counter after opening day takes a month.
  7. ImranSo a design review is that walk, done on a document instead of a shop floor.
  8. NadiaYes. Follow the user's path through the design, ask what happens when each part fails, and leave with decisions and owners in writing.
  9. ImranWhat exactly is it for, though? Some of my engineers treat it like an exam.
  10. NadiaThree jobs. Find the risky parts before code exists. Make the important decisions visible, so they're made on purpose. And give everyone the same picture of the system. It isn't a status meeting, a demo, a vote, or an exam for the author.
  11. NadiaAnd name the roles in the invite. The author writes the design doc and presents it. Two to five reviewers read it beforehand, including someone who'll run it in production. One decider, usually the tech lead, makes the call if the room can't agree.
  12. ImranAnd the PM is the timekeeper and note-taker.
  13. NadiaOften. You own the problem, the requirements, the numbers and the priorities. On requirements, speak first. On technical choices, ask questions and speak last, so engineers say what they really think before they hear what you prefer.
  14. ImranSo I don't need to be the best engineer in the room.
  15. NadiaNo. Your strongest tool is a precise question at the right moment. And not every ticket needs a review. Hold one when a change is hard to undo, touches money or stock, crosses teams, or takes more than about two weeks.
  16. ImranWhat happens before the meeting?
  17. NadiaMost of the value. The author shares the doc one or two working days ahead, reviewers comment in the doc, and the author answers the easy comments in writing. The meeting is for the hard ones.
  18. NadiaAnd the invite states the ask. Decide: Postgres job table or BullMQ for report jobs. Review: what happens when the report worker crashes. An invite that says discuss report design produces a discussion, and discussions don't end.
  19. ImranWhat if people come without reading?
  20. NadiaStart with eight minutes of silent reading. Amazon is one company that starts meetings with a written memo like that. It feels strange the first time, but a written doc can't hide a missing number behind a nice picture.
  21. ImranNow the hour itself.
  22. NadiaThe first diagram is a sixty-minute agenda, as a list of steps with minutes beside each one. It's the thinking loop from the first lesson of the track, What system design really is, with a clock. Requirements five minutes, numbers five, API and data ten, big picture five.
  23. NadiaThen the biggest block, deep dives, fifteen minutes. Failure modes ten. Trade-offs five, rollout and operations five. And after the meeting, an ADR with owners and dates.
  24. ImranSo a quarter of the hour goes to deep dives.
  25. NadiaBecause that's where designs usually fail. And each step has a question. In requirements: which of these is the hardest to meet? That answer often picks the deep-dive topic.
  26. NadiaIn numbers: can you show me the arithmetic? A number without its arithmetic can't be checked. In API and data: which unique key stops a retry from creating a duplicate?
  27. ImranAnd the deep dives are the hard parts.
  28. NadiaOne or two, chosen by the decider before the meeting. For stock, usually two people buy the last unit. For sync, the upload succeeded but the reply was lost.
  29. ImranAnd in a forty-five minute slot, I'd cut the deep dives to make room for the presentation.
  30. NadiaThat's exactly the cut the lesson forbids. Shrink every step a little and keep the shape. Never cut the deep dives and failure modes to make room for a longer presentation.
  31. NadiaTwo tools keep the clock honest. A parking lot, a visible list for off-track topics, each with an owner. And one sentence the timekeeper can always say: we have two minutes left on this. What fact would settle it, and who can get it by Thursday?
  32. ImranBecause most stuck debates are missing a fact nobody in the room has.
  33. NadiaRight. And five minutes before the end, stop and read the decisions and actions back. Otherwise the review has produced nothing anyone can find next week.
  34. ImranWhat does a good design doc look like?
  35. NadiaThree to six pages. The second diagram shows its anatomy as a column of sections. The top four, summary and ask, goals and non-goals, requirements, numbers, are what everyone reads. The middle four are where engineers check how it works.
  36. NadiaAt the bottom, alternatives and open questions. Each decision among the alternatives becomes an ADR, and each open question becomes an action with an owner.
  37. ImranWhich section gets skipped most?
  38. NadiaAlternatives. And it's the most useful. If a doc shows only one option, nobody can tell whether it was chosen or was only the first idea.
  39. ImranEngineers will show me architecture diagrams. They always look complete.
  40. NadiaBecause the boxes are neat. The risk hides in the arrows, and in what isn't drawn. So, a routine. First, find the user and follow one request, out loud. If nobody can narrate it, the diagram is decoration.
  41. NadiaThen four things about every arrow. What moves along it? How often? Does the caller wait for the answer? What happens when it fails?
  42. NadiaThe third diagram puts numbered questions on a sample design. A Store app, an API, Postgres, a queue, a worker, an SMS gateway. Question one sits on an unlabelled arrow: what moves, how often? Two on the API: how many copies run?
  43. ImranThree on Postgres: who else writes here? And four on the SMS gateway: what if it's down?
  44. NadiaExactly. And find the source of truth. If Redis and Postgres both hold stock numbers, which one wins when they disagree? Then cover each box with your finger. What does the user see now?
  45. ImranSlower pages, an error, a stuck spinner.
  46. NadiaOr wrong data, which is the worst answer, because nobody notices it. And look for what's missing: login, rate limits, monitoring, backups, the dead-letter queue, the admin screen someone needs on day two.
  47. ImranThe lesson also has a question bank.
  48. NadiaBy area, from requirements to cost to stores and mobile. Don't ask everything. Before the meeting, pick the two areas where this design is most likely to hurt, and bring three questions from each.
  49. ImranNow the hard part. Two seniors arguing.
  50. NadiaDisagreement is the point of a review. The problem is a disagreement with no way to end. So turn positions into conditions. Ask each side, what would make you change your mind?
  51. ImranAnd a good answer is a number, like if we pass about two hundred jobs a minute.
  52. NadiaOr a feature, or a test result. Then the argument is about facts. If nobody can name a condition, it's taste: the decider picks, and you move on. Or ask for the cheapest test. A two-day spike is cheaper than another hour in a meeting room.
  53. NadiaThen, know which doors lock behind you. Amazon talks about one-way and two-way doors. A public API, a core table, a new data store are one-way. A cache expiry time is two-way. Spend the time on one-way doors.
  54. ImranAnd once the decider decides?
  55. NadiaDisagree, then commit. Everyone builds it fully, including the people who argued against it. Their view goes in the ADR, with the condition that would reopen it. And watch for bikeshedding, long debates on easy topics like names. Parking lot.
  56. ImranSo the ADR. Architecture decision record.
  57. NadiaA one-page note about one decision. The usual format comes from a twenty eleven blog post by Michael Nygard: title, status, context, decision, consequences. Many teams add the options and when to revisit.
  58. NadiaKeep them numbered in the code repository. And never edit an accepted one. Write a new one that supersedes it. A year later, a new engineer can read why the system looks the way it does.
  59. ImranLet me tell our own story from the lesson. A review for the monthly sales report in Back office. The first draft builds each report inside the HTTP request, from the main database.
  60. NadiaAnd in the numbers step, you asked: how many people press Generate at nine am on the first of the month? Tomás checked the logs. About forty area managers and about eighty store managers, all in the first hour. Roughly a hundred and twenty heavy reports.
  61. ImranAnd big reports take more than a minute, so the load balancer times out, people press Generate again, and the heavy queries pile up on the same database the stores' sales are written to.
  62. NadiaOne question changed the design. Reports move to background jobs reading a reporting replica. Then two engineers disagree, BullMQ or a Postgres table. Each names a condition, I make the call as decider, and you write ADR seven that afternoon.
  63. NadiaThe Build-it gives you the paperwork. A design doc template in two halves, with a three-column failure table and an alternatives section that's hard to skip.
  64. NadiaThen a short invite with the ask, an ADR template, and ADR seven filled in.
  65. ImranRemind everyone what ADR seven decided.
  66. NadiaA Postgres job table. About three hundred reports a day, peaking around a hundred and twenty in the first hour. Their only Redis evicts keys, so it can't hold jobs safely. They accept writing about a hundred and fifty lines of retry code themselves.
  67. NadiaAnd revisit when: more than about five thousand jobs a day, or a need for delayed jobs. The dissenting engineer agreed to those triggers. Last, a one-page checklist you bring to every review, ticking only what you actually checked.
  68. ImranAnd the practice section has two tasks of its own. Fill the failure table for that third diagram, and turn a review's notes about Rider app delivery photos into an ADR.
  69. ImranThis whole loop sounds a lot like a system design interview.
  70. NadiaIt is the same loop, squeezed into forty-five minutes, with the interviewer as the reviewer. Strong candidates run their own clock, show their arithmetic, and spend most of the time on the hard part and on what fails.
  71. ImranMy meeting questions, then. What decision do we need to leave this room with? If we don't agree, who makes the final call?
  72. NadiaGood. Can you walk me through one request, from the phone to the database and back?
  73. ImranWhich part are you least sure about, so we spend the deep dive there? And who writes the ADR, by when?
  74. NadiaA question to think about. It's minute thirty-five of sixty. The team is still debating whether the table is called report job or job, and nobody has discussed a worker crash. What do you do? Take a second.
  75. ImranI'd want to decide the name myself as PM, just to move them on.
  76. NadiaTempting, but that skips the decider and teaches the team the loudest person wins. Put the name in the parking lot with an owner, and move to failure modes. A table name is a two-way door.
  77. ImranMy takeaways. One: share the doc a day or two ahead, with a clear ask, a decider, a timekeeper and a note-taker. Two: follow the loop with a clock, and protect the deep dives and failure modes. Three: what would change your mind, then decide, commit and write the ADR.
  78. NadiaAnd for diagrams: follow one request, question every arrow, cover every box. Next time, we run a whole design review together, on something that looks like a weekend project: a link shortener.
Finished reading?Mark it complete to fill in its stop on your course line.

Use it at work

Architecture review

Today's design on the board with the questions a review asks as notes, and criteria for the targets you must keep.

Open in the System Design Studio
Next stopCase study: a URL shortener
Was this lesson helpful?
Questions and discussion

Loading the discussion…