SD System Design In Depth
0%
design system-designobject-storagedesign

Design: an object store (S3)

Module 6.1: Infrastructure & Core Service Designs Updated Sep 18, 2026
📄 Cheat Sheet
Amazon S3 (Object Stores) - In Practice | Distributed Systems Deep Dives With Ex-Google SWE
Jordan has no life Amazon S3 (Object Stores) - In Practice | Distributed Systems Deep Dives With Ex-Google SWE Watch on YouTube ↗

Explains how an S3-like store is built internally: the metadata and data split, chunking, replication vs erasure coding, and consistency. The current video is about using object storage in interviews, not designing one.

0:00 / --:--

Object Storage vs. Block & File Systems

Object storage (like Amazon S3, Google Cloud Storage, or MinIO) is designed for large binary objects such as images, videos, and backups. It generally does not support in-place byte mutation, but many services do allow a key to be replaced or deleted; immutable names, retention controls, or versioning are separate policies. Unlike POSIX file systems, object APIs commonly expose key-oriented operations such as GET, PUT, DELETE, and HEAD.

Storage Tiering Architecture

flowchart TD Client["HTTP Client"] --> Edge["API & Load Balancer Tier"] Edge --> MetaService["Metadata Service & KV Store"] Edge --> StorageNode["Storage Engine / Data Nodes"] StorageNode --> Disk1[("Disk 1: Chunk")] StorageNode --> Disk2[("Disk 2: Chunk")] StorageNode --> Disk3[("Disk 3: Erasure Coding Parity")]

Separation of Metadata and Payload Data

  • Metadata Tier: Stores object key, bucket name, size, ETag/checksum, ownership, and mapping to physical disk blocks. Stored in high-speed distributed KV stores (like Spanner, CockroachDB, or Cassandra).
  • Data Storage Tier: Large object payloads are split into fixed-size chunks (e.g., 64MB or 128MB) and written append-only to storage daemon drives.

Durability via Erasure Coding vs. 3x Replication

Standard 3x replication carries a 200% storage overhead (300GB disk used for 100GB data). Modern object stores implement Reed-Solomon Erasure Coding (e.g., 8 + 4 scheme):

  • Data is split into 8 data chunks, and 4 parity chunks are generated (total 12 chunks).
  • The object can survive the loss of any 4 of its 12 chunks simultaneously (so any 4 drives, nodes or racks only if the 12 chunks are placed in 12 independent failure domains) while imposing only a 50% storage overhead, saving millions of dollars in hardware costs.

Worked example: 3x replication vs RS(8,4)

SchemeRaw storage for 10 PB logicalFailures toleratedRead to repair one lost 20 TB driveRead latency
3x replication30 PB2 copies lostAbout 20 TB (copy from one replica)Read from 1 node
Reed-Solomon 8+415 PBAny 4 of 12 chunks lostAbout 160 TB (8 chunks per lost chunk)Read 8 chunks in parallel; slow nodes add tail latency
Hybrid (replicate recent objects, erasure-code them after N days)Between the twoBothBothFast for new objects

Saving 15 PB of raw disk is worth millions per year, which is why large stores erasure-code warm and cold data. The extra repair traffic is why codes that reduce repair reads, such as Local Reconstruction Codes used in Azure Storage, exist.

Write path

sequenceDiagram participant C as Client participant F as Front end participant M as Metadata service participant D as Data nodes x12 C->>F: PUT bucket/key, 1 GB F->>D: Stream erasure-coded chunks to 12 nodes in separate racks D-->>F: Checksums acknowledged F->>M: Commit key to chunk map, size and ETag M-->>F: Committed, new version is now visible F-->>C: 200 OK with ETag

The object only becomes visible when the metadata commit happens, after the data is durable. That ordering is how S3 provides strong read-after-write consistency, which it has done for all operations since December 2020. A crash before the commit leaves orphaned chunks, which a background garbage collector cleans up.

Numbers worth knowing

  • S3 is designed for 99.999999999% (eleven nines) annual durability, and advertises at least 3,500 writes and 5,500 reads per second per prefix, scaling out by adding prefixes.
  • Multipart upload: parts of 5 MiB to 5 GiB, at most 10,000 parts, objects up to 5 TiB. Parts upload in parallel and can be retried individually.
  • Metadata scale: 100 billion objects at about 300 B of metadata each is about 30 TB. It must be sharded by bucket and key range, which is why listing a prefix is fast but "find all objects larger than X" is not supported natively.
Check yourself Question 1 of 3
Failure-domain placement apply
From: Durability via Erasure Coding vs. 3x Replication

An RS 8+4 object has its 12 chunks placed on only 6 racks, two chunks per rack. How many simultaneous whole-rack failures is it guaranteed to survive?

Key Takeaways

Decouple metadata management from high-volume binary payload data storage.
Object APIs generally avoid in-place byte mutation, but keys may still be replaced or deleted unless versioning or retention policy prevents it.
Erasure coding reduces storage overhead for a chosen fault tolerance; end-to-end durability also depends on failure-domain placement, checksums, repair speed, and operations.
Multipart uploads allow large files to be uploaded concurrently and resumed seamlessly on network interruptions.
Was this lesson helpful? Spot an issue or have a suggestion? Let us know on GitHub.
Report an issue