0PricingLogin
NestJS Enterprise Backend APIs · Lesson

Direct-to-S3 Uploads with Presigned URLs

Offload heavy uploads to object storage by issuing short-lived presigned URLs from the API.

Why Not Proxy Uploads Through the API?

When a client uploads a large file, the naive design sends the bytes to your NestJS API, which then forwards them to object storage. This makes your server a bottleneck.

  • Memory & CPU pressure — every upload occupies a request thread and buffers/streams through your process.
  • Doubled bandwidth — bytes travel client → API → S3, so you pay for the same data twice.
  • Request timeouts — load balancers (e.g. ALB, Nginx) cap request duration; multi-GB uploads stall.

The fix: let the browser upload directly to S3. Your API only issues a short-lived, signed URL that grants permission for one specific operation.

What Is a Presigned URL?

A presigned URL is a normal S3 object URL with extra query parameters that encode a temporary, cryptographically-signed grant. Anyone holding the URL can perform exactly one operation (e.g. PutObject) on exactly one key, until it expires.

  • Signed with your AWS credentials, but the credentials are never exposed — only the signature is.
  • Scoped to a single HTTP method, bucket, and object key.
  • Has a hard expiry (seconds), after which S3 rejects it with 403.

Because S3 validates the signature itself, your API does not touch the file bytes at all.

All lessons in this course

  1. Multipart Uploads with Multer Interceptors
  2. Streaming Large Responses with StreamableFile
  3. Direct-to-S3 Uploads with Presigned URLs
  4. Image Processing Pipelines with Sharp
← Back to NestJS Enterprise Backend APIs