How file uploads to S3 work
Large files should not pass through your server. Your server signs a short-lived upload link, the browser sends the file straight to S3, and your server only records that it arrived.
Direct upload with a presigned URL
Browser
Picks the file and shows progress
Your server
Checks the user and signs a URL
Browser
Uploads the file with the URL
S3 bucket
Stores the object
Why not upload through your server
A file passed through your server uses its bandwidth, memory and request time, and many hosts limit the request size. Sending the file straight to S3 removes that load and scales with the number of users, not the size of your server.
What the signature controls
The presigned URL is created with your credentials but contains only a signature. It can be limited to one object key, one method, a maximum size and a content type, and it expires after a few minutes. Keep the bucket private and let only these links write to it.
After the upload
Save the object key in your database only once the upload has succeeded, either from the browser's confirmation or from an S3 event. Scan or resize files in a background job that reacts to the new object.
Questions
What is a presigned URL?
A temporary link that carries permission to upload or download one specific object, signed with your credentials, so the holder needs no keys of their own.
How long should the link last?
Minutes, not hours. Long enough to start the upload, short enough that a leaked link is useless.
Can users upload anything with it?
Only what the signature allows. Set the allowed content type and maximum size when you sign, and validate again after the upload.
How do I upload very large files?
Use S3 multipart upload: your server signs a URL per part and the browser sends the parts in parallel and can resume.