RDS Storage Types – Which one should I choose?

Amazon RDS (Relational Database Service) is a cloud-based web service that makes it easier to set up, operate, and scale a relational database. RDS is designed to provide an efficient and cost-effective solution for managing databases. One of the crucial components of RDS, is storage. Amazon RDS provides three recommended storage options for database instances: GP2, GP3 & IO1 (Magnetic is for backward compatibility).

In this blog post, we will explore the differences between storage types and when to use each type. But before we dive in, you’ll need to understand the main differences between GP2 and GP3 volumes.

Here is an AWS blog regarding migrating EBS with a great comparison table.

TLDR; GP2 IOPS and throughput get larger with volume size, while GP3 requires you to configure the amount of IOPS and throughput required.

Traditional EBS vs RDS storage

RDS storage is backed by AWS EBS but it has a few tricks that do not come out of the box with traditional EBS, for example, an EBS volume can be up to 16TiB while RDS storage can max out at 64TiB.

This also makes different performance metrics maximums:

Max Throughput (MiB/s) 250 1,000 1,000 1,000 4,000 4,000
Max IOPS 16,000 16,000 64,000 64,000 64,000 256,000

Disclaimer – These maximums are for all engines other than SQL Server as it doesn’t support volume striping.

This is mainly due to AWS performing some magic behind the scenes that make use of multiple EBS volumes & volume striping.

Another consideration is price. With traditional EBS, GP3 is generally 20% cheaper than GP2. However, how does this compare with RDS storage?

They are the same price!

What’s more, as GP3 is GP3, you will need to pay more for each additional Throughput/IOPS over baseline.

Then when should I use GP3?

The obvious answer would be when I have a small amount of storage but require a large amount of IOPS/Throughput. But we’re not here for the obvious answers, let’s geek out with some graphs!

Here are a few graphs depicting the difference between GP2 & GP3 regarding the amount of IOPS, Throughput & price (When equalizing GP3 IOPS & Throughput configuration to what is provided with GP2).

These charts are up to 25TB storage since after 21 it flat lines (or in the case of price continues in parallel with each other)

Disclaimer; Notice the gray areas on the IOPS and Throughput graphs, these are in a bit of a gray area (see what I did there?), These areas indicate where GP2 is burstable. For the IOPS graph, the burst can be up to 3000, and for the Throughput graph, between 170-334GB storage, the burst can be up to 250MiB/s however between 1,000GB and 1,336GB, it’s burstable up to 1,000MiB/s.

So in the IOPS and Throughput graphs, whenever GP2 is higher than GP3, we have to pay more to get the same performance! And the delta between the price gets higher the larger the storage!

Hold on, with all these technicalities between GP2 and GP3 storage I’ve forgotten the third (and most mind-blowing) storage type; IO1.

IO1 is a storage type for workloads that require huge amounts of IOPS, allowing you to go up to 256,000 IOPS! But how does its pricing compare with GP2 & GP3?

Storage type Storage price (per GB) IOPS price
GP2 $0.115 0
GP3 $0.115 $0.02
IO1 $0.125 $0.1

us-east-1 pricing

Well some bad news for you if you’ve been using IO1 at under 64,000 IOPS. It looks like you’re wasting money!

Comparing the pricing with GP3 you can see that you will be getting the same performance for a lot lower price! (Even without taking into consideration the free baseline IOPS you get from GP3). The main use-case that makes sense to use IO1 over GP3 is when you’re restricted by GP3s IOPS limit (64,000).

Disclaimer: There is another metric that slightly differs between GP2/3 and IO1, which is latency. While all provide single digit latency, for GP2/3 it’s for 99% of the time, while for IO1 it’s 99.9% of the time. This may be relevant if you have tight SLO/SLA requirements, but keep in mind the trade-off of potentially thousands of dollars a month. If you want to deep dive into more granular resolution, Percona wrote this great article benchmarking the performance of each storage type.

So how do I decide which storage type to pick?

So the answer to this question is the good old; It’s complicated. There are a few rules of thumb we can go by:

  • If you require more IOPS than what GP2 offers at the storage size you require, better go with GP3.
  • If you don’t know your IOPS and Throughput requirements, use GP3 when your storage is lower than 4TB, and when your storage is over 4TB use GP2 (This makes sure you get larger baselines).
  • If you know how much Storage, IOPS and Throughput you require, you can calculate which one would be either cheaper, or (in the case of smaller storage sizes) provides larger IOPS & Throughput headroom at the same price (GP3 baselines).
  • If you don’t need over 64,000 IOPS, don’t use IO1.

Awesome, so I’m all set?

Well, it would be great if this was the end of the story right?

But I’m afraid there is another parameter we have to take into consideration when configuring these metrics, which can very well be a bottleneck; the instance type.

In AWS each instance type has it’s own IOPS and Throughput limits for the instance itself (You can view the whole table here). This means that we can hit an IOPS or Throughput bottleneck if we aren’t using a large enough instance.

For example let’s take the m6g.large instance which has a baseline Throughput of 78.75 MB/s and baseline IOPS of 3600 (Yes, these are also burstable but only for 30mins in a 24 period so I wouldn’t count on it). If I use m6g.large for my RDS instance I wouldn’t be able to take advantage of any storage configuration that provides more than the instance constraints.

This is quite rare as usually you’ll be required to have a larger instance to answer to CPU and memory requirements at this scale before you hit the IOPS and Throughput limits. But if you are experiencing inability to utilize the storage configuration you may want to keep this in mind.