See It Flow
System Design · Interview · ~18 min read

File Storage & Sync: Interview Perspective

How to approach 'Design Dropbox / Google Drive' in a system design interview — from opening moves to final architecture, plus a full bank of realistic follow-up questions across scope, upload, metadata, synchronization, delta sync, conflicts, sharing, scaling, versioning/GC, CDN/download, and failure curveballs.

Mangesh MandlikLast updated:
Interview 01

Opening Move

Start by clarifying the scope. 'Design Dropbox' is broad — the interviewer wants to see you narrow it to the most important problems.

Say something like: 'File storage and sync has several distinct challenges — reliable upload of large files, durable storage, multi-device synchronization, and access control. I'll start with requirements and scale, then build the architecture from first principles, starting simple and evolving as we hit bottlenecks. Should I focus on any particular area?'

Interview 02

Requirements & Scale

Spend 2–3 minutes on requirements. This is where you demonstrate that you think about the problem before jumping to solutions.

Functional requirements to state

Upload files (including very large files, resumably). Download from any device. Sync changes across devices automatically, including offline edits and conflicts. Share files with access control. File versioning and restore. Folder hierarchy and operations.

Non-functional requirements to state

High durability with an appropriate recovery/backup strategy (avoid promising an absolute 'never lost'). High availability. Efficient bandwidth (sync only what changed, where practical). Secure access on every operation. Bounded sync freshness rather than instant.

Scale to estimate

~500M users, 100M DAU. ~200M uploads/day. Average file 5 MB, up to 50 GB. ~1 PB new data/day. 5:1 read-to-write ratio. 100M devices syncing. State these as illustrative assumptions that drive the design, not as facts about any real product.

Interview 03

API Before Architecture

Define the key APIs before drawing boxes. This shows the interviewer you think about the system from the client's perspective.

The essential endpoints: POST /files (create record, get upload URL, idempotency-key protected), PUT /files/{id}/upload (initiate upload → presigned URL / multipart session), POST /files/{id}/complete (finalize upload, idempotent), GET /files/{id} (metadata), GET /files/{id}/download (auth → presigned download URL), PATCH /files/{id} (rename/move with a version precondition), GET /sync/changes?cursor=... (durable delta since last checkpoint).

Interview 04

Building the Architecture

Start simple. Show the bottleneck. Then introduce the right component — and be precise about why, not just what.

Start simple

Draw: User → File API → Database + Local Storage. Say: 'This works for small files and a few users. Let me show where it breaks — and be specific about the actual bottlenecks, not just a vague CPU number.'

Introduce metadata/storage separation

Say: 'File bytes and metadata are different workloads. Object storage is purpose-built for large binary blobs at this scale — durable, cheap per GB, independently scalable. The database stores queryable metadata. For this workload and scale, storing multi-GB blobs in a relational database isn't a good fit — though it can be a reasonable choice for small files in other systems.'

Introduce direct upload

Say: 'The application server should orchestrate, not proxy bytes, in the normal large-file path. The client calls the File Service for a presigned URL, then uploads directly to object storage. This removes byte-proxying load from the application tier — I won't quote an exact CPU number, but the mechanism is what matters: bandwidth and connection pressure move off the app tier.'

Introduce chunked upload

Say: 'A 10 GB file as one PUT still fails completely on a network drop. With chunked upload, each chunk — sized based on provider limits, network conditions and file size, not a fixed universal number — has its own presigned URL and acknowledgment. If one chunk fails, only that chunk retries.'

Interview 05

Important Deep Dives

The interviewer will pick one area to go deep. Be ready for any of these.

Upload flow deep dive

Walk through the full flow: POST /files creates metadata (CREATED) → upload initiation returns presigned URL(s)/session → client uploads directly to object storage → completion call verifies integrity and only then flips lifecycle state to AVAILABLE. Mention session expiration, orphan cleanup, and that completion must be idempotent. Read deeper: Architecture Deep Dive → Multipart Upload State Machine and Metadata/Object Consistency.

Sync deep dive

Explain local change discovery (filesystem watch + periodic reconciliation), remote change discovery via a durable cursor-based change log (push is just a hint), the sync client's own local state machine, and delta transfer as a distinct algorithm from whole-file hashing. Mention offline queuing and cursor-retention fallback to full resync. Read deeper: Architecture Deep Dive → Sync Client State Machine, Sync Change Log & Cursor Semantics, Delta Sync Algorithms.

Conflict resolution deep dive

Explain the parent-version model: every version records its parent; the server accepts a mutation only if its declared base version is still current. Two versions with the same parent = conflict. Default: preserve both as conflict copies. Alternatives: last-write-wins (simple but lossy), three-way merge (works for text, not binary, and is a product-policy choice). Read deeper: Architecture Deep Dive → Conflict Detection and Optimistic Concurrency.

Access control deep dive

Auth service checks ACL on every file operation. Presigned URLs are only generated after authorization passes, and are treated as bearer capabilities, not identity-bound credentials — revoking access does not retroactively invalidate an already-issued URL. Folder sharing introduces inherited permissions. Read deeper: Architecture Deep Dive → Sharing, ACLs and Revocation.

Interview 06

Full Question & Follow-Up Bank

Scope & Requirements

Are we designing storage only, or storage plus multi-device sync?

Strong answer angle

Clarify scope explicitly — sync, conflict resolution, and offline handling are a substantially different (and larger) problem than upload/download/storage alone. State which you're covering and why, rather than assuming.

Likely follow-ups
  • What's the maximum file size we need to support? — Drives chunking strategy and part-count/size trade-offs — see Trade-offs & Decisions → Chunk/Part Size Selection.
  • Do we need offline editing? — If yes, the sync client state machine and conflict handling become first-class, not optional — see Architecture Deep Dive → Sync Client State Machine.

Do we need a multi-region requirement, or is single-region acceptable for this design?

Strong answer angle

Push back on scope creep toward active-active global metadata unless the interviewer specifically asks for it — a bounded single-region-primary-with-DR-failover story is defensible for a foundations design.

Likely follow-ups
  • What availability vs durability trade-off matters more here? — These are different properties — durability is about not losing data, availability is about being reachable; see Architecture Deep Dive → Disaster Recovery and Multi-Region.

File Upload

Why direct-to-object-storage instead of proxying through the application?

Strong answer angle

At scale, proxying bytes through the application tier consumes bandwidth, holds long-lived connections, and couples data-transfer availability to control-plane availability. Direct upload via a presigned URL keeps the application tier lightweight — orchestration and authorization only.

Likely follow-ups
  • How do presigned URLs actually work? — See Architecture Deep Dive → Presigned URL Security — emphasize bearer-capability semantics, not 'non-transferable.'
  • What if the URL expires mid-upload? — See Failure & Scale → Presigned URL Expiry — differentiate URL expiry, session expiry, and credential/policy changes.

How do you resume a 50 GB upload that failed at 90%?

Strong answer angle

Chunked/multipart upload with a durable session: the client (or service, where supported) reconciles which parts are actually confirmed in storage, then uploads only the missing parts before an idempotent completion call.

Likely follow-ups

How do you verify upload integrity end-to-end?

Strong answer angle

Distinguish transport (TLS), per-part checksum, whole-object checksum, and application content hash. The completion step should verify the assembled object against an expected checksum before marking it AVAILABLE.

Likely follow-ups
  • Is ETag always a reliable integrity checksum? — No — ETag semantics vary by provider, encryption mode, and multipart behavior; don't assume ETag == MD5. See Architecture Deep Dive → End-to-End Data Integrity.

Metadata vs Bytes

Why separate metadata from file bytes instead of storing everything in one system?

Strong answer angle

They're different workloads: metadata needs queryable, relational, frequently-updated small records; bytes need durable, cheap, large-object storage with independent scaling. For this design's scale, this separation is the foundational decision — but note it's a workload-driven choice, not a claim that databases can never store any blobs.

Likely follow-ups
  • How do you keep the two systems consistent? — There's no ordinary atomic transaction spanning both — see Architecture Deep Dive → Metadata/Object Consistency for the verify-then-publish state machine.

Why use a stable file_id instead of the file's path as its identity?

Strong answer angle

Rename and move are extremely common operations; if identity were the path, every rename would be an identity change. A stable file_id lets rename/move be cheap metadata mutations, and lets sync clients recognize 'same file, new name' instead of treating it as delete-plus-create.

Likely follow-ups
  • How does that affect folder listing and uniqueness? — See Architecture Deep Dive → Metadata Model, Namespace & Folder Hierarchy — listing by parent_folder_id, optional (parent_folder_id, normalized_name) uniqueness.

Synchronization

How does a device detect that it made a local change?

Strong answer angle

A filesystem watcher (inotify/FSEvents/ReadDirectoryChanges-style) plus a periodic full reconciliation scan as a safety net against missed events.

How does a device discover changes made on other devices?

Strong answer angle

It calls a durable, cursor-based change endpoint. Push notifications are only a wake-up hint that something changed — the durable change log, not the push payload, is the source of truth.

Likely follow-ups
  • Why use a cursor instead of a timestamp? — Avoids clock-skew bugs between devices and the server; a cursor represents 'all changes up to X have been processed.'
  • What if the device missed the push notification entirely? — See Failure & Scale → Sync Notification Service Down — reconnect/periodic polling catches up regardless.

What happens if a device is offline for months?

Strong answer angle

If it's offline longer than the server retains change history, incremental cursor replay is no longer possible. The fallback is a full metadata snapshot, comparison against local state, reconciliation of any pending local operations, and establishing a fresh cursor.

Likely follow-ups
  • How do you handle duplicate or out-of-order sync events? — Operation IDs and version checks make replay idempotent and order-safe — see Architecture Deep Dive → Ordering and Idempotency.

Delta Sync

Does a whole-file hash tell you which bytes changed?

Strong answer angle

No. It only tells you that content changed. Identifying which bytes changed requires block-level signatures or a content-defined-chunking/rolling-checksum approach.

Likely follow-ups
  • When is delta sync not worth it? — Compressed, encrypted, or otherwise binary-dense formats can have a small logical edit that changes much of the byte representation — whole-file replacement may be simpler and equally effective.

Compare whole-file replacement, fixed blocks, and rolling/content-defined chunking.

Strong answer angle

Whole-file is simplest and best for small/incompressible-delta files. Fixed blocks are simple but broken by insertions shifting subsequent boundaries. Rolling checksums (rsync-style) find matching regions despite shifted offsets, at the cost of CPU and chunk-index metadata.

Conflict Resolution

Two devices edit the same file offline — what happens when both reconnect?

Strong answer angle

Both submit a mutation based on the same parent version. The server detects the version fork (not by timestamp) and, by default, preserves both as conflict copies rather than silently picking a winner.

Likely follow-ups
  • Why not just use timestamps / last-write-wins? — Clock skew between devices makes timestamp-based ordering unreliable, and last-write-wins silently discards one side's work — that's a product policy choice, not a distributed-systems requirement.
  • When is three-way merge possible? — For mergeable text formats using the common ancestor version — not for binary files, and not a substitute for real-time collaborative editing (CRDT/OT), which is out of scope here.

What if one device deletes a file while another edits it offline?

Strong answer angle

This is a delete/edit race. Tombstone (soft-delete) semantics let the reconnecting device learn the file was deleted rather than silently re-uploading its edit as a brand-new file. Product policy then decides: restore as conflict copy, reject as stale, or create a recovered file.

Sharing & Security

How do you enforce viewer vs editor access?

Strong answer angle

An ACL check on every file operation, backed by a permissions table recording owner, direct shares, and folder-inherited permissions with defined override rules.

What if an ACL is revoked after a signed download URL was already issued?

Strong answer angle

The already-issued URL remains usable until it expires — revocation is not retroactive for a plain bearer-capability URL. Mitigate with short TTLs, and use a stricter token-validation/proxy path only if instant revocation is a hard requirement.

Likely follow-ups
  • Can a signed URL be shared/forwarded by the recipient? — Generally yes — treat it as a bearer capability unless the design adds an explicit additional binding mechanism. Don't claim it's non-transferable.

Should authorization fail open or fail closed when current permission state can't be determined?

Strong answer angle

Fail closed. Serving a stale cached 'allowed' answer during a metadata outage risks honoring a permission that has since been revoked.

Metadata Scaling

SQL or NoSQL for metadata, and why?

Strong answer angle

Either can work; avoid caricatures like 'NoSQL means no joins' or 'SQL means vertical-only.' Compare on transaction model, access patterns, secondary-index support, consistency needs for ACL enforcement, and sharing-query shape. A relational store is a reasonable illustrative choice given this design's join-heavy sharing queries.

How would you shard the metadata store, and what breaks for 'files shared with me'?

Strong answer angle

Owner/user sharding gives good 'my files' locality but a large tenant can become a hot shard, and cross-owner sharing queries need a secondary recipient-oriented index rather than scanning every shard.

Likely follow-ups
  • How do you handle a hugely oversized tenant or a huge shared folder? — Paginated listings, asynchronous fan-out, and per-tenant fairness limits — see Failure & Scale Scenarios → Hot User / Huge Shared Folder.

Versioning, Deletion & GC

How do you store and retain file versions?

Strong answer angle

One immutable object per committed version; current metadata points to the current version. Retention (keep-all, time/count/quota-based) is a separate policy layered on top — don't conflate the application's version concept with a storage provider's native object versioning feature.

How do you clean up orphaned uploads and prevent GC from deleting referenced data?

Strong answer angle

Never delete a blob solely because one transient metadata lookup says it's unreferenced. Use soft-delete with a grace period, idempotent GC jobs, and periodic audit/reconciliation — GC bugs here are one of the few failure modes that can cause genuine permanent data loss.

CDN & Download

Should private files be served through a CDN?

Strong answer angle

It's workload-dependent — public/shared immutable content benefits most from caching; private/high-cardinality files may see little reuse. If private content is CDN-delivered at all, it needs its own signed-URL/cookie authorization design at the edge — an ordinary object-storage presigned URL doesn't automatically become CDN-backed.

Likely follow-ups
  • How do immutable/versioned object keys help? — A new version gets a new key/URL, sidestepping most cache-invalidation problems instead of relying solely on purging a mutable URL.

How do you support resumable downloads of large files?

Strong answer angle

HTTP range requests — resume from the last received byte, fetch partial ranges, or support streaming/preview without downloading the whole object first.

Failure Curveballs

What if object storage is temporarily down?

Strong answer angle

Bounded retry with backoff/jitter; metadata browsing can remain available; in-progress multipart uploads need explicit reconciliation on recovery, not an assumption of automatic resume.

What if the metadata primary goes down?

Strong answer angle

Fail closed for authorization-sensitive operations; don't rely on an in-memory application write queue as a durable recovery mechanism; failover time is deployment-specific, not a fixed number.

What if the upload completes in storage but the metadata commit fails?

Strong answer angle

This is the central metadata/object consistency failure. Idempotent completion plus a reconciliation job that verifies storage state and safely commits AVAILABLE (or garbage-collects a truly orphaned object after a grace period) is the answer.

What if the sync push/notification service goes down?

Strong answer angle

Push is an optimization, not the source of truth — clients fall back to cursor-based polling on reconnect and still catch up, just with higher latency.

Interview 07

What Makes a Strong Answer

The difference between a good and great answer is not the final architecture — it's the reasoning that builds it.

Key takeaways
  • Lead with requirements and scale — show you think before you draw, and label assumptions as illustrative
  • Define APIs before internal architecture — think from the client's perspective, including idempotency and version preconditions
  • Build from simple to complex — each component solves a visible problem, without inventing precision such as fixed CPU percentages or universal chunk sizes
  • Separate file bytes from metadata — different workloads, different tools, with an explicit consistency-reconciliation story between them
  • The application orchestrates — it never proxies large file bytes in the normal path
  • Presigned URLs are bearer capabilities, not non-transferable, identity-bound credentials
  • Sync uses a durable cursor-based change log as truth, with push as a hint and delta transfer as a distinct algorithm from whole-file hashing
  • Conflicts are detected by version lineage — not timestamps
  • Every trade-off has alternatives — explain why you chose yours and state its limits instead of claiming universal guarantees