System Design · Architecture under constraints
How would you design a file storage service?
Short answer
Store file bytes in object storage and metadata in a database. Use presigned URLs for upload and download, chunk large files, and handle permissions, deduplication, versioning and consistency explicitly.
Assume users upload files up to several gigabytes, download them with access control, share links, and expect durability. The service should not proxy every byte through the application tier. Separate the control plane, which manages metadata and permissions, from the data plane, which moves bytes.
Architecture
- Object storage such as S3 for blobs, with erasure coding and cross-region replication
- Metadata database for file id, owner, size, content type, checksum, version and status
- Presigned upload URL so the client writes directly to object storage
- Presigned download URL with a short expiry, issued only after an authorization check
- Chunked or multipart upload for large files, with resumable parts
- Queue and workers for virus scanning, thumbnails and text extraction
The upload flow should be two-phase. First create a metadata record in a pending state and return a presigned URL. The client uploads directly, then calls a complete endpoint. The server verifies the object exists, checks its size and checksum, and marks it ready. A pending record that is never completed can be cleaned up by a sweeper.
Deduplication can be content-addressed: hash the bytes and store one blob per hash, with references counted in metadata. That saves space but requires care with deletion and access control, because two users may reference the same blob. Versioning keeps prior objects when a file is replaced, which is useful for sync and recovery but increases storage cost.
Permissions belong in the metadata layer, not in an unguessable URL. A signed URL is a bearer token for a limited time, so keep the expiry short and bind it to the intended operation. Object storage consistency is usually strong for new objects but listings and caches can lag, so the control plane should not rely on a list operation to confirm an upload.
Follow-ups you should expect
Interviewers use these to check whether the first answer was understanding or memorisation.
- 1Why use presigned URLs instead of proxying uploads through the API?
- 2How do you support resumable uploads for large files?
- 3How does content-addressed deduplication interact with deletion?
- 4What consistency issues arise between metadata and object storage?
Say it in the interview
I split the control plane from the data plane: metadata and permissions live in a database, while bytes go directly to object storage through presigned URLs. Uploads are two-phase, with a pending record and a completion check on size and checksum, and large files use multipart upload. Deduplication by content hash saves space but complicates deletion and access control. Signed URLs are short-lived bearer tokens, and cleanup of orphaned blobs is a separate idempotent process.
Use this as a model, not a script. Saying it in your own words is what makes it survive follow-up pressure.
Related questions
Reading is step one
Now say it out loud.
Understanding an answer and delivering it under pressure are different skills. Rehearse this topic in a live System Design mock interview and get scored feedback on depth, clarity and confidence.