S3 Storage Classes: Fast Access

I only ever used the Standard S3 storage class at work and for my personal project. At work, cost optimisation usually boils down to right-sizing compute or databases; S3 never made the cut. For personal projects, my S3 bill has never gone above a dollar for me to consider using anything other than the Standard class.

Still, S3 storage classes are an essential topic. They show up in AWS certification exams, and like many other people, my strategy is to memorise a handful of mappings: “frequent” means Standard Access (SA); “once a month” is most likely Standard-Infrequent Access (IA), and “once a quarter” is probably Glacier Instant Retrieval (GIR) and so on. It is good enough to pass the exam, but I know that my understanding of this topic is shallow.

For example, how cost-effective are the other classes compared to SA? Where do those monthly or quarterly usage heuristics come from? At what point do the savings from IA or GIR outweigh the cost of transitioning data? And what other gotchas should I watch out for? These are the kinds of questions this deep dive sets out to answer.

AWS offers nine storage classes today, but covering them all in a single post would be too much. So this blog focuses on just three: SA, IA, and GIR. I chose these because they share the same performance and redundancy characteristics, which makes cost comparisons more straightforward.

You will find plenty of interactive diagrams that break down the individual cost components. Click or tap on them to explore each element in more detail.

Let us start with why storage classes exist in the first place.

Storage classes

S3 is used to store files, called objects, after they are uploaded, ranging from a few bytes to 5 TB. Like many AWS services, S3 is economical at a small scale, but storing millions of HD movies will put a dent in the bill. One way to reduce this cost is by picking a different storage class for the object. Take a look at the bucket below; notice that each object has a different storage class.

s3 bucket icon

Objects of demo_1

Name
Storage class
Size
Last Modified
s3 object iconterraform.tfstateStandard5 KB1 sec ago
s3 object icondb_bkp.dbStandard-IA500 MB1 sec ago
s3 object iconmovie.mp4Glacier Instant Retrieval3.0 GB1 sec ago

Consider terraform.tfstate, it is in the SA storage class, which is the default storage class that offers fast retrieval and high availability. But it is also among the most expensive of the storage classes available. However, it is the perfect choice for terraform.tfstate because the file is read many times a day, needs to be retrieved quickly, and teams will be blocked from making infrastructure changes if it is unavailable.

The other two objects, db_bkp.db and movie.mp4, are read less often than terraform.tfstate but still need the same durability and millisecond retrieval that SA provides. For this kind of data, IA and GIR are a better choices because they offer the same performance and features as SA at lower storage cost, in exchange for higher GET, PUT and retrieval charges. They are the most cost-effective for data that needs to be stored for a while but accessed infrequently.

billing line items

S3 has about 100 possible billing line itemsexternal link icon, but here we will limit it to those most relevant to the three storage classes. The breakdown below shows the prices for the 8th November 2025 in the ap-southeast-2 region.

Cost Calculator icon

Cost Calculator

  • Requests Tier 1

    per 1,000 PUT, COPY, POST or LIST requests

    • SA$0.0055
    • IA$0.01
    • GIR$0.02
  • Requests Tier 2

    per 1,000 GET and all other requests

    • SA$0.00044
    • IA$0.001
    • GIR$0.01
  • Storage

    per GB-Month of storage

    • SA$0.025
    • IA$0.0138
    • GIR$0.005
  • Retrieval

    per GB

    • IA$0.01
    • GIR$0.03
  • Early Delete

    per GB-Month of storage

    • IA$0.0138
    • GIR$0.005
  • Lifecycle Transition

    per 1,000 lifecycle transition requests

    • IA$0.01
    • GIR$0.02

I always found it a lot of work to parse a list or table like this, especially when the displayed values are fractions of a cent. A better approach is to chart this data, as it puts the numbers into context. To do that, we need a simple model that lets us visually represent these values. The next section introduces that model and shows how it maps onto a stacked bar chart.

model

At the end of each month, AWS calculates your S3 costs by summing up all the cost components. AWS can do this because it tracks the usage data for each cost component in your account throughout the month. However, since we do not have that usage data here, we need to model each cost component through a few simple assumptions.

The model we will build assumes that the objects in the bucket are roughly the same size, accessed at about the same rate, and uploaded directly into the storage class. These assumptions allow us to create a simple model to compare the three storage classes. With that in place, we can now represent the cost components as equations.

Any good model uses the fewest possible variables while remaining highly accurate. For this one, we will use three: the total number of objects (Nobj), the average object size (Sbytes), and the percentage of objects read (P%read), which we will explore in more detail later. With these, I claim that we can represent the first four S3 cost components as:

  • PUT Requests=Requests-Tier1×Nobj

    Upload cost grows only with object count

  • GET Requests=Requests-Tier2×Nobj×P%read

    Read cost grows with both object count and read fraction

  • Storage=TimedStorage-ByteHrs×Nobj×Sbytes

    Storage cost grows with total storage

  • GB Retrieved=Retrieval×Nobj×Sbytes×P%read

    Retrieval cost grows with total storage and read fraction

The stacked bar chart below shows the cost components produced by the equations after substituting the variables with the pricing for each storage class; refer to the Cost Calculator table above for the exact values used. The chart is interactive, so you can hover over or click the bars to see the dollar breakdown for each cost component.

Monthly S3 cost


Total object count (Nobj):

1 K
1 M
1 B

Average object size (Sbytes):

128 B
400 KB
1 MB
500 MB
1 GB

Percentage of objects read (P%read):

0%
50%
100%
150%
200%

If you played with this chart, you would find that the following statements are true:

  • SA is the most cost effective option when the Sbytes is less than 400 KB
  • IA becomes a cost effective option at Sbytes of 400 KB with P%read of 0%
  • GIR is not a viable option when Sbytes is less than 1 MB
  • IA and GIR can remain cost effective at higher P%read as Sbytes increases
  • IA is never the cost effective option when P%read is greater than 112%
  • GIR is never the cost effective option when P%read is greater than 50%
  • Nobj only scales the cost; the proportions are not changed

The general trend is that as Sbytes increases, IA and GIR become more economical. When P%read increases, SA becomes more economical. Both observations are consistent with what we would expect.

What we want to understand now is why the common guidance suggests that IA objects should be read no more than once a month, and GIR objects no more than once a quarter. To answer that, we need to look more closely at P%read.

Percentage of objects read

A P%read of 100% means every object in the bucket was read that month. On its own, this is not very informative, as it says nothing about read frequency or the data volume. However, because we are assuming that all objects are roughly the same size and accessed at similar rates, P%read becomes a useful variable. Under these assumptions, a P%read of 200% means each object is read twice per month on average; 50% means once every two months; and 33% means once every three months, or roughly once a quarter.

If you look back at the chart, you will notice that IA stops being cost-effective at around a P%read of 112% which corresponds to objects being read slightly more than once per month. Similarly, GIR becomes less cost-effective beyond 33%, which corresponds to reading objects more than once every three months. These observations confirm the common heuristics that IA aligns with monthly access and GIR with quarterly access, and they also show why accessing data more often than this reduces their cost-effectiveness.

Proving these heuristics was what I mainly wanted to cover. Still, for completeness, we need to discuss two additional cost components that affect storage class selection: transition and early-delete costs.

transition between storage classes

The previous graph compares the cost of uploading to SA with uploading objects directly to IA or GIR. However, this is uncommon. In practice, objects are typically uploaded to SA first and later moved to IA or GIR, since most reads occur soon after upload. In our model, the cost of this transition is expressed as:

Transition=Requests-Tier4×Nobj

Transition cost grows only with object count

This transition cost is a one-off charge, and over time, the lower monthly storage rate for the infrequent classes offsets this fee. The bar chart below illustrates this effect. It assumes that objects are first uploaded to SA, and either left there or immediately transitioned to IA or GIR using the appropriate S3 API calls, rather than using lifecycle rules, which would be terribly hard to model accurately. Try adjusting the Stored for (days) variable and find when the savings from IA or GIR exceed the initial transition cost.

Total S3 cost for 16 days


Total object count (Nobj):

1 K
1 M
1 B

Average object size (Sbytes):

128 B
400 KB
1 MB
500 MB
1 GB

Stored for (days):

16
30
90

Admittedly, this chart is not as interesting as the previous one; it mainly shows that larger objects reach breakeven sooner. Still, there are some interesting cases. For example, 1 MB objects are only cost-effective in IA for a short period between days 30 and 35, after which GIR becomes the cheaper option. But this assumes the object is not deleted early, which we look at in the next section.

Early delete

Assuming good design, storage is usually the dominant cost component in S3. There are two ways to manage it: choose cheaper storage classes, as already discussed, or delete objects when they are no longer required. Though from experience, it often takes a lot more effort to convince an organisation to remove data than to store more of it; those that do it usually do so out of necessity.

Depending on the workload, data may need to be retained for days, months, or even years. For data that must be kept for several months, it is possible to see some savings by moving objects to IA or GIR before they are removed. However, they must not be deleted too early, as these classes enforce minimum storage durations.

When an object is moved to IA or GIR, storage costs are effectively prepaid for a minimum duration. If it is deleted before that period ends, AWS applies an early deletion charge, which can be represented by the following equation:

Early Delete=EarlyDelete×Nobj×Sbytes×(minimum storage days - days stored)

Objects deleted before the minimum storage period are still charged as if they had stayed the full term.

It represents the difference between what was paid and what would have been paid if the object had remained stored for the full duration. The minimum storage durations for SA, IA, GIR are 0, 30 and 90 days, respectively. Try adjusting the variables, particularly the Delete after (days) setting, in the final chart to see how early deletion costs are affected.

Total S3 cost for 16 days


Total object count (Nobj):

1 K
1 M
1 B

Average object size (Sbytes):

128 B
400 KB
1 MB
500 MB
1 GB

Delete after (days):

16
30
90

According to the chart, an object must be stored long enough for the storage savings to exceed the early deletion fee. In this model, that is about 16 days when Sbytes is 1 GB, and longer for smaller objects. Otherwise, it is more cost-effective to simply keep the object in SA.

limitations

There is a common saying: 'all models are wrong, but some are useful'. In that spirit, below are several limitations of the models in this blog:

  • Multipart uploads are not modelled. For simplicity, the model assumes each object is uploaded with a single PUT request. In practice, large objects are uploaded in multiple parts, which increases the number of PUT requests.
  • Multiple GET requests per object. Large objects are usually not fetched with a single request; a single download may use several ranged GET requests, increasing the total request count.
  • Similar object size. The models assume that objects are roughly similar in size so that an average object size can be used. Real S3 buckets often contain objects with highly varied sizes.
  • Uneven access patterns. A small subset of objects can receive a disproportionate share of reads, making P%read a less representative variable.
  • Validating the models. Validating the model is an important step in any analysis. Unfortunately, I did not run experiments to generate real-world cost data for this post.

It is likely that I have missed other assumptions, and these models are simple and do not consider optimisation strategies. Even so, they are still helpful for visualising how the main cost drivers change with object properties, which is the main point of this blog.

final thoughts

I am sure there are simpler ways to explain the same concepts without using graphs or diagrams. But I do not enjoy long walls of text and always find interactive visuals more engaging. In fact, this post might have just been an excuse to learn more about SVGs.

I customised quite a few of the original SVG files to achieve the effects I wanted, such as the polka dots on the transition bar graph and the animated like button in the desktop view. I am especially pleased with the one below. It is based on the official AWS S3 bucket SVG, which I modified to look like a layered cake, with each layer representing a different storage class. It is not the most accurate mental model of storage classes, but it was fun to make, and it looks nice.

The bucket contains links to my NAT Gateway blog, my interview with Corey Quinn on Screaming in the Cloud, and my social media profiles. Feel free to reach out if you have feedback or questions. Thank you for reading!