Drawing the architecture diagram
How to draw a clear, interview-worthy architecture diagram: what components to include, how to label data flows, and how to layer complexity over three rounds.
TL;DR
- Most interview diagrams fail because they dump every component at once with unlabeled arrows. The interviewer can't tell what your system actually does.
- Draw in three rounds: core data path first, then read optimization (cache, replicas, CDN), then write optimization (queues, workers, sharding).
- Every arrow must have a label. "HTTP POST /tweets" is useful. A bare arrow is meaningless.
- Group components into visual layers (Internet, App Tier, Cache Tier, Data Tier) so the interviewer can scan your diagram in seconds.
- Narrate while you draw. Silent drawing wastes interview time and misses the chance to explain trade-offs in real time.
Why this framework matters
You're 15 minutes into a "Design Twitter" interview. Your whiteboard has 14 boxes, 22 arrows, and zero labels. The interviewer squints at it, tilts their head, and asks: "So... what talks to what here?"
You've drawn a diagram that makes sense to you because you just drew it, but communicates little to someone who lacks the context in your head. A technically sound architecture can still be difficult to evaluate when the diagram is a wall of crossed lines and unlabeled edges.
The fix is a layering strategy. You don't draw everything at once. You build the diagram in three deliberate rounds, narrating each one. By the end, your diagram is complex but readable, because the interviewer watched it evolve and understood each addition.
Think of it like explaining directions. You wouldn't dump a complete route with every turn, highway merge, and landmark at once. You'd say: "First, get on the highway heading north. Then take exit 15. Then turn left at the intersection." Each step builds on the last. Your architecture diagram should work the same way.
Unlabeled arrows hide the data flow
An unlabeled arrow does not tell the reader whether it is an HTTP request, a queue message, a database query, or a WebSocket push. Label each important edge with the operation, protocol, or data flow.
When to use this framework
Use this method when the architecture needs to be explained visually: system-design interviews, design reviews, incident reviews, and onboarding. It is especially useful when a system has separate read and write paths or asynchronous processing. For a small CRUD system, the first round may be enough; do not add layers that the requirements do not need.
The examples use illustrative workloads, cache hit rates, and latency targets. Replace them with the prompt's requirements or with measurements. The three rounds describe a communication sequence, not a universal deployment order.
Why most diagrams fail
Before fixing diagrams, name the failure modes that matter for the current design.
No labels on arrows. Your diagram has a line from "App Server" to "Database" but doesn't say whether it's a read, a write, a transaction, or a health check. The interviewer has to ask, which wastes time and makes the data flow harder to evaluate.
Everything at once. The candidate draws load balancers, app servers, two databases, a cache, a message queue, three workers, a CDN, and a monitoring service in the first two minutes. There's no story, no progression, and no clear indication of what's core versus what's optimization.
No visual grouping. Components are scattered randomly. The database is next to the CDN. The cache is below the client. The interviewer can't see which components form a layer or which path data takes through the system.
Missing components that matter. The candidate draws app servers and a database but forgets the load balancer. Or draws a cache but never shows a cache-miss path. Or has a queue but no workers consuming from it. Incomplete paths leave holes the interviewer will probe, and they will.
For your interview: the bar is not a beautiful diagram. The bar is a diagram where someone who has never seen your design can trace the read path and write path in under 10 seconds.
Step-by-step method: three-round layering
Here's the core technique. You draw your architecture in three rounds, each adding a specific type of complexity. This gives the interviewer a clear narrative arc and proves you know when to add each component.
Round 1: The Core Data Path
This is the happy path with zero optimization. Client sends a request, it reaches your application, your application reads from or writes to a database. That's it.
The goal of Round 1 is to establish the basic functional contract. What does the system do? What's the write path? What's the read path? You're not thinking about scale yet. You're thinking about correctness.
As a rule of thumb, keep Round 1 to about five boxes. The usual starting set is the client, load balancer, application server(s), and primary database; omit the load balancer if the availability and deployment requirements do not need one.
Say this out loud while drawing: "The client sends POST /tweets to create a tweet and GET /timeline to read their feed. The load balancer distributes requests to stateless app servers. Each app server reads from and writes to a single PostgreSQL primary. This handles the basic functional requirement but obviously won't scale."
That last sentence is key. You're signaling that Round 2 is coming.
Round 2: Read Optimization
Now identify the read bottleneck and address it. In a read-heavy system, reads may substantially outnumber writes. If the database cannot meet the read volume or latency target, evaluate caching and read replicas; neither is automatic.
The components you add in Round 2: a cache layer (Redis or Memcached), read replicas for the database, and potentially a CDN for static content.
Narrate the addition: "Reads dominate our traffic, so I'm adding a Redis cache in front of the database. For timeline reads, the app server checks Redis first. On a cache miss, it falls back to a read replica. Writes still go to the primary, and replicas receive updates via async replication. I'm also putting static content behind a CDN to offload image serving entirely."
State the expected cache hit rate as an illustrative assumption when you add caching. "With a 95% cache hit rate on timeline reads, the database sees about 5% of those reads" is more useful than simply saying "we add a cache." Validate the hit rate and the cache-miss failure path.
Round 3: Write Optimization and Async Processing
Now you address the write path. For a system like Twitter, the bottleneck isn't writing the tweet itself (that's one INSERT). The bottleneck is fan-out: delivering that tweet to every follower's timeline.
The components you add in Round 3: a message queue (Kafka, SQS), background workers, and potentially write sharding.
The narration: "When a user tweets, the app server writes the tweet to the primary DB and publishes a fan-out event to Kafka. The API acknowledges according to the queue's chosen durability policy; if fan-out is not complete yet, 202 Accepted may describe that contract better than 200 OK. Fan-out workers then read the event, look up the author's followers, and write the tweet to each follower's timeline cache in Redis. This makes the fan-out work asynchronous, so a user with an illustrative 100K followers does not block the API response."
Interview tip: name the boundary between sync and async
When you introduce a message queue, say where the synchronous boundary ends. "The client gets an acknowledgment after the queue accepts the event according to its durability policy. Everything after that is asynchronous." This makes the latency and delivery contract explicit.
Labeling Rules That Actually Matter
Every arrow in your diagram needs a label. But not all labels are equally useful. Here's what makes a good label versus a bad one.
Good labels describe the operation or data flowing across the edge:
POST /tweets(HTTP verb + path)INSERT tweet(database operation)Publish fan-out event(message queue operation)Cache read/Cache miss(cache operation with outcome)Async replication(replication type)
Bad labels are vague or redundant:
request(what kind of request?)data(what data?)sends to(the arrow already shows direction)connects(meaningless)
A useful rule is: if someone covers the boxes at each end of an arrow, can they still understand what is happening from the label alone? If not, the label needs work.
For your interview: you don't need to label every arrow with full HTTP path details. At minimum, label with the operation type (read, write, publish, consume, replicate). Upgrade to HTTP verb + path when the specific endpoint matters for your design discussion.
Visual Grouping with Subgraph Layers
The most readable diagrams group related components into named layers. This isn't just aesthetic preference. It communicates architectural thinking.
Standard layers for most web applications:
| Layer | Contains | Purpose |
|---|---|---|
| 🌐 Internet | Clients, CDN | Traffic sources, edge caching |
| ⚙️ App Tier | Load balancer, app servers | Stateless request handling |
| ⚡ Cache Tier | Redis, Memcached | Hot data, session storage |
| 📨 Async Tier | Kafka, workers | Background processing |
| 🗄️ Data Tier | Primary DB, replicas | Persistent storage |
When you group components this way, the interviewer immediately sees: requests flow top to bottom, each tier can scale independently, and the boundary between synchronous and asynchronous processing is visible.
Visual layers often reduce clarifying questions because the diagram makes boundaries and direction easier to scan.
Not every system needs all five layers. A simple CRUD application might only need Internet, App Tier, and Data Tier. That's fine. The point is not to have all layers, but to group whatever components you have into coherent tiers. Resist the temptation to add a Cache Tier just because the template has one.
The other benefit of layers: they make scaling discussions easier. "We'll horizontally scale the App Tier" is clearer when the App Tier is visually distinct. "We'll add replicas to the Data Tier" makes sense when the Data Tier is its own group. Layers turn scaling from an abstract discussion into a visual one.
Tracing Read and Write Paths Separately
Here's a technique that separates strong candidates from average ones: explicitly call out the read path and the write path as separate flows through your diagram.
Most systems have dramatically different read and write characteristics. Twitter's write path (create a tweet) goes through the app server, Kafka, and fan-out workers. The read path (load timeline) goes through the app server, Redis cache, and maybe a read replica on cache miss.
When you narrate, trace each path separately:
Write path (tweet creation):
"Client sends POST /tweets to the app server. The server validates, writes to the primary DB, and publishes to Kafka. The client receives the response defined by the contract. Async workers fan out to followers' timeline caches."
Read path (timeline load):
"Client sends GET /timeline. The app server checks Redis. On a hit—using an illustrative 95% hit-rate assumption—it returns immediately. On a miss, it queries the read replica, populates the cache, and returns."
This separated narration proves you understand that read-heavy systems need different optimization strategies than write-heavy systems. It's one of the clearest signals of architectural maturity.
Narrating While You Draw
Never draw in silence. The diagram is only half the deliverable. The narration is the other half.
Here's why: when you draw silently, the interviewer watches a diagram appear piece by piece with no context. They don't know if the next box is a database or a cache until you label it. They're trying to reverse-engineer your thought process from the drawing order alone.
When you narrate, you control the story. The interviewer understands each component as you add it, hears your reasoning, and can ask targeted follow-ups. This makes the whole conversation more productive and collaborative.
Use "I'm adding X because Y" sentences while drawing.
- "I'm adding a load balancer here because our app servers are stateless and we want horizontal scalability."
- "I'm putting Redis in front of the database because timeline reads are an illustrative 100:1 relative to writes, and the latency target favors a low-latency cache path."
- "I'm introducing Kafka here because fan-out to 100K followers is too slow to do synchronously. The client shouldn't wait for that."
Each sentence has the component (what) and the justification (why). That's the pattern.
If you can only remember one rule about narration, make it that one: what you're adding and why you're adding it. Everything else is refinement.
Interview tip: pause after Round 1
After drawing the core data path, stop and ask: "Does this capture the core flow? Should I focus on scaling the read path or the write path first?" This shows you're collaborative and gives the interviewer a chance to steer the discussion toward what they care about.
Common diagram mistakes
Spaghetti lines. Arrows cross in every direction, making the data flow impossible to trace. Fix: organize components in layers so data flows primarily top-to-bottom or left-to-right. Avoid crossing arrows by rearranging component positions within their layer.
The magic app server. A single "App Server" box that apparently handles routing, authentication, business logic, caching, and database access. Fix: if you're discussing a specific subsystem (like fan-out), break the app server into its relevant subcomponents. Otherwise, label what the app server does at each arrow.
One giant database. A single "DB" box that stores users, tweets, timelines, social graphs, and analytics. Fix: label what's in the database (at minimum, name the key tables), or split into separate stores when they have different access patterns.
Unidirectional arrows only. Every arrow goes from client to server to database. No responses shown. Fix: you don't need to show every response arrow, but for async flows where the response path is different from the request path, make the return path explicit.
Over-precision too early. Drawing internal subsystems of your cache or detailed Kafka partition assignments before you've established the overall flow. Fix: get the high-level architecture right first. Zoom into subsystems only when asked, or when you're specifically discussing a deep-dive component.
No failure paths. The diagram shows only the happy path with no indication of what happens when a component fails. Fix: be ready to add fallback arrows (cache miss path, circuit breaker, retry path) when asked "what if X goes down?"
Identical boxes with no differentiation. Three "Service" boxes that all look the same and connect to the same database. If your services are truly different (User Service, Tweet Service, Timeline Service), label them differently and show how they handle distinct data flows. If they're identical stateless instances behind a load balancer, say so explicitly.
The 10-second scan test
After finishing your diagram, step back and ask: "Can someone who didn't draw this trace the read path in 10 seconds?" If arrows are crossing, labels are missing, or there's no clear top-to-bottom flow, simplify before adding more complexity.
Trade-offs, limitations, and failure modes
Progressive layering keeps the explanation readable, but it can hide important interactions if the rounds are treated as isolated architectures. A cache changes the failure path, replicas introduce lag, and a queue changes acknowledgment, delivery, duplication, and recovery semantics. Each new layer should therefore update the affected arrows and the narration, not only add a box.
The diagram is also an abstraction. It should show the components and data flows needed for the decision at hand, while leaving implementation details for a deep dive. At minimum, be ready to explain cache misses, dependency timeouts, queue backlog or duplicate delivery, database failover, and what the client observes during each failure. Use distinct arrows for synchronous and asynchronous work and label any degraded or fallback path.
Interview application
30-second answer
"I draw the diagram in three rounds. First I show the core read and write path with the smallest set of components. Then I add the optimization that addresses the measured bottleneck—often cache or replica capacity for reads—and finally asynchronous workers, queues, or write distribution when the write path requires them. I label each important edge, group components into layers, narrate the reason for every addition, and call out the failure path."
5-minute explanation
"I start with the client, the request-handling tier, and the data store, then trace one read and one write. I keep the first round small so the functional contract is visible. In the second round I add only the read-side components justified by the latency or read-volume assumption, such as a cache, replica, or CDN, and I draw the cache-miss and replication paths.
"In the third round I address write amplification or background work with a queue and workers, making the synchronous acknowledgment boundary explicit. Throughout, every arrow names the operation, data, and sync or async behavior. I group components into coherent layers, pause to check direction, and finish by tracing the two paths again and explaining what happens when a cache, queue, database, or downstream dependency fails."
Common interviewer prompts
"Walk me through your diagram." The interviewer wants you to trace the read and write paths separately. They want operation names on arrows, not vague "sends data" labels. Practice this narration out loud.
"Can you make this more concrete?" Your diagram is too abstract. Add specific technology choices (PostgreSQL, Redis, Kafka), operation labels (POST /tweets, INSERT INTO tweets), and capacity hints such as an explicitly labeled 95% cache hit-rate assumption.
"What happens if Redis goes down?" This tests whether you've thought about failure paths. If your diagram only shows the happy path, you need to be ready to draw a fallback arrow (app server falls back to read replica on cache miss).
"Why did you add the queue here?" The interviewer is testing whether you added the component deliberately or reflexively. Your answer should reference a specific bottleneck: "Because fan-out to N followers is O(N) work that would block the API response if done synchronously."
"This seems complex for this scale." You've over-engineered. Round 1 might have been sufficient for the stated requirements. Always calibrate your architecture to the stated scale. If the interviewer said "100 users," you probably don't need Kafka.
Test Your Understanding
Use the following prompts to practice simplifying a diagram, labeling its paths, and adding failure behavior.
Recap
- Draw in three rounds: core data path (about 5 boxes as a rule of thumb), read optimization (cache, replicas, CDN), and write optimization (queues, workers, sharding). This progression is the framework.
- Label every arrow with the operation, HTTP verb, or data description. An unlabeled arrow communicates nothing and forces the interviewer to ask clarifying questions.
- Group components into named layers (Internet, App Tier, Cache Tier, Async Tier, Data Tier). Visual grouping makes complex diagrams scannable.
- Narrate while you draw using "I'm adding X because Y" sentences. The narration is as important as the diagram itself.
- Trace read and write paths separately. They go through different components in any non-trivial system, and calling them out separately shows architectural maturity.
- After Round 1, pause and ask the interviewer where to focus. This is collaborative and prevents you from optimizing the wrong thing.
- Be ready for failure-path questions. "What if Redis goes down?" should prompt a fallback arrow, not a blank stare.
Related Concepts
- Approach & Structure - Places diagramming after requirements, APIs, and flow design.
- Defining APIs First - Provides the endpoint contracts that give arrows and boxes concrete meaning.
- Handling Scale Questions - Extends the diagram when the interviewer changes the workload or constraint.
- Schema Design Approach - Connects data flows to entities, keys, and storage choices.
Related Articles
A 6-phase framework for any system design interview: requirements, NFRs, APIs, flows, architecture, and deep dives, with time splits for each.
A repeatable framework for when the interviewer says 'now scale it to 10x': how to identify bottlenecks, pick the right scaling strategy, and communicate the trade-offs.
How to design a data schema in a system design interview, starting from entities, mapping access patterns, picking storage, and making normalization decisions.