Back to Blog
Why Icefiery

Why Rolling Your Own S3-Based Image System Is a Bad Idea

Building your image infrastructure on top of Amazon S3 seems simple at first, but leads to hidden costs, complexity, and dev-prod inconsistency. Here's a breakdown of why it's usually not worth it.

June 8, 2025
8 min read
by Martti Laine

Amazon S3 is often the default choice when teams need to store and serve images. It's widely available, integrates with other AWS services, and appears cost-effective at first glance. But once you move past basic file storage, building a production-grade image system on top of S3 introduces significant complexity and ongoing maintenance burden.

This post outlines the common pitfalls of S3-based image pipelines and compares them to purpose-built alternatives.


1. S3 is just storage, not an image system

S3 is an object store.

It does not provide any image-specific functionality, like URL-based transforms or CDN delivery, out of the box.

Developers must build or bolt on additional components (e.g. CloudFront CDN) to meet these common image infrastructure requirements.


2. No Support for Temporary Uploads

With S3 you have 2 options when uploading an image:

  • Upload to a bucket and keep it there until manually deleted
  • Upload to a bucket (or path within a bucket) with a lifecycle rule that expires the file after a certain amount of time

A common need for image uploads is to have the client upload an image to the cloud before it has been associated with a user or other entity.

For example, in a chat app, users can upload images before they send the message.

But if the user never sends the message, those images remain "orphaned" in object storage forever, unless you keep track of them and manually delete them.

In S3 you can utilize a lifecycle rule to help with this. Only upload images initially to a lifecycled bucket/path…

But then you need to move the image from the temporary location to a permanent location when the user sends the message.

So you'll need to implement either:

  • A lambda/cronjob which cleans up orphaned images
  • Application logic to move an uploaded image from temporary to permanent location

3. Metadata Is Immutable

S3 object metadata cannot be modified after upload.

If you need to update image metadata (e.g. related user ID, account ID, etc.), you have the following options:

  • Re-upload the image with updated metadata and update references to it
  • Maintain a separate metadata database

Additionally, there is no native way to query images by metadata fields. Granted, your metadata-based queries should probably live in a dedicated database anyway.


4. No Built-in Image Transformations

S3 does not offer any built-in image transformation capabilities. Features such as:

  • Resizing
  • Format conversion (e.g. PNG to WebP)
  • Cropping
  • Quality optimization

Meaning, these must be handled through separate tools such as CloudFront CDN in front of the bucket.

Or… building custom using something like AWS Lambda with ImageMagick or Sharp. But surely reinventing this wheel is not what you want to spend development time on.


5. No Native CDN Behavior

On a related note… to serve images globally with caching, CloudFront must be configured.

This setup includes:

  • Defining cache behaviors and origin policies
  • Managing signed URLs if access control is needed
  • Manual cache invalidation when images are updated

Sounds simple, but it can be a surprising amount of work to get right.


6. Access Control Is Overly Complex

S3's access model is IAM-based. Implementing project-scoped access is not as straightforwad as with simple API keys.

Additionally, for client-facing public upload URLs, generating presigned URLs is required.


7. Unpredictable Costs

While S3 storage is inexpensive and scales linearly with usage, costs can easily balloon due to egress costs (granted, there is a generous free tier).


8. Comparison: S3-Based Stack vs Icefiery

FeatureS3-Based StackIcefiery
Temporary UploadsRequires custom cleanup logicBuilt-in auto-expiry (24h default)
Metadata EditingNot supportedEditable via API
Image TransformationsRequires external tools (e.g. Lambda or external CDN product)Built-in via CDN URL params
CDN SetupRequires manual CloudFront configBuilt-in, zero-config CDN
Local DevelopmentPossible with e.g. MinIOFully runnable with Docker
Access ControlIAM or signed URLsProject-scoped API keys
Cost ModelMultiple variables (storage, egress)Simple monthly subscription
Dev ExperienceMulti-step, fragmentedSimple upload → transform → serve pipeline

9. Conclusion

Developers generally default to "let's use S3" when they need to store images.

But it actually gets quite a bit more complicated than that.

Most of what a modern app needs, i.e. temporary uploads, image transformations, metadata editing, CDN delivery, scoped access and local development, are not natively supported by S3. These features must be added manually.

If your team is building software, not image CDN infrastructure, consider using a dedicated image CDN like Icefiery.

Enjoyed this article?

Follow us for more technical insights and product updates.