Free lesson · System Design Crash Course
HLD vs LLD vs Design Docs vs Architecture
Lesson 1.2 - HLD vs LLD vs Design Docs vs Architecture
The vocabulary lesson.
Here's a thing that happens to almost every engineer at some point: you join a new company, and within the first week, you hear all four of these terms used in different ways by different people. Someone says "let's set up an architecture review." Someone else says "we need an LLD before we can implement this." A third person says "did you read the design doc?" A fourth says "the HLD has the answer." And you nod along, because asking what they all mean feels like admitting you don't know basic things.
Here's the secret: even experienced engineers use these terms inconsistently. There's no single industry standard. Different companies use them slightly differently. But there ARE real distinctions underneath the inconsistency, and learning them will save you a lot of confusion. This lesson lays out the distinctions clearly, so when you encounter these terms in the wild, you'll know what they likely mean and what to ask if you're unsure.
Let me walk you through each term, then show how they relate.
High-Level Design (HLD)
We covered this in Lesson 1.1. HLD is the activity of deciding the overall shape of a system. It works at the level of components, services, and connections. When you do HLD, you produce things like:
- A diagram with boxes representing the major services
- Arrows showing how they communicate
- Notes about which database each service uses
- Decisions about whether to put a cache somewhere
- Estimates of how much traffic each component handles
The key phrase is "overall shape." You're working zoomed out, seeing the system as a whole. You're not zoomed into the details of any single component.
A simple HLD diagram for a basic web app looks like this:
flowchart LR
User["User's browser"]
CDN["CDN<br/>(Static assets)"]
LB["Load Balancer"]
App["App Servers<br/>(2-3 instances)"]
Cache["Cache<br/>(Redis)"]
DB["Database<br/>(Postgres)"]
User --> CDN
User --> LB
LB --> App
App --> Cache
App --> DB
style App fill:#a78bfa,stroke:#8b5cf6,color:#000
style DB fill:#34d399,stroke:#10b981,color:#000
style Cache fill:#fbbf24,stroke:#f59e0b,color:#000
A high-level design diagram showing a simple web application. The user's browser connects to a CDN for static assets like images and CSS, and to a load balancer for dynamic requests. The load balancer distributes traffic across two or three app server instances. The app servers read from a Redis cache for fast lookups, and read and write to a Postgres database for persistent storage. This is what an HLD looks like - boxes representing components, arrows representing connections, and no detail about what's inside any single box.
Notice what's NOT here. There's no mention of which programming language the app servers are written in. No detail about which Postgres tables exist. No note about how the cache is sharded internally. Those are LLD-level details. HLD stops at the boundary of each box.
Low-Level Design (LLD)
If HLD is about the overall shape, LLD is about what's inside one box. When you do LLD, you're zoomed in on a specific component, working out its internal structure.
LLD produces things like:
- Class diagrams showing the classes inside a service
- Method signatures and how they interact
- Data structures used internally
- Algorithms and their complexity
- Specific design patterns being applied (Observer, Factory, Strategy)
- Object-oriented relationships (inheritance, composition, interfaces)
If HLD is the architectural blueprint of a building (showing rooms and connections), LLD is the electrical and plumbing schematics of one specific room. It's the detail level where you decide how the room actually functions.
To make this concrete: in our HLD diagram above, there's a box called "App Servers." That box hides a lot of detail. Inside it, there might be:
- A
UserControllerclass that handles user requests - A
UserServiceclass that contains the business logic - A
UserRepositoryclass that talks to the database - A
CacheClientclass that talks to Redis - A specific design pattern like "Repository Pattern" being applied throughout
That's LLD. It's how the App Server actually works internally. Useful when you're implementing or modifying that specific component; not useful when you're trying to understand the system as a whole.
LLD is what gets tested in LLD interviews (sometimes called "object-oriented design" interviews). You're asked something like "design a parking lot system" or "design a chess game," and you produce class diagrams and method signatures. That's LLD work - designing the internals of one component.
flowchart TB
subgraph AppServer["App Server (one box in the HLD)"]
Controller["UserController"]
Service["UserService"]
Repo["UserRepository"]
CacheClient["CacheClient"]
Controller --> Service
Service --> Repo
Service --> CacheClient
end
style AppServer fill:#a78bfa,stroke:#8b5cf6,color:#000
A low-level design diagram showing what's inside one of the boxes from the HLD - specifically the App Server. Inside it: a UserController class that receives incoming HTTP requests; a UserService class that contains the business logic; a UserRepository class that talks to the database; and a CacheClient class that talks to Redis. The Controller calls the Service, which calls the Repository and the CacheClient. This is what LLD looks like - internal structure of one component, with classes and method calls. Notice that the entire diagram fits inside one box of the HLD. LLD zooms in; HLD zooms out.
So:
- HLD = the system as a whole (services, databases, queues)
- LLD = inside one service (classes, methods, internal data structures)
These two are complementary. A well-designed system needs both. HLD makes the high-level decisions; LLD makes the per-component decisions inside that frame.
Interactive animation: HLD zooms out to services and databases; LLD zooms into one service's classes - design Instagram versus a parking lot.
Design Docs
A design doc is a written document describing a proposed change to a system. It's not a level of abstraction (like HLD or LLD) - it's a format, a document type. Inside a design doc, you might include HLD content, LLD content, or both. The point is that it's written down, reviewed by other engineers, and approved before significant work begins.
Design docs typically include:
- Context. What problem are we solving? Why now? Why does this matter?
- Requirements. What does the solution need to do? What's out of scope?
- Proposed design. The HLD (and sometimes LLD) of the solution.
- Alternatives considered. What other approaches did we think about? Why did we reject them?
- Trade-offs. What are we giving up with this approach? What are the risks?
- Open questions. Things still being figured out.
- Implementation plan. Rough steps to actually build it.
- Success criteria. How do we know if this worked?
Design docs are a cultural practice more than a technical artifact. At Google, Stripe, Amazon, Meta, and most senior engineering organizations, writing a design doc is a normal part of starting any non-trivial project. Junior engineers write them; senior engineers review them.
Here's the loose hierarchy:
flowchart TB
Doc["Design Doc<br/>(the written artifact)"]
HLD["HLD content<br/>(usually included)"]
LLD["LLD content<br/>(sometimes included)"]
Context["Context, alternatives,<br/>trade-offs, plans"]
Doc --> HLD
Doc --> LLD
Doc --> Context
style Doc fill:#a78bfa,stroke:#8b5cf6,color:#000
A diagram showing what's inside a design doc. The design doc is the written artifact. Inside it, there's usually HLD content showing the proposed system shape. Sometimes there's LLD content showing the internal structure of components. And there's also context - the problem being solved, alternatives considered, trade-offs, implementation plan. So a design doc is a container that includes both HLD and LLD content along with the surrounding context that explains and justifies the design. Different companies have different design doc templates, but they almost always include these elements.
So when someone says "I'm writing a design doc," they mean "I'm writing the proposal document for this change, which will include the HLD and possibly the LLD, along with context and reasoning." Design docs are the written form of HLD and LLD thinking.
A really important point: design docs are how senior engineers actually communicate at most companies. When you advance in your career, you'll spend more time writing and reviewing them. They're not bureaucratic - they're how teams align on what's being built before code is written.
Architecture
"Architecture" is the broadest and fuzziest term. It encompasses everything technical about a system at a high level, plus often some non-technical concerns. When someone says "architecture," they might mean:
- The HLD of the whole system (the technical design)
- The technology stack ("we're a Postgres + Python + React shop")
- Architectural principles ("we prefer simplicity over cleverness")
- The overall organizational shape ("which teams own which services")
- Cultural norms about how technical decisions get made
- Long-term roadmaps and platform direction
Different organizations emphasize different parts. At a small startup, "the architecture" might mean basically the HLD plus some technology choices. At a large enterprise, "the architecture" might be a 50-page document with principles, governance processes, and decision-making frameworks.
The relationship between these terms:
flowchart TB
Arch["Architecture<br/>(the broadest term)"]
HLD["HLD<br/>(technical system shape)"]
LLD["LLD<br/>(component internals)"]
Tech["Technology choices<br/>(languages, frameworks, tools)"]
Principles["Principles &<br/>cultural norms"]
Org["Organizational structure<br/>(team ownership)"]
Arch --> HLD
Arch --> Tech
Arch --> Principles
Arch --> Org
HLD --> LLD
style Arch fill:#fb7185,stroke:#f43f5e,color:#000
style HLD fill:#a78bfa,stroke:#8b5cf6,color:#000
style LLD fill:#fbbf24,stroke:#f59e0b,color:#000
A diagram showing how all these terms relate. At the top is "Architecture" - the broadest term. It encompasses HLD, which is the technical system shape. It also encompasses technology choices like programming languages and frameworks. It includes principles and cultural norms about how to build software. And it covers organizational structure - which teams own which parts of the system. LLD sits underneath HLD as a more detailed view of individual components. So architecture is the umbrella; HLD is the technical design piece of it; LLD is the next zoom-in below HLD.
You can think of it this way: architecture is the whole umbrella; HLD is the technical-design piece of it; LLD is one zoom deeper; design docs are how you write any of these down.
When in doubt about what someone means by "architecture," ask clarifying questions. "Are we talking about the system design? The technology choices? The team structure?" People often answer "yes, all of it." That's fine - at least you've made the conversation specific.
When You Need Each
Interactive animation: When you reach for each term: HLD, LLD, a design doc and architecture, each with its typical trigger.
Now that you know what each term means, here's when you actually use each one:
You do HLD when:
- Starting a new system or major feature
- Scaling an existing system
- Migrating to a new technology
- Investigating a system-wide performance problem
- Preparing for a system design interview
You do LLD when:
- Implementing a specific component
- Refactoring a class or module
- Preparing for an LLD interview ("design a parking lot")
- Onboarding to an existing codebase (understanding its internal structure)
You write a design doc when:
- Proposing any non-trivial change to a production system
- Onboarding new engineers (existing docs help them learn)
- Building consensus across teams
- Creating a record for future engineers ("why did we do it this way?")
You think about architecture when:
- Setting platform direction
- Hiring and team organization
- Making technology bets ("are we a Postgres shop or a MySQL shop?")
- Writing internal documentation about your team's principles
In practice, most engineering work touches multiple of these. A senior engineer designing a new payment service might:
- Write a design doc (the format)
- That includes HLD (the system shape)
- And some LLD (the key components inside)
- While respecting the company's overall architecture (principles, technology stack)
Knowing the vocabulary lets you communicate precisely about what you're doing at each moment.
A Real-World Example
Let me give you a concrete example to tie this all together.
Imagine you're a senior engineer at a startup, and the product team comes to you with: "We want to add a notification feature. Users should get an email and a push notification when someone replies to their post."
You start thinking. The work involved will touch all four concepts:
Architecture-level thinking. You note that your company has a stated principle of "no new third-party services without security review." That affects what notification provider you can use (you'll need to vet candidates). You also know your stack - you're a Node.js + Postgres + Redis company - so you'll work within that.
HLD work. You sketch the design. You'll need: a notifications service that knows how to send notifications, integration with an email provider (SendGrid? Mailgun?), integration with a push notification provider (Firebase? OneSignal?), a way to track which notifications were sent, and a worker queue (already in the system) to send asynchronously so user requests aren't blocked.
flowchart LR
User["User posts<br/>a reply"]
App["App server<br/>(existing)"]
Queue["Message Queue<br/>(existing)"]
NotifService["Notification Service<br/>(NEW)"]
Email["Email Provider<br/>(SendGrid)"]
Push["Push Provider<br/>(Firebase)"]
DB["Notifications DB<br/>(NEW table)"]
User --> App
App --> Queue
Queue --> NotifService
NotifService --> Email
NotifService --> Push
NotifService --> DB
style NotifService fill:#a78bfa,stroke:#8b5cf6,color:#000
style DB fill:#a78bfa,stroke:#8b5cf6,color:#000
The HLD for the notifications feature. When a user posts a reply, the existing app server publishes a message to the existing message queue. A new notifications service consumes messages from the queue, sends emails via SendGrid, sends push notifications via Firebase, and records what was sent in a new notifications database table. The two highlighted boxes - the Notification Service and the Notifications DB - are new components. Everything else already exists. This is HLD work - deciding what new components are needed, where they fit, and how they connect to existing infrastructure.
LLD work. Within the new Notification Service, you'd design the internal classes - maybe a NotificationDispatcher, an EmailSender, a PushSender, a NotificationRepository. You'd think about retries, idempotency, how to handle failures from the external providers. This is the internal design of the new service.
Design doc. You write all of this down in a 4-page document. Title: "Notifications Feature Design." Sections: Background, Requirements, Proposed Design (with the diagrams above), Alternatives Considered (what about doing this synchronously?), Trade-offs (what happens if SendGrid is down?), Implementation Plan (rolled out in 3 phases), Open Questions (do we need user preferences?). You share it with your team for review.
Each of these activities is real engineering work. They flow into each other. Knowing which one you're doing at any moment is how you communicate clearly with teammates.
A Common Confusion
One last thing worth naming because it trips up beginners constantly:
You'll sometimes hear people say "the HLD" or "the LLD" as if it's a fixed document. "Have you seen the HLD for the orders service?" In this usage, "the HLD" means "the document that describes the high-level design." So HLD can refer to either the activity (designing) or the artifact (the document showing the design). Same for LLD.
Context tells you which one is meant:
- "Let's do some HLD." → the activity
- "Read the HLD." → the document/artifact
This dual usage is normal. Both meanings are correct. Just stay aware of which one you're talking about.
Interactive animation: 'Let's do some HLD' means the activity, while 'Read the HLD' means the document that shows the design.
Six Takeaways from This Lesson
- HLD = overall system shape (boxes and arrows for services, databases, queues).
- LLD = inside one component (classes, methods, internal structure of a single service).
- Design doc = written artifact that contains HLD and/or LLD content plus context and reasoning. It's the format senior engineers use to communicate technical proposals.
- Architecture = the broadest term, encompassing HLD, technology choices, principles, organizational structure.
- You'll use multiple of these in any real project. They're not competing - they're complementary, working at different levels.
- The terms get used inconsistently across companies. When in doubt, ask what someone specifically means.
Try It
Exercise: Warmup (10 minutes). For a project at work or a personal project, write down which of these you've done: HLD, LLD, written a design doc, set architectural principles. Most engineers have done HLD and LLD without naming them.
Exercise: Core (20 minutes). Take any HLD diagram from a system you know about. Pick ONE box. Now sketch the LLD for that box - what classes or functions are inside? What's the internal structure?
Exercise: Stretch (30 minutes). Search for "Google design doc template" or "engineering design doc example." Read one from a real company. Note how it combines HLD, LLD, and context.
What's Next
Lesson 1.3 introduces a five-component mental model that fits every system you'll encounter. It's the most useful framework you'll learn in this module - a lens that makes any architecture diagram easier to read.