How to actually draw an HLD diagram under interview time pressure — notation conventions, what belongs in the first pass vs the deep-dive pass, and the specific mistakes that make a diagram read as unclear. Includes the C4 model with a worked e-commerce context and container diagram.
Published September 23, 2026
The 6-Step Design Framework names "high-level design" as a step; this lesson is specifically about the mechanics of drawing it well under real interview time pressure — a skill separate from knowing the architecture concepts themselves.
[Client] → [API Gateway] → [Order Service] → [Order DB]
↘ [Inventory Service] → [Inventory DB]
The first pass through a design should produce only: the major components (as boxes) and the direction of data flow between them (as arrows) — no database schema details, no specific algorithm choices, no failure handling yet. Trying to add full detail on the first pass is a common time-management mistake — it burns the limited whiteboard/interview time on details that might get redesigned once the interviewer picks a deep-dive target anyway.
Going deep on every component in the first pass means running out of time before reaching the deep-dive the interviewer actually wanted — the first pass exists specifically to give the interviewer a menu to pick from, not to pre-answer every possible follow-up.
→ synchronous call (caller waits for response)
⇢ or ~> asynchronous message (caller doesn't wait)
[Box] a service or component
(Cylinder / DB icon) a data store
A small, consistent set of notation conventions — distinguishing synchronous calls from asynchronous ones, at minimum — lets an interviewer read the diagram's intent at a glance rather than having to ask "wait, does this call block?" for every arrow. Labeling arrows with what actually flows ("order ID," "stock reservation request") rather than leaving them unlabeled is a small habit that measurably improves diagram clarity.
Most messy architecture diagrams have the same root problem: they try to show everything at once. The C4 model solves this by splitting one system into four diagrams, each answering a different question at a different zoom level, like a map app zooming from country to street.
| Level | Question it answers | What appears as a box | Typical audience |
|---|---|---|---|
| 1. Context | What is this system, and who and what does it talk to? | Your whole system as one box, plus people and external systems | Anyone, including non-engineers |
| 2. Container | What are the separately deployable or runnable pieces? | Services, web apps, databases, queues, caches | Engineers, interviewers |
| 3. Component | What are the main building blocks inside one container? | Modules or classes-with-responsibility inside a single service | Engineers working on that service |
| 4. Code | How is one component implemented? | Classes, interfaces (a UML class diagram) | Rarely drawn; the code itself usually serves |
"Container" here has nothing to do with Docker. In C4 it means anything that runs or stores data on its own: a Spring Boot service, a React app, a PostgreSQL database, a Kafka topic.
Why this matters in an interview: an HLD interview lives almost entirely at levels 1 and 2. Starting at level 1 shows you understand the system's boundary before its internals. Moving to level 2 is exactly the "boxes and arrows" first pass described above. Dropping to level 3 only for the one component the interviewer wants to deep-dive keeps each diagram at one consistent level of detail, which is the "mixing abstraction levels" mistake avoided by design.
The context diagram answers "what's inside our boundary and what isn't?" Everything inside collapses to a single box.
┌──────────────┐ ┌───────────────────────┐
│ Customer │──── browses, orders ───────▶ │ │
│ (person) │◀─── order status emails ──── │ │
└──────────────┘ │ E-Commerce System │
│ (our software) │
┌──────────────┐ │ │
│ Store admin │──── manages catalogue ─────▶ │ │
│ (person) │ └───────────┬───────────┘
└──────────────┘ │
┌──────────────────────────────┼─────────────────────────┐
▼ ▼ ▼
┌────────────────────┐ ┌────────────────────┐ ┌────────────────────┐
│ Payment gateway │ │ Email provider │ │ Shipping partner │
│ (external system) │ │ (external system) │ │ (external system) │
└────────────────────┘ └────────────────────┘ └────────────────────┘
Three things make this diagram useful rather than decorative:
Now open the single box. Each deployable service gets its own box, and each service owns its own data store. A database box connected to two services is a design smell you should either justify or remove.
Customer ──HTTPS──▶ ┌──────────────┐
│ API Gateway │ (auth, rate limiting, routing)
└──────┬───────┘
┌─────────────────┼──────────────────┬───────────────────┐
│ REST (sync) │ REST (sync) │ REST (sync) │
▼ ▼ ▼ │
┌─────────────┐ ┌─────────────┐ ┌──────────────┐ │
│ Catalog │ │ Order │──▶│ Payment │──HTTPS──▶ Payment gateway
│ Service │ │ Service │ │ Service │ (sync)
└──────┬──────┘ └──────┬──────┘ └──────┬───────┘
│ │ │
[Catalog DB] [Order DB] [Payment DB]
│
│ publishes OrderPlaced / OrderCancelled
▼
═══════ Kafka topic: order-events ═══════
┆ ┆
┆ (async) ┆ (async)
▼ ▼
┌──────────────┐ ┌──────────────┐
│ Inventory │ │ Notification │──▶ Email provider
│ Service │ │ Service │
└──────┬───────┘ └──────────────┘
│
[Inventory DB]
Reading it top to bottom tells the story of a checkout without a word of narration. The request enters through the gateway, and the order service calls payment synchronously, because the customer needs a yes or no now. The order service then announces the result as an event, and inventory and notifications react to it in their own time.
The container diagram above uses two visual languages on purpose:
Getting this distinction onto the diagram matters because it changes the answer to almost every follow-up question:
| Question | If the arrow is sync | If the arrow is async |
|---|---|---|
| Downstream service is down | Caller fails or degrades immediately | Messages wait in the topic; nothing fails for the user |
| Latency | Adds directly to the user's response time | Doesn't affect the response at all |
| Consistency | Caller sees the result immediately | Eventual; the consumer catches up later |
An interviewer who can see at a glance that "Order → Payment" is sync but "Order → Inventory" is async can ask the sharp questions immediately: what if payment times out? and what if inventory can't reserve the item after the order was accepted? That second question leads straight into the saga discussion.
Diagrams drawn once for a project are worth keeping and polishing, because the same system tends to come up again in "tell me about something you built" questions:
Q: How much time should the first-pass diagram actually take in a typical 45-minute interview? A: Roughly 5-8 minutes is a reasonable target after requirements and estimation are done — enough to lay out the major components and flow clearly, not so long that it eats into the deep-dive time that's usually where the interview is actually evaluated most heavily.
Q: Should failure handling (Failure Scenario Walkthroughs) be shown in the diagram itself, or just discussed verbally? A: Typically discussed verbally and only added to the diagram if it changes the architecture concretely (e.g. adding a previously-missing replica, or a cache layer) — annotating every possible failure directly on the first-pass diagram would clutter it past readability; the diagram should reflect the current best design, with failure reasoning layered in verbally or in a later revision.
Q: What if the interviewer asks a question the current diagram genuinely can't answer well? A: That's a legitimate moment to revise the diagram on the spot (adding a missing component, a missing data store) rather than trying to verbally patch over a real gap — interviewers generally view an candidate iterating visibly on their own diagram as a positive signal, not a sign of an incomplete first attempt.
Q: Does diagram notation matter more in a virtual (shared doc/whiteboard tool) interview vs an in-person whiteboard one? A: The underlying principles are identical, but virtual tools often make it easier to label arrows and reposition boxes cleanly — worth using that affordance deliberately (clean labels, consistent shapes) rather than defaulting to the same rough sketching habits that are more forgivable on a physical whiteboard.
Q: Do I need to draw all four C4 levels in an interview? A: No. Almost every HLD interview needs only level 1 (briefly, to agree the boundary) and level 2 (the main design). Drop to level 3 for one service only when the interviewer asks you to go deeper there. Level 4 is essentially never drawn in interviews, because at that depth the code or class design is the better medium.
Q: What's the difference between a C4 "container" and a Docker container? A: In C4, a container is anything that runs or stores data independently: a service, a single-page app, a database, a message topic. It may or may not be deployed in a Docker container. Using the word carefully (or saying "deployable unit" out loud) avoids confusing the interviewer.
Q: Why draw each service with its own database instead of one shared database? A: Shared databases couple services at the data level. One team's schema change can break another service, and you can't scale or migrate them independently. Drawing one data store per service makes ownership visible. If you do choose a shared database (a reasonable early-stage simplification), label it and be ready to defend the choice.