Guide Spring Boot Cloud Storage

Upload files to Amazon S3 with Spring Boot

March 29, 2026 9 min read

A Spring Boot S3 upload flow needs more than an SDK call. Define validation, object keys, metadata, authorization, failure handling, and the boundary between application APIs and Amazon S3 before choosing direct or server-mediated uploads.

Recommended upload architecture

The best way to upload files to AWS S3 using Spring Boot is to separate storage logic into a dedicated service layer and use pre-signed URLs for direct uploads. This approach improves scalability, security, and keeps your backend architecture clean.

Many implementations directly connect controllers to S3 upload logic. This works for simple cases, but quickly becomes hard to maintain when adding validation, security, and metadata handling.

A better approach is to design a clear architecture where storage concerns are separated from application logic.

Amazon S3 is widely used for file storage in backend systems because it provides highly scalable, durable, and cost-efficient object storage without managing infrastructure.

Why use AWS S3 for file storage

S3 provides scalable and durable storage without managing physical infrastructure.

  • handles large files and high traffic
  • integrates easily with backend systems
  • supports secure access control

When to use S3 vs local storage

S3 is ideal for production systems where scalability and reliability matter. Local storage can work for development or small applications but becomes difficult to manage as traffic grows.

  • use S3 for scalable and distributed systems
  • use local storage for quick prototypes or internal tools
  • avoid local storage in multi-instance deployments

High-level architecture

A clean file upload system should separate responsibilities across layers.

  • controller handles incoming requests
  • service processes file logic
  • storage layer interacts with S3
  • database stores file metadata

Designing file metadata storage

Storing file metadata in a database helps manage files efficiently and enables features like search, access control, and auditing.

  • file name and unique identifier
  • s3 object key
  • file size and type
  • upload timestamp
  • owner or user reference

Example API design

A typical file upload API in Spring Boot follows a simple structure.

  • POST /files → upload file
  • GET /files/{id} → fetch metadata
  • GET /files/{id}/url → get access URL

Upload flow

  • client sends file to upload endpoint
  • server validates file
  • file is uploaded to S3 bucket
  • file metadata is stored in database
  • response returns file reference or URL

Keep storage logic abstract

Do not tightly couple your application with S3-specific code.

  • define a storage interface
  • implement S3-specific logic separately
  • allow switching storage providers if needed

Security considerations

  • validate file type and size
  • use IAM roles or access keys securely
  • avoid exposing S3 bucket directly
  • use pre-signed URLs for controlled access

Using pre-signed URLs for uploads

Instead of sending files through your backend, you can generate pre-signed URLs that allow clients to upload directly to S3. This reduces server load and improves scalability.

  • backend generates a temporary upload URL
  • client uploads file directly to S3
  • backend stores metadata after upload

If you want a ready-to-use implementation, check the file upload boilerplate .

Common mistakes to avoid

  • direct S3 calls from controllers
  • hardcoding credentials in code
  • no metadata tracking
  • no separation between upload and access logic

Verify

Use the smallest safe test that exercises the implementation described above.

  • Upload a small disposable file through the application flow after configuring the intended S3 bucket and credentials.
  • Confirm the object exists under the generated key and, when the design persists metadata, that the metadata points to the same object.
  • Retrieve the object through the application's authorized access flow.

Expected result

  • ✓ The application stores the object in the configured bucket rather than on the application filesystem.
  • ✓ The object key and any persisted metadata remain consistent.
  • ✓ Authorized retrieval returns the uploaded content while the bucket remains private.

Continue learning