AlgoInsight

Free lesson · AWS for System Design Interviews

The primitive behind the product

Easy9 min readawssystem-designinterview-preparation

Every Managed Service Is A Known Primitive

There is nothing in the AWS catalogue that is architecturally novel. Each service is a well-understood distributed systems primitive, operated for you, with a control plane and a billing model attached.

That is not a criticism - operating these things is genuinely hard and the value is real. It is an observation with a direct consequence for interviews:

Important: If you know the primitive, you can derive the service's properties instead of memorising them.

A candidate who knows DynamoDB is a partitioned hash table can reason their way to the hot-partition problem, the fixed access patterns, and why a GSI is eventually consistent - without having read those facts anywhere. They follow from the structure.

A candidate who memorised the facts can recite them and cannot extend them. When the interviewer asks something outside the memorised set, the difference becomes visible immediately, and it is the moment most system design interviews are decided.

The test to apply to yourself: could you sketch how you would build this service? Not to production quality - enough to explain where the data lives, how it is partitioned, what is replicated, and what breaks under load. If you cannot, you do not understand the service; you have a summary of it.


The Storage Layer

S3 - a distributed object store. Objects are chunked, erasure-coded, and spread across many devices in multiple AZs. Metadata lives in a separate indexing layer, which is why listing is a different operation from reading and historically the slower one.

Understanding the erasure coding is what makes eleven nines make sense - you can lose several devices and reconstruct. Understanding the separate metadata layer is what explains why the flat namespace is not a filesystem and why prefix design once mattered for throughput.

EBS - network-attached block storage, replicated within one AZ. It is not on your host; it is over the network. That explains the latency floor, why it is AZ-scoped, and why snapshots to S3 are the only cross-AZ path.

Instance store - actual local NVMe. Physically attached, which is why it is fastest and why it disappears when the instance moves to different hardware.

EFS - a distributed NFS implementation. Metadata coordination across a distributed filesystem is expensive, which is why per-operation latency is higher than a local disk and why it costs what it does.


The Database Layer

DynamoDB - a partitioned hash table with optional range keys, built on log-structured storage. Items are distributed by a hash of the partition key. Every one of its published behaviours follows from that sentence:

Behaviour Because
Hot partitions throttle Throughput is per-partition, not global
Access patterns fixed at design time The key determines placement
No joins Items are spread across nodes
GSIs eventually consistent The index is asynchronously maintained
Predictable latency A hash lookup, not a query plan

Aurora - a conventional database engine on a distributed, log-structured storage layer. The interesting part is the split: the engine writes only the redo log to storage, and the storage layer materialises pages. The log is replicated six ways across three AZs with a quorum write.

Tip: The Aurora architecture is worth being able to describe, because it explains its whole property set and it is a strong signal when it comes up.

Replicas are fast to add and lag very little because they read the same shared storage rather than replaying a replication stream - there is no second copy of the data being built.

Failover is fast because the storage survives the compute; a new writer attaches to existing storage rather than recovering it.

Storage is durable across AZs by construction, not by a replication feature bolted on.

And the constraint follows too: one writer. The shared storage layer serialises writes, so Aurora scales reads far better than writes - which is exactly the design constraint that matters when you choose it.

ElastiCache - Redis or Memcached, operated. No architectural mystery; the primitive is an in-memory key-value store, and Redis's single-threaded command execution is the property that matters most for design.

RDS - a database on an instance with automated operations. Multi-AZ is synchronous replication to a standby with DNS-based failover, which is why failover has a window and why your connection pool must reconnect.


The Messaging Layer

graph TD
    Q[**Queue** - work distributed<br/>among competing consumers] --> SQS[SQS]
    L[**Append-only log** —<br/>ordered, replayable,<br/>multiple independent readers] --> K[Kinesis, MSK]
    PS[**Pub/sub fanout** —<br/>one message, many<br/>subscribers, no retention] --> SNS[SNS, EventBridge]
    Q --> QP[Message consumed once.<br/>Visibility timeout.<br/>**No ordering** unless FIFO.]
    L --> LP[**Ordered per shard.**<br/>Retained and replayable.<br/>Each reader has an offset.]
    PS --> PP[**No retention** by default.<br/>Not delivered means gone,<br/>unless a queue subscribes.]
This diagram shows three messaging primitives and their AWS implementations. A queue distributes work among competing consumers and is implemented by SQS: each message is consumed once, with a visibility timeout, and no ordering unless FIFO is used. An append-only log is ordered and replayable with multiple independent readers, implemented by Kinesis and MSK: ordered per shard, retained, with each reader holding its own offset. Pub/sub fanout sends one message to many subscribers with no retention, implemented by SNS and EventBridge: undelivered messages are gone unless a queue subscribes.

Warning: Confusing the queue and the log primitives is one of the most common design errors, and it shows up as a specific symptom: needing to reprocess and being unable to.

A queue is consumed. Once a message is deleted it is gone. Adding a second consumer group means the two compete for messages rather than each receiving all of them.

A log is read. Each consumer holds its own offset, the data is retained, and adding a consumer later lets it read history from the beginning.

The design question that discriminates: will you ever need to add a new consumer that must see past events, or reprocess after fixing a bug? If yes, you need a log, and choosing a queue is a decision you cannot undo without rebuilding the ingestion path.


The Edge And Network Layer

CloudFront - a CDN. Points of presence caching content near users, with the origin behind them. The primitive is geographically distributed caching, and every CDN question - invalidation, cache keys, TTLs, the thundering herd on a cold cache - is a caching question.

Route 53 - anycast DNS with health checking. DNS is a distributed, heavily-cached lookup system, which is the source of every property that matters: failover is bounded by caching you do not control, and clients may ignore your TTL entirely.

ALB and NLB - layer 7 and layer 4 load balancers. The distinction is whether the balancer terminates and understands the protocol. Layer 7 can route on path and header and terminate TLS; layer 4 forwards packets and is faster and less capable.

API Gateway - a reverse proxy with authentication, throttling, and transformation. The primitive is an API front door.


The Coordination And Compute Layer

Lambda - a container scheduler with a very short-lived container and per-invocation billing. Cold start is container start; the concurrency limit is a scheduler limit; the 15-minute cap is a scheduling policy.

Step Functions - a distributed state machine with durable execution state. The primitive is a workflow engine, and the value is that the state survives failure of any worker.

ECS and EKS - container orchestrators. Desired-state reconciliation loops: you declare what should run, a control plane makes reality match.

KMS - a hardware-backed key hierarchy with an authorisation layer. Envelope encryption: a data key encrypts the data, the master key encrypts the data key, the master key never leaves the module.


The Analytics And ML Layer

Redshift - a columnar, massively parallel query engine. Data is stored by column rather than by row, so a query touching three columns of a hundred reads three columns' worth of bytes. That single fact explains why it is fast for aggregation and wrong for point lookups - retrieving one complete row means reassembling it from a hundred separate column stores.

Athena - a distributed query engine over object storage. No storage of its own; it reads files in S3 and runs SQL across them. The primitive is query-over-files, which is why file format and partitioning determine everything - the engine can only skip what the layout lets it skip.

Glue - a metadata catalogue plus managed ETL. The catalogue is the interesting half: a schema registry mapping table names to file locations and formats, which is what makes files queryable as tables.

OpenSearch - an inverted index. Terms map to the documents containing them, which is why full-text search is fast and why the index is a derived, eventually-consistent copy of your source of truth rather than the source itself.


Where The Analogy Ends

Important: Knowing the primitive tells you the shape of the properties. It does not tell you the specific numbers, and the gap between them is where careless answers get caught.

Knowing DynamoDB is a partitioned hash table tells you there will be a per-partition throughput ceiling. It does not tell you what that ceiling is, and it does not tell you about adaptive capacity, which changes how the ceiling behaves in practice.

Knowing Aurora shares storage across replicas tells you lag will be low. It does not tell you it is zero - it is not.

The correct interview posture is to reason from the primitive and caveat the specifics: "there will be a per-partition limit - I would check the current number, but the design implication is that I need the key to distribute." That is a stronger answer than a confidently quoted figure, because quoted figures go stale and a wrong one confidently delivered is far more damaging than an acknowledged uncertainty.


Common Failure Modes

Warning: Treating managed services as magic. No basis for reasoning about failure.

Memorised properties rather than derived ones. Cannot extend beyond the memorised set.

Cannot sketch how the service would be built. A summary, not understanding.

Confusing queue and log primitives. Discovered when reprocessing is needed.

Assuming Aurora scales writes. One writer, by construction.

Assuming replicas are current. Low lag is not zero lag.

Expecting filesystem semantics from an object store.

Quoting specific limits confidently. They change; a wrong figure is expensive.

Not knowing which primitive a named service implements.

Assuming SNS retains messages. It does not.


Why This Matters In An Interview

Interview: This is the knowledge that makes primitive-first answers possible.

What interviewers are listening for:

  • Properties derived from structure rather than recited.
  • The queue/log distinction, correctly applied.
  • Aurora's shared storage explaining its read-scaling and single-writer constraint.
  • Reasoning about limits without quoting stale numbers.

Common follow-ups:

  • "How would you build DynamoDB?" → Consistent hashing over a key space, partitions replicated across AZs, log-structured storage per node, a routing layer mapping keys to partitions, and asynchronous index maintenance. That sketch explains every published behaviour.
  • "Why can Aurora add read replicas so quickly?" → They attach to the same distributed storage rather than building a second copy from a replication stream. That also explains fast failover, and why it does not help with writes.
  • "Queue or stream for this?" → Will anything ever need to reprocess history or add a consumer that must see past events? If yes, a log. That is the discriminating question, and it is not reversible later.
  • "What is the throughput limit on that?" → There will be a per-partition ceiling because throughput is provisioned per partition. I would verify the current figure - the design consequence is that the key must distribute.

Practice

Exercise: Starter. For five services you would name in an interview, write one sentence naming the primitive each implements.

Intermediate. For one service, derive three of its documented behaviours from its structure without looking them up. Then check.

Advanced. Sketch how you would build Kinesis: partitioning, ordering, retention, consumer offsets, and rebalancing. The parts you cannot sketch are the parts you do not understand.


Related Topics

Back to AWS for System Design Interviews