Cloud file storage and sync inspired by Google Drive and Dropbox: metadata separated from content, chunked resumable uploads deduplicated by content hash, a change journal with per-device cursors for sync, background scanning, previews and search, and versioning. A teaching design.
See why storing files on a server's disk can't scale or survive failures.
What was missing: Nothing yet.
Why that's risky: Files live on one machine's disk, every download streams through the server, and a large upload that drops restarts from zero.
What gets added: One server that saves files to its own disk and keeps their names and folders in a database.
Trade-offs: Simple, but storage, bandwidth and metadata all share one machine.
Keep file bytes in object storage, metadata in a database, and serve downloads from the edge.
What was missing: Bytes and metadata lived together on one server.
Why that's risky: Uploads are single requests: a dropped connection on a 2 GB file starts over, and identical files are stored many times.
What gets added: Object storage for file content, a sharded metadata database for names, folders, owners and permissions, a file service that hands out short-lived signed URLs, and a CDN that serves downloads through them.
Trade-offs: Signed URLs expire in minutes, so a shared download link must be refreshed by the file service.
Make large uploads survive dropped connections and never store the same bytes twice.
What was missing: Uploads were all-or-nothing, and duplicates were stored repeatedly.
Why that's risky: Other devices don't learn about changes unless they re-list everything.
What gets added: An upload service that takes files in 8 MB chunks named by their SHA-256 hash, keeps an upload session so a dropped upload resumes, and lets the client skip chunks that already exist; plus a metadata cache for hot listings and permission checks.
Trade-offs: Content-addressed chunks make deduplication free but mean deleting a file can't delete chunks other files still use; garbage collection handles that later.
Keep every device up to date without polling.
What was missing: Devices had to re-list folders to find changes.
Why that's risky: Uploaded files aren't scanned for malware, have no previews, and can't be searched by content.
What gets added: A change journal per user and shared folder with a cursor per device, a durable file event log written with each change (outbox pattern), and a sync service that holds a connection to each device and sends a small 'something changed' signal so the device pulls only changes after its cursor.
Trade-offs: Devices pull changes after a signal instead of receiving them pushed, which keeps the notification tiny and the journal the single source of order.
Process every upload in the background and make files findable.
What was missing: No malware scanning, previews or content search.
Why that's risky: Old versions and trashed files are kept forever, and nothing limits abusive clients.
What gets added: Workers on the file event log that scan uploads in a sandbox, build thumbnails and previews, and index names and contents into a per-user search index served by a search service.
Trade-offs: Until a scan finishes, only the owner can open a new file.
Restore old versions, clean up storage, and protect and watch the service.
What was missing: No version history, no cleanup, no per-user limits, no monitoring.
Why that's risky: Remaining risk is regional: metadata and chunks are replicated to a second region for disaster recovery.
What gets added: A versioning service that restores old versions by pointing at their chunks, a trash and retention worker that deletes expired files and unreferenced chunks, an API gateway with per-user limits, and monitoring of upload success, sync lag and scan backlog.
Trade-offs: Keeping versions costs storage; retention policies cap it.
Split files into chunks (e.g. 5–10 MB each) and upload them in parallel or sequentially. Each chunk is written to blob storage independently. A resumable upload session tracks which chunks have been received so a failed upload can resume from the last successful chunk rather than starting over.
Use optimistic concurrency — tag each file version with an ETag or version number. On write, the client sends the version it last saw; the server rejects the write if the current version doesn't match, forcing the client to fetch the latest and re-apply its changes. For collaborative editing, operational transformation or CRDTs handle fine-grained conflict resolution.
After every write, publish a change event to a notification service (e.g. via Server-Sent Events or WebSocket). Each connected device listens for events matching its user ID and re-fetches the changed metadata on receiving one. Delta sync — sending only the changed bytes — reduces bandwidth compared to re-downloading the full file.
Compute a content hash (e.g. SHA-256) of every chunk before storing it. Before writing a chunk to blob storage, check if an identical hash already exists. If it does, store only a pointer to the existing chunk. This is content-addressable storage — the same bytes are stored once regardless of how many users have uploaded identical files.
Store permissions as an Access Control List (ACL) in the metadata database — each entry maps a (file_id, user_id/group_id) pair to a role (owner, editor, commenter, viewer). Cache hot ACLs in Redis. On every file operation, check the calling user's role. Link-based sharing generates a signed URL or a token that encodes the permission level and expiry.
Shard when the primary metadata DB can no longer handle write throughput or when the dataset no longer fits on a single node. Shard by user_id so all of a user's files live on the same shard — this keeps folder-listing queries local and avoids cross-shard joins. Add routing logic in the application layer to map user_id to the correct shard.
Object storage like S3 or GCS stores at least 3 copies of every object across different availability zones by default. Durability is typically 11 nines (99.999999999%). For extra protection, enable cross-region replication so a regional outage doesn't make data unavailable. Version history means deleted or overwritten files can be recovered within a retention window.
After a file is uploaded, a worker indexes its name, MIME type, owner, and extracted text (for documents) into a dedicated search index like Elasticsearch. Queries run against the index rather than the metadata database. The index is updated asynchronously so it doesn't block uploads. Shard the index by user_id or org_id to keep queries isolated.
You're in the middle of an interview session. Leaving now will end your current attempt.
Explore concept overviews, real-system examples, key tradeoffs, and interview talking points for each roadmap section.
You've conquered this phase. These are the skills you now own: