Free full guide

Dropbox

Design Dropbox — a cloud file storage and synchronization service where users upload large files and keep them in sync across devices and shared folders.

00

Practice checkpoints

The interview rhythm stays compact, so the page can spend attention on the actual design decisions.

  1. 01
    Clarify scope
  2. 02
    Requirements + scale
  3. 03
    API + data model
  4. 04
    Draw architecture
  5. 05
    Deep dive
  6. 06
    Trade-off decision
01

Requirements that shape the design

Do not only state requirements. Ask for them. Each card pairs the design constraint with a clarification question you can say out loud before drawing the architecture.

Functional requirements

01How big can a single file get?

Users upload and download from any device, with files up to 50 GB.

02Is sync automatic, and what happens to offline edits?

Files sync automatically across all devices. Edits made offline get merged back in when the device reconnects. The server copy is the source of truth.

03What does sharing mean — a copy, or the same file?

Sharing gives access to the same file, not a copy. Recipients see it in their own view. Any update reaches everyone who has access.

04Are folders, moves, and renames file operations?

No. Folders are just metadata. Move and rename only change metadata and never touch the stored blocks, so they stay instant at any file size.

05Does sharing carry permissions - view-only vs edit?

Yes. Each share carries a role (viewer/editor), and the metadata service enforces it. Presigned URLs are limited to the role that asked for them.

06Do deletes sync, and can a user recover a deleted file?

Deletes sync like any other edit, using tombstones. Blocks sit in a trash window before they are reclaimed. A synced mistake needs a way to undo it.

Out of scopeIn-place collaborative editing (that is the collaborative document-editing question) · Preview and rendering without download · Version history UI (the data model keeps latest_version, but browsing history is out)

Non-functional requirements

01When the network partitions, what must keep working?

Availability over consistency: a stale file list for a few seconds is fine; failing an upload is not.

02What happens when a 50 GB upload dies at 49 GB?

It resumes from the last verified chunk — never restarts. Chunk status is tracked server-side, so any device can continue the upload.

03How do we know a file was not corrupted in transit?

Every chunk and the whole file carry SHA-256 fingerprints. A chunk is only marked uploaded after the storage layer confirms the bytes.

04Two users upload the same 2 GB video — do we store it twice?

No: identical fingerprints mean identical content — the metadata points both users at the same stored blocks.

05How fresh does cross-device sync need to be?

Seconds: online devices get pushed change notifications, with periodic polling as the safety net.

Keep asking — the interview is a conversation

Real interviews probe far more than a tidy list. These are the scope questions that separate candidates who interrogate the problem from those who recite it.

  • What is the max file size — megabytes or tens of gigabytes?
  • Is collaborative in-place editing in scope, or files-as-blobs only?
  • When two devices edit the same file offline, what should the user end up seeing?
  • Do we need version history, or just the latest version?
  • Should identical content uploaded by different users be stored once?
02

Numbers that force architecture decisions

Treat every estimate as a pressure that justifies a component: cache, queue, partition, replica, worker pool, or fallback path.

01

Chunks per big file

50 GB file ÷ 5 MB chunks50,000 MB ÷ 5 MB = 10,000 chunks

That is ten thousand uploads that run in parallel and can each resume on their own. This is why one giant POST can never work.

02

Resume cost after failure

Upload dies at 98%retry = the remaining ~200 chunks, not 10,000

Chunk-status tracking turns a catastrophic restart into a 2% top-up.

03

Dedup win

Same file uploaded by N users, fingerprint-matchedstorage cost = 1 copy + N metadata rows

Content-addressed storage makes the second and every later upload nearly free.

04

Edit one byte

Fixed-size chunking vs content-defined chunking (CDC)fixed: a 1-byte insert shifts every boundary → nearly all chunks re-upload · CDC: only the touched chunks

CDC (rolling hash) is what makes delta sync cheap for edited files.

05

Presigned URL window

URLs valid ~5 minutes, scoped to one chunkleak window = minutes · blast radius = one chunk

Short-lived, narrow-scope URLs are the security story for client-direct upload.

Decision example

The numbers

A 50 GB file is ten thousand 5 MB chunks. At that size the interesting problems are not storage — they are resume, dedup, and what happens when two devices edit the same file.

My choice

Clients chunk and fingerprint files locally, then upload the chunks in parallel straight to blob storage using short-lived presigned URLs. The API only handles metadata, and it verifies each chunk’s ETag before marking it done. Sync works by pushing a notification, then each device reconciles against a changes-since cursor. For conflicts, last write wins for the main copy. The losing edit is kept as a conflict copy next to it, so the user loses nothing and resolves it themselves.

Avoid

What I would NOT do: route file bytes through my API servers. They become a bandwidth bottleneck and an attack surface for zero benefit. And I would not silently drop the losing edit in a conflict. Pure last-write-wins is fine for a file LIST. But for file CONTENT, quietly throwing away someone’s afternoon of work is how you lose customers.

Change if

If in-place collaborative editing enters scope, blob-level sync is the wrong tool. That becomes operational transforms or CRDTs over the document structure. It is a different design, and a different interview question.

03

Architecture path

One complete picture first, then each path as its own diagram — the write path and the read path carry different traffic and justify different components.

Complete picture

Overview — every component

Client (SyncAgent)API / MetadataServiceMetadata DBBlob StorageCDNNotificationServicechange pushed to devicesChunk +FingerprintSHA-256 per chunkChunk Verify(ETags)trust but verify

File bytes flow client → blob storage directly (presigned URLs). Only metadata passes through the API. The notification service tells other devices to pull the changes cursor.

Path 1

Upload path — chunk, fingerprint, direct to blob

ClientChunk +FingerprintPresigned URLsBlob Storage(parallel)Metadata:complete

Dedup check first — a known fingerprint completes without uploading a byte. Chunks upload in parallel; the file flips to complete only after every chunk’s ETag verifies.

Path 2

Sync path — notify, then reconcile

Device A savesMetadata ServiceNotificationpushDevice B:changes cursorDownload via CDN

Push is the doorbell, the changes cursor is the truth: even a missed notification self-heals on the next poll.

04

API and data model

Before optimizing, make the contract inspectable: endpoints, entities, ownership, retries, and state.

POST/files/presigned-url

req{ name, size, fingerprint, chunk_fingerprints[] }

res200 { file_id, presigned_urls[] } · 200 { deduplicated: true } when the fingerprint already exists

The client uploads chunks straight to blob storage with these URLs — file bytes never pass through the API servers.

PATCH/files/{file_id}/chunks

req{ chunk_id, etag }

res200 chunk status

Trust but verify: the server accepts the client’s progress report, then confirms the ETag against blob storage before counting the chunk as uploaded.

GET/files/{file_id}/presigned-url

res200 { url } (CDN-signed, short expiry)

Downloads come from the CDN edge; short-lived signed URLs keep share links from becoming permanent public URLs.

GET/files/changes?since={cursor}

res200 [{ file_id, change, version }]

The sync backbone: push notifies “something changed”; this endpoint is the truth a device reconciles against.

Core entities

FileMetadata

file_id (PK) · name · size · fingerprint (SHA-256) · latest_version · status · chunks[] {id, fingerprint, status}

file_id (identity) is deliberately separate from fingerprint (content) — a rename changes neither the content nor the stored blocks.

SharedFiles

user_id (partition key) · file_id (sort key)

One row per user per shared file: "what can this user see" is a single-partition query.

Device

device_id (PK) · user_id · last_synced_at

Sync state is per device — each device pulls changes since its own cursor.

05

Deep dive directions

Pick one lane for the final third of the interview. Each lane gives you the topic, the interviewer question it should answer, and the failure mode to avoid.

Focus

The 50 GB upload

Ask

Walk the upload end to end: chunking, parallelism, what the server tracks, and what happens when it dies at 98%.

Answer

Split the file into chunks, upload them in parallel, and track per-chunk status server-side; a death at 98% resumes from the last verified chunk — on any device.

Avoid

One multipart POST and a retry-from-zero — at this size, resume IS the feature.

Focus

Same file, two uploaders

Ask

Two users upload an identical 2 GB video. What actually gets stored, and how does the system know?

Answer

Both uploads fingerprint to the same SHA-256, so the blocks are stored once and both users' metadata points at them; the second upload is just a metadata write.

Avoid

Deduping by filename or size — only content fingerprints (SHA-256) define identity.

Focus

Two devices edit offline

Ask

Laptop and phone both edited the same file offline. Both come online. What does the user end up with?

Answer

The first sync wins cleanly; the second device's version is kept as a conflict copy next to the file — the user resolves it, the system never silently discards an edit.

Avoid

Silently keeping only the last write — the losing edit must survive as a conflict copy.

Focus

Where do the bytes actually flow

Ask

What breaks if file bytes flow through the API servers, and what exactly do presigned URLs protect?

Answer

Bytes go client → blob storage directly, via short-lived chunk-scoped presigned URLs; the API only issues URLs and records metadata, so file traffic can never saturate it.

Avoid

Long-lived or file-wide presigned URLs — minutes of validity, one chunk of scope.

Focus

A tiny edit in a huge file

Ask

A user changes a few bytes in the middle of a 50 GB file. Do we re-upload everything — how do we sync only what changed?

Answer

Content-defined chunking: chunk boundaries come from the bytes themselves, so a small edit only changes the chunks it touches and sync re-uploads just those.

Avoid

Fixed-size chunking for edited files — inserting one byte shifts every later chunk boundary, so almost every chunk looks new and re-uploads.

Ready to practice?

Talk through Dropbox out loud and get AI scoring on the explanation.

Practice this with AI →