The Boundary
High-Level Design decides what parts exist and how they relate. Low-Level Design decides how each part works inside. The dividing line is the component boundary: HLD treats every service, database, and queue as a box with a contract; LLD opens one box at a time.
┌─────────────────────────── HLD TERRITORY ───────────────────────────┐
│ │
│ Client ──► CDN ──► Load Balancer ──► Feed Service ──► Postgres │
│ │ ▲ │
│ ▼ │ │
│ Redis cache│ Kafka │
│ decisions: services, data stores, sync/async links, scaling axes │
└──────────────────────────────────┬──────────────────────────────────┘
│ contract handoff (API + schema)
┌──────────────────────────────────▼──────────────────────────────────┐
│ FEED SERVICE — LLD TERRITORY │
│ FanoutOnWrite vs FanoutOnRead strategy class │
│ FeedCacheKeyBuilder, RetryPolicy, connection pool sizing │
│ decisions: classes, patterns, algorithms, invariants │
└─────────────────────────────────────────────────────────────────────┘
The handoff between them is a contract: HLD fixes the API shape and data schema; LLD implements within it. If LLD needs to change the contract, that escalation goes back up to HLD — contracts are not implementation details.
Decision Scope Comparison
| Dimension | HLD | LLD |
|---|---|---|
| Unit of design | Services, databases, queues | Classes, interfaces, functions |
| Driven by | Scale, availability, cost, org structure | Requirements of one component, code quality |
| Key risks | Bottlenecks, SPOFs, consistency gaps | Coupling, fragility, unmaintainable code |
| Typical artifacts | Architecture diagram, estimation sheet, ADRs | Class diagrams, API specs per service, schemas |
| Validation | Load tests, failure drills, capacity models | Unit tests, code review |
| Time horizon | Years; evolves quarterly | Sprints; evolves continuously |
The Same Problem at Both Altitudes
Requirement: “users see their notification feed.”
HLD ANSWER LLD ANSWER (Feed Service)
- feed reads served from Redis - FanoutStrategy interface:
cache, rebuilt on miss PushFanout vs PullFanout impls
- writes fan out via Kafka to - key scheme: feed:{userId} with
fan-out workers cursor-encoded score
- cache TTL 24h, max 800 entries - batch pipeline write (pipeline()
~100 msgs) to Redis
- consistent? eventual is fine - retry with jitter on Redis timeout;
for feeds idempotency key = event UUID
Neither answer is complete without the other. The HLD choice (cache + async fan-out) dictates the LLD problem space; the LLD reality (batching limits, retry semantics) can force an HLD revision.
Why the Distinction Matters
- Different review audiences: HLD gets reviewed for risk and cost by senior/staff engineers; LLD for correctness by the owning team.
- Different change costs: moving a box in HLD ripples across teams and migrations; renaming a class in LLD is a refactor.
- Interview separation: system design interviews test HLD; many companies add a separate LLD round. Conflating them — drawing class diagrams when asked about scale, or naming shards without saying why — signals confusion about altitude.
Interview Framing
A strong answer keeps altitudes ordered: settle HLD first (components, data flow, scaling), then descend into LLD only where the interviewer probes. Announcing the descent (“let me detail the feed service internals”) demonstrates command of the boundary itself.
Premium Content
Unlock HLD vs LLD and all premium lessons with a subscription.
From ₹199.99/year — See plans