retrystorm · Learn · Interview practice · Glossary · Components

Home › Learn › File Sharing

Chapter 40 · Case studies · 28 min

File Sharing

Designing Inkwell Drive end to end: sizes first, the numbers, metadata apart from blobs, presigned uploads, a CDN, deep dives and tradeoffs.

Inkwell Drive lets writers share big files with their readers. The first version sends every file through the app servers and the database. Last week the database's network card filled up and the whole service fell over, folders included.

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

QuestionWhy it mattersInkwell Drive
How big are the files?Decides whether one request can carry one fileA few MB to tens of MB, sometimes more
Who can open a file?Every download needs a permission checkThe owner, and anyone given a link
Where are the readers?Distance is latencyThree continents
What if an upload is cut off?Large uploads fail midwayResume it, don't restart
Is anything done to a file after upload?Thumbnails and scans are background workThumbnails 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 askWhat to sayChapter
A 2 GB upload fails at 90%Upload in parts, and resume from the missing onesObject storage
Someone shares a link, then revokes itShort-lived signed URLs, a short CDN TTL, and a permission check each time one is issuedObject storage
One file goes viralThe CDN absorbs it. Protect storage with a shield layer so one miss isn't a thousandEdge, Hot keys
The same file is uploaded 1 000 timesStore by content hash, and keep one copyObject storage
Thumbnails take a whileA queue and workers, with the original served until they're readyQueues and workers
Storage costs too muchMove old files to a cheaper tier, delete what was removed, watch egressBandwidth
People upload video, not documentsTranscode 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 onceWhole-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

ChoiceOne sideThe other side
Where bytes goThrough the app: simple, and it slows everythingPresigned and CDN: more moving parts, the servers stay free
CDNFaster for distant readers and less load on storage, about the same bill, stale until the TTL endsNone: always current, slow for distant readers
DedupeStore by hash: saves storage, needs a hash and a reference countStore each upload: simple, wasteful
UploadOne request: simple, fails wholeIn 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:

IdeaWhere you'll meet it
Presigned upload and multipart uploadAmazon S3
Signed URLs through a CDNAmazon CloudFront signed URLs
Metadata apart from blobsDropbox, which stores files in blocks addressed by hash
Thumbnails and scans as background workAn 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.

Key takeaways

  • The file sizes decide the design: data and requests travel separately.
  • The request rate is small and the bytes are huge, so bandwidth and storage are the costs.
  • Metadata through the servers, files through object storage and a CDN.
  • A presigned URL lets the client upload straight to storage, and parts make it resumable.
  • Commit to metadata in a database, blobs behind a CDN and uploads in parts, and watch egress.

Read first

  • Object Storage
  • Queues and Workers
  • Hot Keys
  • Data Modeling
  • The Design Interview

Practise it

  • File Sharing: Design Inkwell Drive: share big files with readers on three continents, with uploads that never touch the app servers.
About · Contact · Privacy · Terms of use