Chapter
Core Building Blocks Reference
Quick-reference deep dives on DNS, API gateways, storage types, search, and ID generation.
DNS & Load Balancing
DNS (Domain Name System) translates human-readable domain names to IP addresses. In system design, DNS is the first routing layer — GeoDNS directs users to the nearest region, weighted records split traffic for blue/green deploys, and low TTL enables faster failover.
Browser → OS cache → Recursive resolver (ISP/8.8.8.8)
→ Root (.com) → TLD → Authoritative NS → A/AAAA record
→ IP address → TCP connection to server/LB| Record type | Purpose | Design note |
|---|---|---|
| A / AAAA | Domain → IPv4 / IPv6 | Point to load balancer, not individual servers |
| CNAME | Alias to another domain | www → apex; CDN origin aliases |
| MX | Mail server routing | Email delivery (not web traffic) |
| TXT | Verification, SPF, DKIM | Domain ownership proofs |
| SRV | Service discovery | Internal service location |
- TTL (Time To Live): lower TTL (60s) for faster failover; higher (3600s) reduces DNS load
- DNS is eventually consistent — cached old IP after change until TTL expires
- Anycast: same IP announced from multiple locations; BGP routes to nearest PoP
- Health-checked DNS (Route 53, Cloudflare) removes unhealthy endpoints
Interview mention
Client → DNS → CDN (if cache hit) → LB → app. DNS failover is slow (TTL-bound) — use LB health checks for fast detection, DNS for regional routing.
API Gateway Patterns
An API gateway is a single entry point for client requests, handling cross-cutting concerns: authentication, rate limiting, routing, request/response transformation, SSL termination, and aggregation. It shields internal microservices from direct client exposure.
| Feature | Benefit | Examples |
|---|---|---|
| Authentication / JWT validation | Centralized auth before backend | Kong, AWS API Gateway, Envoy |
| Rate limiting | Protect backends per client/API key | Token bucket at edge |
| Routing | Path-based routing to services | /users → user-svc, /orders → order-svc |
| Aggregation (BFF) | Combine multiple backend calls | Mobile BFF returns one payload |
| Protocol translation | HTTP → gRPC internally | Gateway bridges clients and internal RPC |
- BFF (Backend for Frontend): separate gateway per client type (web, mobile, IoT)
- Don't put business logic in gateway — keep it thin (auth, route, limit)
- Gateway adds latency hop — co-locate with app tier in same AZ
- GraphQL gateway resolves fields to multiple microservices
Gateway vs load balancer
LB distributes traffic to identical servers. API gateway routes to different services by path/header and applies policies. Often both: CDN → LB → API Gateway → services.
Blob vs Block Storage
Block storage presents raw disk volumes to operating systems — used for databases, boot volumes, and anything needing POSIX file system semantics. Blob (object) storage provides HTTP-accessible key-value buckets for unstructured data at virtually unlimited scale.
| Property | Block (EBS, PD) | Blob (S3, GCS) |
|---|---|---|
| Access | Mount as disk (/dev/xvda) | HTTP API (GET/PUT by key) |
| Unit | Fixed-size blocks (4KB–64KB) | Whole object (bytes to 5TB) |
| Mutability | Random read/write any byte | Overwrite whole object (or multipart) |
| Scale | Limited per volume (64 TB) | Virtually unlimited objects |
| Cost model | Provisioned GB/month + IOPS | Storage class + requests + egress |
| Use case | DB files, VM boot disk | Images, video, backups, data lake |
- Never store large files in a relational DB — use blob storage + DB metadata
- Pre-signed URLs for direct client upload/download without proxying through app
- Multipart upload for large files (> 100 MB) with parallel parts
- Block storage snapshots for point-in-time backup; cross-region copy for DR
Design a photo app
Upload → pre-signed S3 URL → store {user_id, s3_key, metadata} in DB. Serve via CDN in front of S3. Thumbnails via Lambda on S3 ObjectCreated event.
Search Indexes (Elasticsearch)
Elasticsearch (and OpenSearch) is a distributed search and analytics engine built on inverted indexes. It excels at full-text search, fuzzy matching, faceted filtering, and aggregations — workloads that relational DB LIKE queries can't serve at scale.
| Concept | Description | Interview relevance |
|---|---|---|
| Inverted index | Term → list of document IDs | Fast 'find all docs containing X' |
| Shard | Horizontal partition of an index | Scale writes and storage |
| Replica | Copy of a shard for read scale + HA | More replicas = faster search QPS |
| Analyzer | Tokenize + stem text (e.g. 'running' → 'run') | Relevance tuning |
| Mapping | Schema: field types, analyzers | Define before indexing |
- Sync via CDC (Debezium) or dual-write from app on create/update
- Near-real-time: documents searchable ~1s after index (refresh interval)
- Don't use ES as primary store — rebuild index from source of truth if lost
- Autocomplete: edge n-gram tokenizer on title field
Write path: App → DB (source of truth)
└→ CDC / Queue → Indexer → Elasticsearch
Read path: App → ES (search queries)
└→ DB (fetch full record by ID after search hit)Product search design
Search returns IDs + snippets from ES. Hydrate full product details from cache or DB. Mention relevance scoring (BM25), filters (category, price range), and pagination via search_after cursor.
Unique ID Generation (Snowflake/UUID)
Distributed systems need globally unique identifiers without a single auto-increment coordinator. Strategies range from random UUIDs (simple, no coordination) to Snowflake IDs (time-ordered, sortable, dense) to database sequences with ranges allocated per server.
| Strategy | Format | Pros | Cons |
|---|---|---|---|
| UUID v4 | 128-bit random | No coordination; trivial | Not sortable; index fragmentation |
| UUID v7 | Time-ordered UUID | Sortable; standard | 128-bit still wide |
| Snowflake | 64-bit: timestamp + machine + sequence | Sortable; compact; high throughput | Requires machine ID coordination |
| DB auto-increment | Sequential integer | Simple; dense | Single-writer bottleneck; reveals count |
| Range allocation | Each server gets ID range from DB | Numeric; no per-insert coordination | Range exhaustion management |
| 1 bit sign | 41 bits timestamp (ms) | 10 bits machine ID | 12 bits sequence | 0 ~69 years from epoch 1024 machines 4096 IDs/ms per machine
- Snowflake: ~4096 IDs/ms per machine; clock skew handling via wait or error
- Twitter Snowflake, Sonyflake, custom — same concept, different bit allocation
- UUID v4 for public-facing opaque IDs (URLs, API tokens)
- Snowflake for internal time-ordered keys (feeds, logs, events) — better DB index locality
Design unique ID service
Dedicated ID generator service with pre-allocated machine IDs (via ZooKeeper/etcd). Batch allocate IDs in memory for throughput. Fallback: UUID if generator unavailable. Mention clock synchronization (NTP).
Staff depth layer
Building Blocks — Staff Depth
Building blocks (rate limiters, unique IDs, queues, search, notifications) are reusable patterns you compose. Staff answers know the algorithm options (token bucket vs sliding window, snowflake vs UUID), their failure modes, and how to place them in a larger design without over-fitting. Precision on APIs and data structures beats vague 'we'll use Redis'.
Anti-patterns → say instead
✕ Rate limit only at the edge
Bypasses, internal fans-out, and per-user vs per-IP dimensions still abuse downstream.
Say instead: Layer limits: edge IP, user/API key, and expensive dependency budgets with clear 429 semantics.
✕ UUID everywhere without thought
Random UUIDs fragment B-tree indexes and prevent sort-by-time without extra columns.
Say instead: Time-sortable IDs when locality matters; discuss DB index behavior and coordination.
✕ Bloom filter as source of truth
False positives are inherent; treating membership as exact causes wrong deletes/allows.
Say instead: Use blooms to skip expensive checks; always confirm positives against authoritative store.
✕ Queue as infinite buffer
Unbounded queues hide overload until disk fills; consumers never catch up.
Say instead: Bound depth, backpressure, DLQ, and load shedding with user-visible degradation.
API gateway must enforce 100 req/min per user across many gateway pods; soft real-time.
- Choose algorithm: token bucket in Redis for smooth bursts; sliding window log if audit-precise.
- Key = user_id; INCR/EXPIRE or Lua for atomicity; cluster Redis for QPS.
- Local counters with sync for ultra-hot paths — accept slight overshoot vs Redis RTT.
- Return 429 + Retry-After; distinct limits for auth vs anonymous.
- Observe: top limited keys, Redis latency, bypass monitoring for internal services.
- 100k RPS limit checks → Redis must handle comparable ops (pipeline/Lua)
- 100/min = ~1.67/s sustained; burst tokens e.g. 20
- Local+async sync may overshoot ~few % — call out the SLA
Name algorithm, atomic store, identity key, and the accuracy vs latency tradeoff.
Cheat sheet
- Rate limit: token bucket / sliding window / leaky
- IDs: UUID vs Snowflake vs DB sequence ranges
- Bloom: probabilistic; confirm positives
- Queues: at-least-once + idempotent consumers
- Search: inverted index; ranking separate
- CDN + signed URLs for large media
- Notifications: fanout, preference, quiet hours