RailwayDocs

Uploading & Serving Files

Buckets are private, but you can still work with their files in a few ways. You can serve files straight from the bucket, proxy them through your backend, or upload files directly from clients or services.

Bucket egress is free. Service egress is not. If your service sends data to users or uploads files to a bucket, that traffic counts as service egress. The sections below explain these patterns and how to avoid unnecessary egress.

Presigned URLs

Presigned URLs are temporary URLs that grant access to individual objects in your bucket for a specific amount of time. They can be created with any S3 client library and can live for up to 90 days.

Files served through presigned URLs come directly from the bucket and incur no egress costs.

Serve files with presigned URLs

You can deliver files directly from your bucket by redirecting users to a presigned URL. This avoids egress costs from your service, as the service isn't serving the file itself.

Use-cases:

  • Delivering user-uploaded assets like profile pictures
  • Handing out temporary links for downloads
  • Serving large files without passing them through your service
  • Enforcing authorization before serving a file
  • Redirecting static URLs to presigned URLs

Serve files with a backend proxy

You can fetch a file in your backend and return it to the client. This gives you full control over headers, formatting, and any transformations. It does incur service egress, but it also lets you use CDN caching on your backend routes. Many frameworks support this pattern natively, especially for image optimization.

Use-cases:

  • Transforming or optimizing images (resizing, cropping, compressing)
  • Sanitizing files or validating metadata before returning them
  • Taking advantage of CDN caching for frequently accessed files
  • Web frameworks that already use a proxy for image optimization

Upload files with presigned URLs

You can generate a presigned URL that lets the client upload a file directly to the bucket, without handling the upload in your service. Doing so prevents service egress and reduces memory consumption.

Similar to handling uploads through your service, be mindful that users may try to upload HTML, JavaScript, or other executable files. Treat all uploads as untrusted. Consider validating or scanning the file after the upload completes, and remove anything that shouldn't be served.

Use-cases:

  • Uploading files from the browser
  • Mobile apps uploading content directly
  • Large file uploads where you want to avoid streaming through your service

Upload files from a service

A service can upload directly to the bucket using the S3 API. This will incur service egress.

Use-cases:

  • Background jobs generating files such as PDFs, exports, or thumbnails
  • Writing logs or analytics dumps to storage
  • Importing data from a third-party API and persisting it in the bucket