Blob storage and CDNs: big files, stored cheaply, served from nearby
Photos, videos, documents, backups and model weights are too big and too numerous for a database. They go in object storage, which is cheap, nearly impossible to lose data from, and effectively unlimited. Users then download them through a CDN, a network of servers close to them. The design skill is keeping your servers out of the way: clients upload straight to storage, and downloads come from the edge.
1. The idea
- Object storage (Amazon S3, Google Cloud Storage, Azure Blob Storage, and S3-compatible services such as Cloudflare R2) stores objects: a blob of bytes plus a little metadata, under a key like
uploads/u42/2026/10/7f3a.jpg, inside a bucket. There are no folders, no partial updates and no queries: youPUT,GET,DELETEandLISTwhole objects. - Durability comes from copies or erasure-coded pieces spread across devices and data centres. S3 is designed for 99.999999999% (eleven nines) durability, storing data across at least three availability zones by default.
- The database keeps the metadata: who owns the file, its key, size, type, status, and anything you'll query. Files themselves never go in the database.
- A CDN (CloudFront, Cloudflare, Akamai, Fastly, Google Cloud CDN) caches copies at hundreds of edge locations. A user in Sydney gets the image from Sydney, not from Virginia.
Rule of thumb: anything over about a megabyte that you won't query inside, and certainly anything over 10 MB, belongs in object storage.
2. How it works
Uploading a video, end to end
Press Play to follow a 2 GB video from a phone to viewers around the world, without its bytes ever passing through your app servers.
The pieces in that flow
- Presigned URL: your server signs a URL that grants one action (PUT this key) for a short time, with limits such as size and content type. Signing happens locally with your credentials, no call to storage needed. S3 presigned URLs can be valid for up to 7 days with long-term credentials; in practice use minutes. Google calls them signed URLs and Azure uses SAS tokens.
- Multipart upload: big files are sent in parts (S3: 5 MiB to 5 GiB per part, up to 10,000 parts, objects up to 48.8 TiB). Parts upload in parallel and can be retried individually; a failed upload resumes from the missing part instead of restarting. A lifecycle rule should delete abandoned uploads, which otherwise cost money silently.
- Events: storage announces new objects (S3 can notify SNS, SQS, Lambda or EventBridge). That event, not the client saying "done", marks the upload complete and triggers processing. A periodic reconciliation job catches anything an event missed.
- Consistency: S3 gives strong read-after-write consistency for PUTs and DELETEs: once a write succeeds, every read sees it.
How a CDN serves a file
A CDN is a set of caches in hundreds of cities. Here is one video segment's journey, from the first viewer in a city to every viewer after:
Pull CDNs and push CDNs
The figure above is a pull CDN: an edge fetches a file the first time someone near it asks. The alternative is a push CDN (or "pre-warming" a pull CDN): you upload files to the edges before anyone asks. Same files, two timings:
Distributed file systems
Object storage isn't the only way to keep huge amounts of data. Analytics clusters grew up on distributed file systems: Google's GFS (2003), its open-source copy HDFS, and their successors. They split each file into large chunks (64–128 MB), keep each chunk on three different machines, and separate the question "where is it?" from the bytes themselves:
Today, most new systems use object storage instead, which offers the same scale as a managed service and without one master's memory as a limit; Spark and similar engines read from S3 directly. You still meet HDFS in existing Hadoop clusters, and the same idea of a metadata path separate from the data path runs through object stores too (see Under the hood).
Video streaming works this way too: the video is cut into short segments in several qualities, listed in a playlist (HLS or DASH). The player downloads segments over plain HTTP and switches quality as bandwidth changes, so CDNs cache video like any other file.
3. Try it yourself
How much does the CDN save the origin?
Each edge location fetches an object from the origin at most once per TTL, then serves every other request itself. An origin shield collapses those fetches into one per object per TTL.
Model: requests spread evenly over the popular objects and edges; each edge–object pair misses once, then hits until the TTL expires (misses per second = 1 ÷ (TTL + 1 ÷ request rate)). Real traffic is skewed, which helps the most popular objects and hurts the long tail.
Cache-Control builder
Pick what the response is, and see the header to send and what it means.
4. Trade-offs
Direct upload vs through your servers
Direct (presigned) uploads are faster, cheaper and scale without you. Proxying through your servers only makes sense when every byte must be checked before storage (some compliance scanning), and even then, stream in chunks.
Long TTL vs freshness
Long TTLs maximise hits; changes then need new URLs or purges. Version file names for static assets, and use short TTLs (or stale-while-revalidate) for things like a public API response.
Storage classes
Frequently read data in the standard class; rarely read data in infrequent-access or archive classes that cost much less to store but more (and slower) to read. Lifecycle rules move objects automatically as they age.
Egress is the hidden cost
Storing a terabyte is cheap; sending it to the internet can cost far more. CDNs usually lower transfer prices and offload the origin. Check each provider's current pricing pages: these numbers change.
5. In real systems
| Need | AWS | Google Cloud | Azure |
|---|---|---|---|
| Object storage | S3 | Cloud Storage | Blob Storage |
| Temporary access | Presigned URL | Signed URL | SAS token |
| Big uploads | Multipart upload | Resumable upload | Block blobs |
| "New object" events | S3 Event Notifications | Pub/Sub notifications | Event Grid |
| CDN with signed access | CloudFront | Cloud CDN / Media CDN | Azure Front Door |
| Age-based cleanup | Lifecycle rules | Lifecycle management | Lifecycle policies |
- Keys are permanent design decisions. Generate them on the server (
uploads/{user}/{date}/{uuid}), never from the client's file name, so nobody can overwrite another user's file or guess a key. - Quarantine untrusted uploads: upload to a private bucket, scan and validate, then move to the serving bucket and mark the row as available.
- Range requests (
Range: bytes=…) let clients resume downloads and let video players seek; object storage and CDNs support them. - Specifications: HTTP caching is RFC 9111;
stale-while-revalidateis RFC 5861;immutableis RFC 8246.
The technologies up close
metadata in the database, bytes in S3, upload with presigned URLs (multipart for large files), mark complete from the storage event, serve through a CDN with signed URLs if private.Servers handle permissions and metadata; bytes never pass through them.
| Prompt | Flow |
|---|---|
| YouTube | Presigned multipart upload → storage event triggers transcoding → CDN with signed URLs for adaptive streaming |
| Direct upload of originals → event → workers make thumbnails and filters → CDN with signed URLs (stops hotlinking) | |
| Dropbox | Chunked presigned uploads feeding sync; shared links are time-limited signed URLs |
| Media uploaded directly; the chat message carries only the file reference; recipients get expiring download URLs |
Object storage (S3 and equivalents)
The default for files · bytes here, metadata in the DBEffectively unlimited storage for whole objects (bytes plus a little metadata) under keys in buckets, designed for 11 nines of durability.
How it works
PUT, GET, DELETE and LIST whole objects; no partial updates and no queries. S3 gives strong read-after-write consistency. The rich metadata (owner, status, size, permissions) belongs in your database, not in object tags: S3 allows only 10 tags per object and you can't query them.
Status today (checked October 2026)
Amazon S3, Google Cloud Storage, Azure Blob Storage, and S3-compatible services (Cloudflare R2, MinIO). The standard home for media, documents, backups and model weights.
Use it when
- Any file over about 10 MB, and any file you'd never query with SQL
- Media, documents, backups, logs, data-lake files
Skip it when
- Small values that are part of a record (a 2 KB JSON blob can live in the database)
- Data that needs partial updates or queries
In the interview
The moment files appear: Metadata in the database, bytes in S3.
- Storing images or videos as blobs in the database.
- Rich metadata only in object tags, which you can't query.
Presigned URLs
The default for uploads and private downloadsA URL your server signs, granting one action (PUT or GET) on one key for a short time, so clients talk to storage directly.
How it works
- The server checks the user and their quota, picks the key (
uploads/{user}/{date}/{uuid}, never the client's file name), and signs the URL locally: no call to storage. - Sign in limits: content length range and content type, so the URL can't be used to upload a 50 GB file. Anyone holding the URL can use it until it expires (minutes, not days).
- At the same moment, create the database row with
status = 'pending'and the key.
Status today
Presigned URLs on S3, signed URLs on Google Cloud Storage, SAS tokens on Azure.
Use it when
- Any upload or download larger than a normal API payload
- Private files that shouldn't be public
Skip it when
- Uploads that must be validated synchronously before accepting (a CSV whose header must be right)
- Compliance scanning before storage: proxy those, streaming in chunks
In the interview
The API returns a presigned PUT URL valid for 15 minutes with a size limit; the client uploads straight to S3.
- Proxying uploads through app servers without a reason: they become slow, expensive pipes.
- Client-chosen keys, or URLs without size limits.
- Trusting a client "upload done" call to mark the file ready: races, fake completions, orphaned files. Use the storage event plus a reconciliation job.
Multipart and resumable uploads
Situational · big files, flaky networksSplit a big upload into parts that go in parallel and can be retried individually, then stitch them together.
How it works
S3 multipart: parts of at least 5 MiB, each with its own presigned URL, up to 10,000 parts. On failure, list the parts already uploaded and send only the missing ones; finish with a complete call carrying the part list and checksums. Progress = parts done. A lifecycle rule deletes abandoned uploads after a day or two, because unfinished parts cost money. Google Cloud Storage and Azure use a single session URL with chunks instead.
Status today
Standard on every object store; most SDKs do it automatically above a size threshold.
Use it when
- Files larger than about 100 MB
- Mobile uploads that may be interrupted
Skip it when
- Small files: one PUT is simpler
In the interview
Videos upload in 10 MB parts; if the phone loses signal at 60%, the app lists the finished parts and resumes from part 4.
- Restarting a 2 GB upload from zero after a failure at 99%.
- No lifecycle rule for abandoned uploads.
CDN delivery with signed URLs
The default for downloads at scaleServe files from CDN edges near users; protect private ones with signed URLs or signed cookies the edge verifies itself.
How it works
The CDN checks the signature with a public key at the edge, so private videos are protected without every request reaching your servers. Popular files go from roughly 200 ms to a few milliseconds after the first request, and the CDN absorbs most traffic. HTTP range requests let downloads resume and players seek.
Status today
CloudFront signed URLs and cookies, Google Cloud CDN and Media CDN, Azure Front Door, Cloudflare and Fastly.
Use it when
- Media and downloads at any real scale
- Paid or private content (signed URLs stop hotlinking)
Skip it when
- Rarely accessed private files, where a presigned storage URL is simpler and cheaper
In the interview
Downloads go through CloudFront with signed URLs that expire in an hour.
- Serving large files from app servers, or straight from one region's bucket to the whole world.
Storage classes and lifecycle rules
Situational · cost at scaleCheaper tiers for data that's rarely read, and rules that move or delete objects as they age.
How it works
Standard for hot data; infrequent-access and archive classes cost far less to store but more, and more slowly, to read. Lifecycle rules move objects between classes after N days and delete expired ones (including abandoned multipart uploads).
Status today
Every provider offers several classes and lifecycle policies; check current pricing pages, which change.
Use it when
- Petabytes of media where most items are rarely watched after a month
- Backups and compliance archives
Skip it when
- Small datasets: the savings don't matter
In the interview
Originals move to an infrequent-access class after 30 days and to archive after a year.
- Ignoring egress cost: sending data out often costs far more than storing it.
How a CDN works inside
Situational · CDN-heavy designsThe choices behind a CDN: who puts content at the edge, how many cache tiers, what can be cached, and how edges stay fresh.
How it works
- Pull vs push: a pull CDN fetches from your origin on the first miss (the default for websites and most media); a push CDN is loaded ahead of time (large files, scheduled releases, video before a premiere).
- Request routing: anycast or DNS sends each user to a nearby, healthy edge.
- Tiers: edges ask regional caches, which ask an origin shield, which asks the origin, so a popular file is fetched from the origin once rather than by every edge.
- Dynamic content: personalised pages can still use the CDN's network (TLS near the user, connection reuse to the origin), and edge compute (Workers, Lambda@Edge) can assemble or authorise responses at the edge.
- Freshness: versioned URLs for static assets (best), short TTLs with stale-while-revalidate for things that change, purge APIs for urgent removals.
Status today
Cloudflare, Akamai, Fastly, CloudFront and the clouds' own CDNs all offer tiered caching, shields, signed URLs and edge compute; push-style prefetch exists for big releases.
Use it when
- Global audiences, media, software downloads, launches with predictable spikes (push or prefetch)
Skip it when
- Personal data cached under shared keys
In the interview
A pull CDN with an origin shield; assets have versioned URLs and year-long TTLs, and the API sends short TTLs with stale-while-revalidate.
- Purging the CDN on every change instead of versioning URLs.
- Assuming a CDN only helps static files: it also terminates TLS near users and keeps warm connections to the origin.
Inside a blob store
Situational · "design S3" questionsHow a service like S3 stores trillions of objects durably: a metadata service, chunk servers, and replication or erasure coding.
How it works
- Front end: authenticates requests and routes them.
- Metadata service: maps bucket + key to the object's chunks and their locations; it's a sharded, replicated database, and the part that must be strongly consistent.
- Data (chunk) servers: store fixed-size chunks on disk, spread across racks and zones.
- Durability: three full replicas cost 3× the space. Erasure coding splits an object into, say, 6 data pieces plus 3 parity pieces: any 6 of the 9 rebuild it, for 1.5× the space. Replicas suit hot, small data; erasure coding suits large, colder data.
- Background work: scrubbing (re-reading data to catch silent corruption with checksums), repairing lost pieces, and garbage-collecting deleted objects.
Status today
S3, Google Cloud Storage and Azure Blob Storage use variants of this; open-source equivalents include Ceph and MinIO. S3 is designed for 11 nines of durability.
Use it when
- Infrastructure interviews: "design a blob store", "design Dropbox's storage layer"
Skip it when
- Product designs: there you use S3, you don't build it
In the interview
Metadata in a sharded, replicated store; data as erasure-coded chunks across three zones, so losing a whole zone loses nothing.
- Storing three full copies of petabytes without considering erasure coding's cost savings.
- Forgetting scrubbing: disks corrupt data silently; checksums catch it.
CDN cache keys, Vary, and purging by tag
Situational · when the CDN hit rate mattersA CDN can only reuse a response for requests that produce the same cache key. By default the key is roughly the host plus the full URL. Every needless difference in the key splits one popular object into many copies, each fetched from your origin.
How it works
Keep the key small:
- Drop what doesn't change the response: tracking parameters (
utm_*, click IDs), and parameters your origin ignores. Sort the ones you keep, so?a=1&b=2and?b=2&a=1match. - Be careful with
Vary. It tells caches to keep a separate copy per value of a request header.Vary: Accept-Encodingis fine (a few values).Vary: User-AgentorVary: Cookiecreates thousands of variants and the hit rate collapses. Normalise at the edge instead: map user agents to "mobile" or "desktop", or pick an image format fromAccept, and key on that. - Never put personal data under a shared key. A response that depends on who's logged in is either marked
privateor keyed per user (which usually means: don't cache it at the CDN).
Purging many pages at once. A price change for one book affects its page, three category pages, the search results and the homepage carousel. Purging by URL means knowing every one of them. Instead, the origin tags each response with the things it contains (Surrogate-Key: book-42 cat-crime home on Fastly, Cache-Tag on Cloudflare), and one purge of the tag book-42 clears every page that shows that book.
Better than purging, where you can: static assets get versioned URLs (app.3f9c2.js) and a year-long TTL, so a deploy changes the URL and nothing needs purging; changing content gets a short TTL with stale-while-revalidate; tag purges are for edits that must show now.
Status today
Fastly (Surrogate-Key) and Cloudflare (Cache-Tag) both purge by tag; other CDNs offer similar features. Checked October 2026 on their documentation.
Use it when
- Public pages and media served through a CDN
- Catalogues where one item appears on many pages
Skip it when
- APIs whose responses are per user
In the interview
The cache key drops tracking parameters and we never vary on cookies. Each page is tagged with the books it shows, so a price change purges tag book-42 and every page with that book refreshes within seconds.
Vary: Cookieon a public page: the CDN keeps a copy per visitor.- Purging by URL list and missing the pages nobody remembered.
A file system across thousands of machines: GFS and HDFS
Classic design · SOSP 2003The Google File System stored huge files (crawls, logs, indexes) on thousands of cheap machines that failed every day. Its central trick still shapes big-data storage: one master holds all metadata in memory, and the bytes flow directly between clients and storage servers, never through the master.
How it works
- Big chunks. Files are split into 64 MB chunks (HDFS: 128 MB blocks by default), each stored on three servers. Big chunks keep the master's metadata small enough for memory.
- The master stays out of the data path. Clients ask it once where a chunk lives, cache the answer, then talk to the storage servers.
- Leases order the writes. For each chunk, the master gives one replica a lease to act as primary; the primary picks the order of all changes and the others follow it.
- Data and control travel separately. The bytes are pushed along a chain of replicas, nearest first, to use every link's bandwidth; the small "apply it" request goes to the primary.
- Record append, at least once. Many producers can append to one file; each record lands atomically at least once, at an offset the system chooses, so readers must skip duplicates and padding.
- Surviving the master. Metadata changes go to an operation log replicated to other machines, with checkpoints; read-only shadow masters keep reads going during a failover.
| GFS (paper) | HDFS (open source) |
|---|---|
| Master, chunkservers, 64 MB chunks | NameNode, DataNodes, 128 MB blocks |
| Operation log on several machines, shadow masters | High availability: an active and a standby NameNode sharing edits through JournalNodes |
| Record append for many writers | Single writer per file, append supported |
Status today
GFS was replaced inside Google by Colossus, which spreads the metadata over many servers instead of one master. HDFS still runs many data lakes, though object storage (Module 10 above, Design D35) has taken most new workloads. Facts checked October 2026 in the GFS paper and the HDFS architecture guide.
Use it when
- Explaining metadata vs data paths in any storage design
- "Design a distributed file system"
Skip it when
- Many small files: one master holding every name in memory is the known limit
In the interview
A single metadata service holds the namespace in memory and hands out leases per chunk; the bytes go client to storage servers along a replication chain, so the metadata service never sees data.
- Routing file bytes through the metadata server.
- Billions of tiny files on a single-master design.
6. Remember it
How this hook works: what "Servers sign, storage carries, edges deliver" means
What the slogan means, phrase by phrase
- "Servers sign"
- The API checks the user and quota, creates a pending metadata row, and returns a presigned URL. It never touches the file's bytes.
- "storage carries"
- The client uploads directly (multipart for big files); the storage service holds the bytes durably and announces the upload with an event.
- "edges deliver"
- Readers download through the CDN, which caches near them and checks signatures for private content.
Why this picture fits: it's the furniture shop again: the counter does paperwork, the warehouse holds stock, the local depot delivers. Nobody carries sofas through the showroom.
The story → the concept
| Furniture shop | System |
|---|---|
| The order form at the counter | The API call that returns a presigned URL |
| The delivery note for one item, valid today | A presigned URL: one key, one action, short expiry |
| The warehouse | Object storage |
| "Delivered" scanned at the warehouse | The storage event that marks the upload complete |
| The depot near the customer | A CDN edge location |
| The order record | The metadata row in the database |
Watch it on an example
- A user shares a 40 MB photo album in a chat app.
- Servers sign: the API returns 8 presigned URLs and creates 8 pending rows.
- Storage carries: the phone uploads in parallel; storage events flip each row to "ready" and trigger thumbnails.
- Edges deliver: 500 group members open the album; the CDN serves the thumbnails from their nearest edge, and the origin serves each file roughly once per region.
The trap it saves you from
Uploading through app servers. They become slow, expensive pipes that tie up memory and connections for minutes per file, and they're the first thing to fall over.
It still works when…
The "files" are machine learning models or dataset shards: store them as objects, give jobs temporary credentials, and let many readers pull from storage or a cache layer instead of a single server (Module 29).
7. Common mistakes
/invoice/123.pdf without checking access can serve it to anyone. Use private or signed URLs.8. Design exercise (25 minutes)
- Design profile photos for an app with 50M users: the upload API, the bucket key scheme, thumbnail generation, the metadata row and its statuses, and how the app shows the photo.
- Make it resumable: users on trains upload 500 MB videos. Describe what the client stores, what happens at 80% when the connection drops, and how abandoned uploads are cleaned up.
- Choose headers with the builder for: your JavaScript bundle, a user's private invoice PDF, and a public "trending" API response that may be 30 seconds old.
- Size the CDN: 100,000 requests a second for 10,000 popular images across 300 edges, TTL one day. Roughly how many requests reach the origin? With a shield?
- Write it down: the upload flow in five steps, in your design notebook.
9. Self-check quiz
With a presigned URL, who sends the file's bytes to storage?
What should mark an upload as complete in your database?
You ship a new version of app.js, cached for a year at the CDN. Best way to make users get it?
app.3f9c2.js) are fresh by definition, and the old ones can stay cached safely.A multipart upload fails at 90%. What happens?
What should mark an uploaded file as ready in your database?
A 2 GB upload fails at 99%. What's the right design?
Why do large blob stores use erasure coding rather than three full copies for cold data?
A public page sends Vary: Cookie, and the CDN hit rate is 2%. Why?
One book's price changes, and it appears on 30 different pages. What purges them all most reliably?
Why could GFS run with a single master for thousands of servers?
10. Go deeper
| Resource | Time | Why |
|---|---|---|
| Uploading and copying objects using multipart upload (Amazon S3 docs) | 20 min | How multipart works, its limits, and cleaning up incomplete uploads. |
| Cache-Control (MDN) | 15 min | Every directive, with examples of what to send for each kind of content. |
| Serve private content with signed URLs and signed cookies (CloudFront docs) | 20 min | Protecting paid or private files at the edge. |
| Handling large blobs (Hello Interview) | 20 min | The interview version of this page, with common follow-up questions. |
11. Under the hood (optional)
How object storage, file systems and disks really work, from signed URLs to erasure coding. Not needed for most interviews; open it when you want to know how the products really do it. All the deep dives are listed on the Under the hood page.
Object, file and block storageOperations each allows, the object API, a live SigV4 signing lab, conditional writes, erasure coding, chunking, SSDs, 8 products comparedabout 40 min
Object storage looks like a giant key-value store with a web API, and that is roughly what it is. The details decide real designs: what you can't do that a file system can, how a signed URL proves permission without a password, what happens when two clients overwrite one key, and how eleven nines of durability are bought.
What each kind of storage lets you do
| Operation | Block (EBS, local disk) | File (local FS, NFS, EFS) | Object (S3, GCS, Azure Blob) |
|---|---|---|---|
| Change bytes in the middle | Yes | Yes | No: write the whole object again (or compose parts) |
| Append | Yes | Yes | Not on S3 or GCS (Azure has append blobs; S3 Express One Zone supports appends) |
| Atomic rename | (Via the file system) | Yes, and it's how apps publish files safely | No: copy plus delete; "directories" are just key prefixes |
| Locks | One machine owns it | Advisory locks (unreliable over NFS) | None; use conditional writes or Azure leases |
| Shared by many machines | Usually one at a time | Yes | Yes, from anywhere over HTTP |
| Scale and cost | Up to tens of TB per volume | Petabytes, higher cost | Effectively unlimited, cheapest per GB |
The object API
| Request | What it does | Worth knowing |
|---|---|---|
PUT /key | Create or replace the whole object | Atomic: readers see the old or the new object, never a mix |
GET /key with Range: bytes=0-1048575 | Read all or part | Range reads make video seeking and parallel downloads possible |
HEAD /key | Metadata only: size, ETag, content type | Cheap existence and change checks |
DELETE /key | Remove (or add a delete marker when versioning is on) | Deleting a missing key still succeeds |
LIST ?prefix=photos/2026/&delimiter=/ | Keys in sorted order, up to 1,000 per page with a continuation token | The delimiter makes prefixes look like folders; listing millions of keys is slow, so keep your own index |
COPY | Server-side copy, no download | How "rename" and storage-class changes are done |
| Multipart: create, upload parts, complete (or abort) | Upload a big object in parallel parts, retrying only failed parts | S3: up to 10,000 parts of 5 MiB–5 GiB; objects up to 50 TB since December 2025. Abort unfinished uploads with a lifecycle rule, or their parts keep costing money |
Signed URLs, step by step
A presigned URL lets a browser upload or download one object directly, without your servers in the data path and without your credentials. Your server signs a description of the request with its secret key; the storage service recomputes the signature and checks it. This lab computes a real AWS Signature Version 4 presigned URL in your browser. It uses AWS's documented example credentials; with the default inputs it reproduces the signature in AWS's own documentation.
- What's protected: the method, bucket, key, expiry and signed headers. Change any of them and the signature no longer matches (403). The secret key never leaves your server.
- Limits: SigV4 presigned URLs last at most 7 days, and no longer than the credentials that signed them (temporary role credentials often expire within hours).
- Uploads with rules: a presigned PUT can't cap the file size; a POST policy can (
content-length-range, allowed key prefix, content type). Google Cloud Storage has the same V4 signing; Azure uses SAS tokens; CloudFront signs URLs or cookies for whole paths.
Overwrites, versions and conditional writes
- Last writer wins by default: two concurrent PUTs both succeed and the later one remains.
- Conditional writes:
If-None-Match: *creates only if the key doesn't exist (S3 since August 2024), andIf-Match: <ETag>replaces only the version you read (S3 since November 2024), otherwise412 Precondition Failed. Google Cloud Storage uses generation numbers (ifGenerationMatch); Azure uses ETags and blob leases. - Versioning keeps every version; a DELETE adds a delete marker on top, so the object can be restored. Old versions cost storage until a lifecycle rule expires them.
- Consistency: S3 has been strongly consistent for reads after writes, overwrites, deletes and listings since December 2020; Google Cloud Storage and Azure Blob are strongly consistent too.
- Request rates: S3 supports at least 3,500 writes and 5,500 reads per second per key prefix and scales by splitting busy prefixes; a sudden spike can see
503 Slow Downuntil it does, so retry with backoff.
Durability: replication vs erasure coding
Three full copies tolerate two losses at 3× the storage. Erasure coding splits an object into k data fragments and adds m parity fragments; any k of the k + m rebuild it (Reed–Solomon).
- The cost of erasure coding is repair traffic and latency: rebuilding one lost fragment reads k others, and small objects are expensive to split, so many systems replicate hot or small data and erasure-code the rest.
- Placement matters as much as the code: fragments go to different disks, servers, racks and zones (failure domains), or one rack failure takes out several at once. HDFS ships policies such as RS-6-3; S3 Standard stores data across at least three Availability Zones and is designed for 99.999999999% durability.
Metadata path vs data path
- Separate them: a small metadata service knows which key or file lives where; the bulk bytes flow directly between clients and storage nodes. GFS and HDFS put all metadata in one master's memory (the NameNode), which is why millions of small files hurt HDFS.
- Or compute placement: Ceph's CRUSH algorithm calculates which devices hold an object from the cluster map, so no lookup table is needed. MinIO stores metadata alongside each object instead of in a central database.
- Large object stores keep a partitioned, replicated index of keys separate from the storage fleet, which is why listing and per-prefix request rates have their own limits.
Chunking and deduplication
Sync tools (Dropbox-style apps, backup tools like restic and Borg) split files into chunks, name each by its hash, and upload only chunks the server lacks. Where the boundaries go decides how much survives an edit:
Content-defined chunking (Rabin fingerprints, FastCDC's gear hash) cuts wherever a rolling hash of the last few bytes matches a pattern, so boundaries move with the content and an insert changes only nearby chunks. Fixed-size chunks are simpler and fine when edits overwrite in place (Dropbox uses 4 MB blocks).
Underneath: file systems and SSDs
- Durable, atomic file writes follow one recipe: write a temporary file,
fsyncit,renameit over the target (atomic), thenfsyncthe directory. Skipping a step can leave an empty or half-written file after a crash. - Journaling (ext4, XFS) logs metadata changes before applying them; copy-on-write file systems (ZFS, Btrfs) never overwrite in place, which gives checksums and instant snapshots.
- SSDs can't overwrite in place: flash is written in pages (KBs) but erased in blocks (MBs). A flash translation layer remaps writes to fresh pages and garbage-collects old blocks, so a nearly full SSD moves more data per write (write amplification) and slows down. TRIM tells the drive which pages are free.
- Network block volumes (EBS, persistent disks) are replicated within a zone and sold by size, IOPS and throughput; local NVMe is faster but disappears with the machine.
Product by product
| Product | Model and access | Overwrites and consistency | The detail worth knowing |
|---|---|---|---|
| Amazon S3 | Buckets of keys; SigV4 presigned URLs; multipart uploads (10,000 parts); objects up to 50 TB | Strongly consistent including listings; whole-object replace; versioning with delete markers; If-Match and If-None-Match | Request rates scale per key prefix |
| Google Cloud Storage | Objects with generation numbers; V4 signed URLs; resumable uploads; compose up to 32 objects | Strongly consistent; preconditions on generations | Generations give compare-and-swap on objects |
| Azure Blob Storage | Block blobs (commit a list of uploaded blocks), append blobs, page blobs; SAS tokens | ETag checks; leases for exclusive writers | Append blobs suit logs; page blobs back VM disks |
| MinIO | S3-compatible, self-hosted | Strict consistency within a deployment | Erasure coding per object; metadata stored with the data |
| Ceph | RADOS objects placed by CRUSH; S3 via RGW, block via RBD, files via CephFS | Strong within the cluster | Placement is computed, not looked up |
| HDFS (and GFS) | Files in large blocks (128 MB by default) on DataNodes; NameNode holds metadata in memory | Write once, append only; 3 replicas across racks or erasure coding | Many small files exhaust NameNode memory |
| Block volumes | A network disk for one machine, replicated in a zone | Behaves like a local disk | IOPS and throughput are bought separately |
| Local file systems | Inodes, extents, directories | Journaling or copy-on-write | fsync plus atomic rename make writes durable and atomic |
Say it in the interview
- "How do users upload 2 GB videos?" The API returns presigned multipart-upload URLs; the client uploads parts directly to object storage in parallel, retrying failed parts; on completion an event triggers processing. App servers never touch the bytes.
- "Two editors save the same object. What happens?" Last writer wins unless we use conditional writes: read the ETag, PUT with If-Match, and on 412 re-read and merge.
- "Why not keep 3 copies of everything?" At petabyte scale 3× storage is expensive; erasure coding like 6+3 gives similar fault tolerance at 1.5×, with replication kept for small or hot data.
You PUT an object with If-Match set to the ETag you read earlier. What does a 412 mean?
Erasure coding with k = 6 data and m = 3 parity fragments costs how much storage, and survives how many losses?
Why does content-defined chunking deduplicate better than fixed-size chunks after an insert near the start of a file?
Sources
- S3: authenticating requests with query parameters (SigV4)
- S3: conditional writes
- S3: versioning
- S3: multipart upload
- S3: performance design patterns
- S3: strong consistency
- S3: maximum object size raised to 50 TB (December 2025)
- Cloud Storage: request preconditions
- Azure Blob: managing concurrency
- Ceph: CRUSH maps
- HDFS architecture
- HDFS erasure coding
- FastCDC (USENIX ATC 2016)
Video deliveryEncoding ladders and codecs, HLS, DASH and CMAF, DRM, an adaptive-bitrate lab, live latency optionsabout 20 min
Video is most of the internet's traffic, and its design is about fitting a picture through an unpredictable network: encode each title at several qualities, cut it into short segments, and let the player choose segment by segment.
The pipeline
- Ingest the original upload (often hundreds of GB for professional content) into object storage.
- Transcode into an encoding ladder: several resolutions and bitrates (say 240p at 0.4 Mbps up to 4K at 15 Mbps), in parallel chunks across many machines. Per-title encoding (pioneered by Netflix) picks the ladder from the content: a cartoon needs far fewer bits than a football match.
- Package into 2–6 second segments plus a manifest listing every rendition: HLS (
.m3u8, Apple, universal) or DASH (.mpd); CMAF lets both share one set of fragmented MP4 segments, halving storage and cache use. - Protect with DRM where needed: Widevine (Chrome, Android), FairPlay (Apple), PlayReady (Microsoft); multi-DRM services encrypt once with common encryption (CENC).
- Deliver through CDNs; popular segments are served from edge caches, so origin load stays tiny.
| Codec | Compression vs H.264 | Support |
|---|---|---|
| H.264 / AVC | Baseline | Everywhere, cheap hardware decoding |
| H.265 / HEVC | About half the bitrate for similar quality | Apple devices, TVs; patent licensing is complex |
| VP9 | Similar to HEVC, royalty-free | Chrome, Android, YouTube |
| AV1 | Better still, royalty-free | Modern browsers and newer devices with hardware decoders; slow to encode |
Services encode popular titles in several codecs and serve each device the most efficient one it can decode: more encoding cost, less bandwidth.
Adaptive bitrate: the player decides
Before each segment, the player picks a rendition. Too high and the buffer drains into a stall; too low and the picture is needlessly soft. Here the bandwidth drops from 9 to 1.6 Mbps, recovers, then dips again:
- Throughput-based players estimate bandwidth from recent segment downloads and pick a rendition below it with a safety margin. Buffer-based ones (BBA, BOLA in dash.js) choose from how full the buffer is. Production players combine both, and some (like Netflix's) add learned models.
- Start fast: begin at a low rendition so playback starts in about a second, then climb.
Live and low latency
| Approach | Typical delay behind real time | Use |
|---|---|---|
| Classic HLS/DASH (6 s segments, 3 in the buffer) | About 20–30 s | Broadcast-scale live where delay doesn't matter |
| Low-latency HLS / low-latency DASH (partial segments, preload hints) | About 2–5 s | Sports, live shopping, still CDN-friendly |
| WebRTC | Under 1 s | Calls, auctions, interactive streams; needs media servers (SFUs), not plain CDNs |
Say it in the interview
- "How does Netflix-style streaming adapt to bad networks?" Each title is encoded as a ladder of renditions cut into 2–6 s segments listed in a manifest; the player measures throughput and buffer and picks each segment's rendition, served from CDN caches.
- "Why not just send the 4K file?" Bandwidth varies second to second; a single bitrate either stalls on weak connections or wastes quality on strong ones, and segments let players switch without restarting.
In HLS or DASH, who chooses which quality to download next?