Design Dropbox — upload, download, share, and sync walkthrough

Design Dropbox

Junior-friendly Dropbox walkthrough: requirements, entities, APIs, presigned S3 upload/download, CDN, sharing, hybrid sync, multipart large files, CDC + compression, security, and what interviewers expect by level.

Understanding the problem

Dropbox is a cloud-based file storage service: users store and share files, and access them from any device. Designing the product is different from designing Blob Storage itself — blob design is related research, but out of scope for this question.

Laptop and phone syncing through cloud storage.
One folder, many devices — cloud is the source of truth.
01Upload

Presigned PUT to S3.

02Download

CDN signed URL.

03Share

ACL + short-lived link.

04Sync

Push + poll safety net.

Pair with Delivery framework, Handling large blobs, Caching, Realtime updates, and CAP theorem.

Functional requirements

Pin what users must be able to do before drawing boxes. Top 3–4 features — don't drown in editing or preview.

Non-functional requirements

Core entities

Start broad — columns come later. Align with the interviewer on these three:

File, FileMetadata, and User as core entities.
File = bytes · FileMetadata = name/size/ACL · User = owner/sharee.
  • File — raw bytes users upload/download/share.
  • FileMetadata — name, size, mime type, uploader, status, later chunks/fingerprint.
  • User — who owns or was shared a file.

API / system interface

Define one endpoint per functional requirement. Expect the upload/download APIs to evolve once you introduce presigned URLs — say that out loud.

POST /files
{ File, FileMetadata }

GET /files/{fileId} -> File & FileMetadata

POST /files/{fileId}/share
{ User[] }  // share with these users

GET /files/changes?since={timestamp} -> ChangeEvent[]
// ChangeEvent: fileId, type (created|updated|deleted), metadata

HLD — upload a file

Two questions: where do bytes live, and where does metadata live?

Metadata fits a document store (DynamoDB) or Postgres — few relations, query by user. Don't burn the interview on DB brand wars; either is fine. Schema sketch:

{
  "id": "123",
  "name": "file.txt",
  "size": 1000,
  "mimeType": "text/plain",
  "uploadedBy": "user1",
  "status": "uploading"
}

Approach 1 — store on the app server

Uploader through API Gateway to File Service storing on local filesystem and File Metadata DB.
Users should be able to upload a file from any device — naive: store on the File Service local disk.

Approach 2 — Blob Storage via the backend

Uploader through Gateway and File Service writing to S3 and File Metadata DB.
Store File in Blob Storage — File Service writes (1) bytes to S3 and (2) metadata to DB.

Handle partial failures carefully: only mark metadata complete when the blob is stored (or compensate). Still suboptimal bandwidth/cost.

Approach 3 — direct upload with presigned URLs (best)

Uploader gets presigned URL via Gateway and File Service, uploads directly to S3, S3 notifies Metadata DB.
Upload directly to S3 via pre-signed URL — File Service generates URL; S3 notification flips status.
  1. POST /files/presigned-url with FileMetadata → backend saves row with status: uploading, returns presigned PUT URL (signed locally with AWS creds — no S3 round-trip to generate).
  2. Client PUTs bytes straight to S3.
  3. S3 notification → backend sets status: uploaded.

HLD — download a file

Same anti-pattern as upload: proxying bytes through the File Service downloads twice. Prefer direct access.

  1. GET /files/{fileId}/presigned-url — ACL check, then return a short-lived download URL.
  2. Client fetches bytes from Blob Storage (or CDN) directly.
Uploader and Downloader with direct S3 upload and download via presigned URLs.
Users should be able to download a file from any device — download via presigned URL directly from S3.

Add a CDN for geo latency

Single-region S3 is slow for far users. Put a CDN (CloudFront) in front: first request may miss to S3; later hits serve from the nearest edge.

Downloader fetches from CDN which caches frequently accessed files from S3.
Cache frequently accessed files on the CDN — Downloader pulls from the edge, not the S3 region.

HLD — share a file

Google Drive–style: share by email/userId (assume users already exist). Keep it fast — ACL writes are small metadata ops.

Owner shares via File Service updating share table so sharee can download.
POST /files/{id}/share → update shareList / share table → enforce on download URL minting.
  • Store shares in the metadata DB (embedded list or separate share table).
  • Before issuing any download URL, verify requester is owner or sharee.
  • Optionally notify the sharee (email / push) — nice-to-have in interview.

HLD — sync across devices

Each device keeps a local copy; remote storage is source of truth. Two directions: local → remote and remote → local.

Uploader watches for changes; Downloader polls; full system with S3, CDN, Metadata and SharedFiles.
Sync — watch local changes and upload; poll remote and pull via CDN. Same spine as Final.

Local → remote

A sync agent watches the Dropbox folder (FSEvents / FileSystemWatcher), queues changes, uploads via the upload API, updates metadata. Conflicts: last write wins for this design. Versioning is below the line — in production you'd keep versions/chunks instead of overwriting the only object.

Remote → local

  • Polling — simple, wasteful if quiet, slow to detect.
  • WebSocket / SSE — one connection per device/session; server pushes ChangeEvents.
  • Hybrid (recommended) — push for near-real-time + poll every few minutes so dropped sockets don't lose updates.

Tying it together — final design

At this point all functional requirements have a path. Here's the whole system:

Final design: Uploader, Downloader, API Gateway, File Service, S3, File Metadata DB with SharedFiles, CDN.
Final — File Service signs URLs; bytes go client ↔ S3/CDN; SharedFiles enforces ACL.
  • Uploader / Downloader — same client app, drawn separately for clarity; also runs the sync agent.
  • LB & API Gateway — SSL, rate limits, routing.
  • File Service — metadata R/W + cryptographic signing of URLs (local op with AWS keys).
  • Metadata DB — files + share mappings for ACL.
  • S3 — durable blob store.
  • CDN — edge cache for downloads.

Deep dive — support large files (50GB)

UX goals: progress and resumable uploads. A single 50GB POST fails timeouts, payload limits (API Gateway ~10MB), and network drops — and leaves the user staring at a spinner.

Chunk on the client (5–10MB typical) — never "chunk on the server" after uploading the whole file once. That defeats the purpose.

Uploader chunks and fingerprints on client; uploads chunks via presigned URL to S3; metadata tracks chunks array.
How can you support large files? — chunk + fingerprint on client; upload parts via pre-signed URL; chunks[] in FileMetadata.
{
  "id": "123",
  "name": "big.bin",
  "status": "uploading",
  "fingerprint": "sha256:…",
  "chunks": [
    { "id": "1", "status": "uploaded" },
    { "id": "2", "status": "uploading" },
    { "id": "3", "status": "not-uploaded" }
  ]
}
  1. Client fingerprints whole file + each chunk (SHA-256) — resume/dedup by content, not filename.
  2. If same fingerprint exists with uploading, resume missing chunks.
  3. Else: backend CreateMultipartUpload, store metadata, return uploadId + per-part presigned URLs.
  4. Client uploads parts; after each, PATCH status + ETag; backend can verify via ListParts.
  5. When all chunks uploaded → CompleteMultipartUpload → mark file uploaded.

Downloads don't need the original chunk map: after complete, it's one object. Use HTTP Range for parallel/resumable downloads.

Deep dive — make upload, download, and sync fast

CDN parallel chunks, content-defined chunking, and client compression.
CDN · parallel/adaptive chunks · CDC for delta sync · smart compression.
  • CDN — downloads from nearest edge.
  • Parallel chunk uploads — fill the pipe; adapt chunk size to network.
  • Delta sync — only changed chunks. Fixed-size chunks break on mid-file inserts (every later fingerprint shifts). Use Content-Defined Chunking (CDC) with a rolling hash (Rabin) so small edits only touch nearby chunks — how Dropbox-like systems actually sync.
  • Compression on the client before upload (zstd / brotli / gzip). Skip already-compressed media. Compress before encrypt — ciphertext doesn't compress.

Deep dive — file security

TLS, encryption at rest, ACL, and short-lived signed URLs.
Transit · rest · ACL · short-lived signed URLs (bearer tokens).
  • Encryption in transit — HTTPS.
  • Encryption at rest — S3 SSE / KMS.
  • Access control — share table checked before minting download URLs.
  • Signed URLs — short TTL (e.g. 5 min). Anyone with the URL can download until expiry — TTL limits leak blast radius; stricter options: IP binding or cookie+URL combo.
  • CDN (CloudFront) validates signature with registered public key + expiry before serving.

Cost and performance levers

What interviewers expect by level

Dropbox is a classic "product design" system question — bar rises with how much of the deep dive you own unprompted.

Architecture by level

Three progressive sketches — beginner spine, mid optimizations, pro production depth. Use the matching diagram in the interview; say the tradeoff out loud.

Beginner Dropbox: File Service with S3 and metadata DB.
Beginner architecture

Pros: Clear split of bytes (object store) vs metadata (DB) — the core insight interviewers want first. Cons: Piping every byte through app servers won't scale; no CDN or chunking means large-file uploads time out in the real world.

Mid Dropbox: signed URLs, CDN, and multipart upload.
Mid architecture

Pros: Signed URLs keep bandwidth off your fleet; CDN speeds downloads; multipart handles GB files. Cons: Signed URL expiry / ACL bugs become a security surface; multipart state machines add failure modes you must name (orphan parts, resume).

Pro Dropbox: sync, SharedFiles ACL, CDN and S3.
Pro architecture

Pros: Sync + CDC/notifications and SharedFiles ACL match real Dropbox product depth; threat model for signed URLs shows staff judgment. Cons: Sync reliability and conflict resolution can eat the whole interview — pick 1–2 deep dives or you never finish the spine.

Sketch of upload via presigned S3, download via CDN, and sync notification paths for interview Q&A.
The three paths every level below is graded against — upload, download, and the sync notification handshake.
Interview takeaway

Mid: solid spine + coachable on blobs. Senior: own large-file deep dive. Staff+: anticipate failures and name trade-offs like you've shipped them.

Wrapping up

Dropbox teaches separating control plane from data plane: metadata + signed URLs on your servers, durable bytes on blob storage, CDN for reads, multipart for 50GB, and hybrid push/poll for sync — with AP-friendly lag between regions.

Related: Delivery framework · Handling large blobs · Design Yelp · Design Instagram · Long-running tasks · Caching · Realtime updates · CAP · Common patterns.

← Lattice