Engineering Atlas › System Design Interviews

Drawing architecture diagrams that read well

13 min read · last reviewed 2026-10-17

Open in the interactive app: practice, quiz, mock interview →

In one minute

How it works

Time budget

In a 45-minute interview, the high-level diagram should exist by around minute 15 and be mostly complete by minute 20. Spend the first pass on structure, not polish. Boxes are cheap to add later; a layout that runs out of room is expensive to fix, so leave space on the right and bottom.

The skeleton first

Draw the minimum that satisfies the functional requirements: client, an entry point (load balancer or API gateway), one or two services, the primary datastore, and a cache or queue if the requirements obviously need one. Walk one write and one read through it before adding anything. This forces gaps to the surface early, such as "where does the feed get built?", while changes are still cheap.

Conventions that make diagrams readable

Narration

Talk as you draw, but in short sentences: "The client uploads to object storage through a pre-signed URL, then calls the post service with the object key." After the skeleton, do one complete pass of each path. When you go deep, zoom: draw a second, smaller diagram for the deep dive (for example a sequence diagram for a payment flow) rather than cramming detail into the overview.

What interviewers look for

Common mistakes

Down the stack

Layer 1The contract

A system diagram makes testable claims. Each box is a deployable unit with an owner and a failure domain. Each arrow is a dependency: if the target is down, the source is affected, synchronously (fails or slows now) or asynchronously (backlog grows). A stateful box claims a data ownership boundary: no other box writes its data directly. From those claims you can answer the questions interviewers ask: which component is a single point of failure, which calls are on the latency-critical path, and what a failure cascades into.

Layer 2The mechanism

Treat the diagram as a directed graph. The request path is every node reachable from the entry point. A single point of failure is a node with no redundancy whose removal disconnects the entry from some required data store, which is a cut vertex (articulation point) in graph terms, findable in linear time with a depth-first search (Wikipedia). A cycle of synchronous edges is a call loop: retries within a loop multiply load, and timeouts nested inside each other can exceed the caller's deadline. Retries multiply along any chain, not just loops: if three layers each retry three times, one user action can become 4 × 4 × 4 = 64 attempts on the database, which is why each arrow should carry a propagated deadline rather than its own timeout (SRE book, ch. 22). Fan-out edges multiply requests: one arrow into a service that calls 20 shards means 20 backend calls per request, and tail latency is set by the slowest; if each shard is slow 1 percent of the time, about 18 percent of requests wait on at least one slow shard. For deep dives, sequence diagrams show ordering and failure points that a box diagram cannot, such as "the response is lost after the charge succeeded". Edges also differ in strength: a strong dependency takes the flow down when it fails, while a weak one only removes a feature, so mark which is which (Azure Well-Architected). The C4 model formalises the zoom levels: context, containers, components and code, plus supplementary dynamic and deployment diagrams (C4 model). Interviews mostly live at the container level, and the AZ boundaries you draw are a small deployment diagram.

Layer 3The machine

Each arrow costs something physical, and annotating it shows depth. A synchronous call inside one AZ is about 0.2 to 0.5 ms of network round trip plus serialisation; a cross-AZ call adds about 1 ms, since AWS keeps a region's AZs within 100 km of each other (AWS), and is billed per GB in most clouds; a cross-region call adds tens to a hundred milliseconds. Behind each arrow are TCP connections held in pools: 200 app instances times a pool of 20 connections is 4,000 connections into one database primary. Postgres runs one backend process per connection (Postgres docs), so that many connections exhausts memory without a pooler such as PgBouncer, which needs about 2 kB per client connection and in transaction mode lends a server connection only for the length of a transaction (PgBouncer). A load balancer box is either L4 (forwarding TCP connections, very cheap per packet) or L7 (terminating TLS and parsing HTTP, costing CPU per request). A queue box is a disk-backed log: its throughput is bounded by sequential disk writes and replication, and its buffer gives you hours of absorption only if you size the disk for it.

Why it's built this way

Interviewers can hold only a few things in working memory while listening, so a consistent left-to-right layout with few boxes reduces their cognitive load. Failures propagate along dependencies, so arrows must show direction and synchrony. Detail is needed only where the risk is, so you zoom into a separate diagram for deep dives. And because the diagram is the evidence for your claims about scale and failure, the numbers and replica counts belong on it.

Diagram

flowchart LR
    C["Client"] -->|"1 POST /posts"| LB["Load balancer x2"]
    LB --> API["Post service x6"]
    API -->|"2 insert"| DB["Posts DB, sharded by user_id"]
    API -.->|"3 PostCreated"| Q["Kafka topic"]
    Q -.->|"4 fan-out"| FW["Feed workers"]
    FW --> FC["Feed cache (Redis)"]
    C -->|"5 GET /feed"| LB
    LB --> FS["Feed service x8"]
    FS -->|"6 read"| FC

Worked example

You are asked to design a URL shortener and have 10 minutes for the high-level design.

Minute 0 to 2: draw client, load balancer, "Shortener service", "URL store" and a cache, left to right. Label the write arrow POST /urls and the read arrow GET /{code} -> 301.

Minute 2 to 4: number the flows. Write path: 1 client to service, 2 service gets an ID from an ID allocator (draw a small box), 3 service writes code -> long_url to the store. Read path: 4 client to service, 5 cache lookup, 6 on miss read store and populate cache. Say each step aloud once.

Minute 4 to 6: add numbers from your estimate. "100 million new URLs a month is about 40 writes per second; reads at 100 to 1 are about 4,000 per second average, 20,000 at peak." Write them on the arrows. Mark the store "KV, partitioned by code, RF=3" and the cache "Redis, about 20 GB hot set".

Minute 6 to 8: mark failure domains. Draw a dashed boundary for each of two AZs and show two service instances and store replicas in each. Point at the ID allocator: "This is a single point of failure, so it hands out ID ranges of 1,000 to each service instance and runs as a three-node group."

Minute 8 to 10: add the async analytics path under the main flow: dashed arrow from service to a click-event topic, then to an aggregation job and an analytics store. You now have a diagram that answers most follow-ups by pointing.

In the wild

Trade-offs

OptionStrengthsWeaknessesChoose when
One overview diagramFast, keeps contextGets crowdedFirst 20 minutes
Overview plus zoomed deep diveDetail where it mattersTakes space and timeDeep dives on one flow
Sequence diagramShows ordering and failure timingPoor at structurePayments, consensus, retries
Box-and-arrow with numbersShows scale and bottlenecksNeeds estimates firstCapacity discussion
Drawing tool templatesNeat, reusable shapesFiddly under time pressureRemote interviews with practice

Pitfalls in production

These apply equally to design reviews at work:

Leadership lens

Check yourself

  1. Why draw async flows with a different line style from sync calls?

    Show answer

    They fail differently: a failed sync dependency fails or slows the caller immediately, while an async one builds a backlog, so readers need to tell them apart at a glance.

  2. When is a box with one replica not a single point of failure?

    Show answer

    When it is not needed on any path from the entry point to a required store, or when an alternative path bypasses it.

  3. Why are cycles of synchronous calls between services a red flag?

    Show answer

    They create long latency chains, retry amplification around the loop and potential deadlock under load, and they make independent deployment hard.

  4. What should you do when you want to show the details of a payment flow?

    Show answer

    Draw a separate sequence diagram for it, keeping the overview uncluttered, and refer back to the numbered step in the overview.

Sources and further study

Primary

Systems docs

Books

Other curricula

Watch

Free resources

Open in the interactive app: practice, quiz, mock interview →