TSTier SlateAll templates

Video & media

File upload - the bytes never touch your server

How presigned URLs send uploads straight to object storage, and what the server still has to check afterwards.

  • System design
  • starter
  • 8 step walkthrough
  • 3 tables

Share

  • Facebook
  • X

What this board gets wrong on purpose

The tension

The presigned URL is a plain PUT with only the object key and Content-Type signed, so the storage does not enforce the size the client declared - a URL issued for a 2 MB avatar accepts a 5 GB upload, and you pay to store it until the worker notices. The content type is whatever the client claimed until the worker reads the file's magic bytes. Verification is driven by bucket events, which are at-least-once and can arrive seconds late, so the worker must be idempotent and the user sees "processing" for an unknown time. And an upload that is started and never finished leaves a pending row and, for multipart uploads, invisible parts that are billed forever - nothing on this board cleans them up except one lifecycle rule.

Practise this as an interview

Take File upload - the bytes never touch your server as a timed system design interview on a blank board - on your own, with the requirements to check yourself against, or with a candidate you invite.

Practise this as an interview

Start here

Why this design

Uploading a file sounds like a form field, and it is one of the most common places a design goes wrong at scale: app servers sized for bandwidth, workers tied up by slow phones, files served before anyone checked what they are. Interviewers ask it to see whether you know the presigned URL pattern, and - the better half of the answer - what that pattern stops the server from checking. The same design is behind profile photos, document uploads, chat attachments and video ingestion.

What you will learn

  • Why 2 million 2.5 MB uploads a day is ~1.4 Gbit/s at peak, and why that traffic should not pass through your app servers.
  • What a presigned URL is: a signed, expiring permission for one method on one object key.
  • Why the upload lands in a private "incoming" area and is only copied to the served bucket after it passes checks.
  • What the server must still check afterwards: real size, real type (magic bytes), malware, image dimensions, metadata like GPS in EXIF.
  • How to clean up uploads that never finish, and why multipart uploads are invisible until you abort them.

How to read this board

  1. GET A URL across the top: user, client app, the upload API hex.
  2. Then the long wire from the client straight to the red INCOMING bucket - the bytes going around your servers.
  3. CHECK IT AFTERWARDS across the middle: the bucket event queue, the verify worker hex and the malware scanner.
  4. SERVE across the bottom: the viewer and the CDN, which can only reach the checked bucket.
  5. STORAGE on the right: upload rows, incoming, files, and the lifecycle rule that cleans up.
  6. Press play, read pages 1 to 6, then the DATA MODEL. The conversation to have: list every check the server can no longer make on the way in, and where on this board each one moved.

1 · Requirements

Functional

  • A signed-in user uploads images (JPEG, PNG, WebP up to 10 MB) and documents (PDF up to 50 MB).
  • Show upload progress, and resume a large upload after a dropped connection.
  • After upload the file is checked, images get thumbnails (256 px and 1024 px), and the file becomes viewable by its link.
  • Reject files that are the wrong type, too big, or malicious - and tell the user.
  • The owner can delete a file; it stops being served.

Non-functional

  • App servers do not carry file bytes. Their capacity is sized for requests, not bandwidth.
  • No file is served to anyone until it has passed the checks.
  • An uploaded file is durable once the user sees "uploaded" (object storage: 11 nines).
  • Processing finishes within 30 seconds for 99 percent of images.
  • Storage costs are bounded: abandoned and rejected uploads are deleted within a day.

Out of scope

  • Video transcoding - the same front half, with a much bigger pipeline after it.
  • Collaborative editing of documents.
  • End-to-end encryption, where the server cannot check content at all.

The rest of this board

Board preview

Available on Tier Slate

This page publishes the question. The answer — 5 more written pages, an 8-step narrated walkthrough and a 3-table schema — is the board itself, and it opens in Tierslate.

  • 5written pages
  • 8walkthrough steps
  • 3tables23 columns

5 pages behind this one

  • Capacity estimation
  • Storage estimation
  • Availability
  • How it works
  • Deployment plan
Open this board in TierslateBrowse every board

More boards

Upload, transcode, deliver - and pay for the bandwidth.

  • Image CDN - resize on the fly, or store every size
  • Live streaming - latency against the buffer that saves you
  • Streaming playback - the bytes were already next to you
  • Transcoding pipeline - 480 tasks, one file
  • Video upload - one file in, seven encodes out
  • Music streaming - three minutes of audio, played a billion times
  • Short video feed - the next swipe is already downloading
  • Video calls - forwarding streams, not mixing them
All 100 templatesOpen Tierslate
Tierslate

tierslate.com

HomeTemplatesPrivacyTerms