You're building an image upload feature. Users can upload profile pictures.

You add an S3 bucket to your code. Standard storage. Ship it.

That design decision just locked in a 10x cost multiplier.

Not because you configured something wrong. Because you didn't think about storage lifecycle at all.

Here's what nobody mentions in system design: cloud storage isn't one thing. It's three different systems with three different price points.

Hot (Standard): $0.023/GB per month
Warm (Infrequent Access): $0.0125/GB per month (46% cheaper)
Cold (Archive): $0.00099/GB per month (96% cheaper)

Same cloud. Same company. Different settings when you create the bucket.

Design Storage in Three Tiers From Day One

When you architect a system that stores images, you need to answer one question upfront:

How does data move through its lifecycle?

Not six months later when the bill shows up. Right now, when you're building the feature.

Here's how to think about it:

Tier 1: Hot (0-30 days) Images people are viewing right now. Keep them in hot storage.

  • Profile pic uploaded this week

  • Product images from active listings

  • Recent photo uploads

Tier 2: Warm (30-90 days) Images that might get viewed occasionally. Move them to warm storage.

  • Profile pic from last month

  • Photos from old blog posts

  • Inactive user uploads

Tier 3: Cold (90+ days) Images you're keeping for compliance or user history. Move them to cold storage.

  • Old profile pictures (user changed it)

  • Deleted user photos (retention policy)

  • Archive of past campaigns

Real Numbers From a Photo Sharing App

A company storing 100TB of user images:

Before (all in Hot): $2,300/month

After designing lifecycle upfront:

  • 5TB in Hot (last week's uploads): $115/month

  • 10TB in Warm (last month): $128/month

  • 85TB in Cold (old stuff): $85/month

New total: $328/month

Savings: $1,972/month ($23,664/year)

Time to design this: 10 minutes.

"But Users Might View Old Photos"

They might. But here's the thing:

Cold storage (Glacier Instant Retrieval) retrieves in milliseconds. Same speed as hot storage.

The catch? Small fee when you retrieve. About $0.03 per GB.

Reality check: images older than 90 days get viewed less than 1% of the time.

The math:

  • Save 96% on storage costs

  • Pay 3 cents per GB on rare retrievals

  • Breaks even if an image gets viewed more than 30 times/month

For old profile pictures? Nobody's viewing them 30 times a month.

How to Actually Design This

When you're building the feature, lifecycle rules are part of the storage design.

Here's what the configuration looks like:

{
  "lifecycle_rules": [
    {
      "name": "move_to_warm",
      "after_days": 30,
      "storage_tier": "infrequent_access"
    },
    {
      "name": "move_to_cold", 
      "after_days": 90,
      "storage_tier": "glacier_instant"

Set it once when you create the bucket. Every image you upload follows these rules automatically.

Design Considerations for Different Features

Different features need different lifecycle designs:

User Profile Pictures: Hot for 30 days → Warm for 60 days → Cold forever Savings: 70%

Product Images (E-commerce): Hot while listing is active → Warm for 30 days after deletion → Cold for compliance Savings: 60%

Photo Sharing App: Hot for 7 days → Warm for 90 days → Cold for 1 year → Delete Savings: 85%

Document Storage: Warm from day one (rarely viewed) → Cold after 90 days Savings: 90%

Multi-Environment Storage Design

Production and dev environments need different designs.

Your production images need long retention. Your dev test images don't.

{
  "retention_days": {
    "production": 365,
    "staging": 30,
    "dev": 7
 

One configuration. Three different storage architectures.

Most systems use the same retention everywhere. That's expensive.

Find Your Biggest Waste

Check your largest buckets:

aws s3 ls --summarize --recursive s3://your-bucket-name

No lifecycle rules? That's where your money goes.

For a 50TB image bucket without rules, you're paying $1,150/month when you could be paying $200/month.

The Design Question Nobody Asks

When building an image upload feature, everyone asks:

  • What's the upload flow?

  • How do we resize images?

  • Where do we store thumbnails?

Nobody asks: What's the lifecycle?

That question determines whether your storage costs $2,300/month or $328/month.

Start Here

Next time you design a feature that stores data, ask three questions:

  1. How long until users stop accessing this data?

  2. What's our legal retention requirement?

  3. Can retrieval take 100ms instead of 10ms?

Those answers become your storage design:

{
  "hot_days": 30,
  "warm_days": 90,
  "cold_days": 365,
  "delete_after": 730
}

Write it in the same commit as the bucket creation. Not later. Not as cleanup.

The Bottom Line

When you design storage for a system, you have three options: hot, warm, or cold.

Using hot storage for everything is a design choice. It's just the wrong one.

Build lifecycle rules into your system from day one. Your storage design should match how users actually access data.

Systems designed this way cost 50-90% less to run.

Systems that aren't designed this way pay the difference.

Keep Reading

No posts found