Inkwell Drive lets writers share big files with their readers: drafts, images, whole manuscripts. It's the case where the data is large, not the request rate, and the design is mostly about keeping those bytes away from the parts of the system that can't carry them. This lesson follows the interview order, and its deep dives name the chapters behind each answer.
Ask before you draw
| Question | Why it matters | Inkwell Drive |
|---|---|---|
| How big are the files? | Decides whether one request can carry one file | A few MB to tens of MB, sometimes more |
| Who can open a file? | Every download needs a permission check | The owner, and anyone given a link |
| Where are the readers? | Distance is latency | Three continents |
| What if an upload is cut off? | Large uploads fail midway | Resume it, don't restart |
| Is anything done to a file after upload? | Thumbnails and scans are background work | Thumbnails and a virus scan |
Write the sizes down. They set the whole design: a file is too big to treat like a request, so the data and the request have to travel separately.
Estimate the load
Work the chain yourself first, from the assumptions in the worksheet. The worked numbers open once you've done it.
API and data model
Keep two kinds of data apart: the small, structured metadata, and the big blobs.
- Metadata (database): file id, owner, name, size, folder, sharing settings, upload state. Kilobytes per file, queried and changed constantly.
- Blobs (object storage): the bytes, keyed by file id (or by a hash of the content, so identical files are stored once).
An upload takes three calls. POST /files records the metadata and returns a presigned URL, a link with a signature that lets the client write to one place in storage for a few minutes. The client uploads the bytes straight to storage with that link. Then POST /files/{id}/complete marks the file ready. Downloads work the same way: GET /files/{id} checks permissions and returns a signed link, and the bytes come from storage or a CDN.
The app servers see only the small requests. They never see a file.
Keep the bytes off the servers
Metadata goes through the servers, and the files go around them.
The first design sends everything the same way, files included. The database's network card, not its CPU, is what runs out first: a megabyte a request fills it long before the processor is busy.
Uploads need a way in
Downloads can go straight to a CDN, because storage holds the file. An upload is harder, because someone has to say it's allowed. The presigned URL is the answer: the app servers say yes by signing, and the client sends the bytes to storage itself.
For files bigger than a few hundred MB, upload in parts: split the file, upload the parts separately and in parallel, and ask storage to join them. A cut connection loses one part, not the file. Then do the after-work in the background: a queue and workers make thumbnails and scan for viruses, and the file shows as processing until they finish.
Deep dives
This lesson is the serving half of a Dropbox or a Google Drive: getting big files in and out. The other half is sync, and it isn't simulated here: files split into chunks, chunks stored once by hash, a conflict copy when two devices change the same file, and a change notification to every device. Raise it in the interview, so the interviewer knows you see the whole system.
| They ask | What to say | Chapter |
|---|---|---|
| A 2 GB upload fails at 90% | Upload in parts, and resume from the missing ones | Object storage |
| Someone shares a link, then revokes it | Short-lived signed URLs, a short CDN TTL, and a permission check each time one is issued | Object storage |
| One file goes viral | The CDN absorbs it. Protect storage with a shield layer so one miss isn't a thousand | Edge, Hot keys |
| The same file is uploaded 1 000 times | Store by content hash, and keep one copy | Object storage |
| Thumbnails take a while | A queue and workers, with the original served until they're ready | Queues and workers |
| Storage costs too much | Move old files to a cheaper tier, delete what was removed, watch egress | Bandwidth |
| People upload video, not documents | Transcode in the background into several bitrates, cut each into segments of a few seconds, and serve the segments from the CDN. The player picks a bitrate segment by segment as the network changes (HLS or DASH) | Queues and workers, Edge |
| Two people edit the same document at once | Whole-file sync can only keep both versions, as a conflict copy. Live co-editing sends small operations instead, through one server per document that orders them, and merges concurrent edits with operational transformation (as Google Docs does) or a CRDT (as libraries like Yjs and Automerge do) | Consistency |
Pick two, and say why you'd start with one.
Say the tradeoffs
| Choice | One side | The other side |
|---|---|---|
| Where bytes go | Through the app: simple, and it slows everything | Presigned and CDN: more moving parts, the servers stay free |
| CDN | Faster for distant readers and less load on storage, about the same bill, stale until the TTL ends | None: always current, slow for distant readers |
| Dedupe | Store by hash: saves storage, needs a hash and a reference count | Store each upload: simple, wasteful |
| Upload | One request: simple, fails whole | In parts: resumable, more calls |
Commit to metadata in a database, blobs in object storage behind a CDN, and presigned uploads, in parts for the few huge files. Then say what you'd watch: egress, the CDN hit rate, upload failures and the age of the thumbnail queue.
In the wild
The ideas in this chapter, and where you'll meet them in real systems and interviews:
| Idea | Where you'll meet it |
|---|---|
| Presigned upload and multipart upload | Amazon S3 |
| Signed URLs through a CDN | Amazon CloudFront signed URLs |
| Metadata apart from blobs | Dropbox, which stores files in blocks addressed by hash |
| Thumbnails and scans as background work | An object-created event driving a queue and workers |
Your practice
Inkwell Drive's database fell over under its own files. Move the files out, let readers on three continents open them fast, and then make it cost as little as you can.