Skip to content

Lesson 7 of 9 · 18m

Blob Storage: Files at Scale

Object storage, presigned URLs, CDN integration, and the patterns that keep file uploads out of your app server.

File uploads kill web servers — a 100MB upload holds a connection for seconds, eats memory, and ties up a worker. The fix is the pattern every large system uses: the app never touches the file; it orchestrates.

Presigned URLs: the upload handshake

# 1. client asks for an upload slot
POST /uploads → { upload_url: "https://s3.amazonaws.com/...", file_id }
# 2. client PUTs the file directly to S3
PUT upload_url, body=file_contents
# 3. app records metadata when the upload completes
POST /uploads/{file_id}/complete → { file_size, checksum }

The app server signs a URL that authorizes one upload to one object key for a short TTL — the client talks to the storage service directly. S3, GCS, MinIO all support this; the pattern is the same. The app never sees the bytes.

Object storage properties that matter

  • Durability — S3's 11 nines means objects survive multiple datacenter failures; the SLA on your app server is nowhere near that.
  • Immutability — versioned objects can't be overwritten (helps with compliance and accidental deletes).
  • Metadata — store the reference (key, size, checksum, mime) in the DB; the object itself lives in storage. The checksum is how you detect corruption.

CDN for delivery

Don't serve files from the app — a CDN (CloudFront, Cloudflare) caches at edge points near users, reduces latency, and absorbs traffic spikes. Signed URLs give the CDN private access; Cache-Control headers tell it what to cache.

Field notes

  • An upload that isn't completed is a leaked object — a lifecycle rule (AbortIncompleteMultipartUpload) cleans partial uploads; a cron cleans orphaned keys.
  • The metadata DB row is the source of truth for "does this file exist" — the object store is the source of truth for the bytes. Keep them consistent with a cleanup job.