Lowering our AWS RDS spend using Aurora I/O-Optimized

DJ Pham and Dave North | Last updated on October 18, 2023 | 6 minute read

When your mission is to back up the cloud, that’s a lot of data to manage– about 3.7PB, to be exact. At Rewind, we use AWS RDS Postgres and Aurora Postgres services extensively as an indexing system into the customer data we back up.

Due to how data is split among the multiple SaaS platforms we back up and multiple geographic regions, we have around 15 RDS databases. Each has a varying amount of data, stored with different read/write profiles, according to the specifications and data structure of the platform. RDS represents close to 6% of our overall spend each month, so we’re always looking for ways we can lower this via the use of reserved instances.

Enter Aurora I/O-Optimized

In May 2023, AWS announced the availability of Aurora I/O-Optimized which offers an improved price/performance profile depending on your Aurora usage patterns. I/O-Optimized has these basic pricing characteristics:

  • There is no charge for IOPS (Input/output operations per second, pronounced “eye-ops”)
  • There is a higher charge for compute instances
  • There is a higher charge for storage
  • There is a requirement to purchase more Reserved Instances (RIs) to offset the higher instance cost (30% more)

The general rule for whether I/O-Optimized will be cost effective for you is: if your storage I/O cost for a particular database is at or around 25% of the compute cost, I/O-Optimized should be less expensive than ‘regular’ Aurora storage pricing.

Rewind specifics

As with any large change like this, we did some modeling to see what the actual impact would be using Rewind’s real costs and current performance profile. Here’s a snippet of our model for three of our current databases that are currently using Aurora:

That 54% savings looked very appealing! It wasn’t unexpected since even on our bill, we could see that some databases were very write heavy and used a significant amount of Aurora storage IOPS.

What about ‘regular’ RDS Postgres databases though? We have several databases that are running RDS Postgres (multi-az) with provisioned IOPS storage. Provisioned IOPS lets us control how much we are willing to spend on storage access charges while still maintaining our SLO for data access times. 

In the past, we had attempted to migrate these to Aurora but with the IOPS now uncapped, the storage cost was higher than we were willing to pay and thus we left these databases on RDS Postgres. But now with I/O-Optimized and knowing the performance characteristics of these databases were very write heavy, was it now worth re-examining moving these to Aurora?

The short answer is yes! With savings up to 40% depending on the current provisioned IOPS and usage patterns, it does indeed seem worth migrating these databases to Aurora.

One important note and a further justification to model this out first is that I/O-Optimized can only be enabled or disabled once a month. If you switch a database to I/O-Optimized and realize it’s actually costing more, you’ll be stuck with it for a month. We recommend doing the math first, then deciding whether it’s the right call for your specific environment.

Important safety notice regarding reserved instances

In order to lower our RDS costs as much as possible and because RDS does not fall into AWS savings plans, we use RDS reserved instances (RIs) to lower our RDS costs. Using one year, no upfront RIs gives around a 40% savings over on-demand and helps with capacity planning for the year. 

One key point to note with Aurora Optimized I/O is that because the compute costs are higher with I/O-Optimized, the reserved instance costs are also higher – actually 30% higher. The way AWS has chosen to model this is you need to purchase more RIs to cover the increased Aurora compute costs. The Aurora pricing page has an example on what RIs to purchase if using Aurora I/O-Optimized but using a simple example:

If you had 10 db.r6g.large instances covered with RDS RIs and you switch to Aurora Optimized I/O, you’d then need 10 x 1.3 = 13 RIs to achieve the same coverage (even though your instance count hasn’t changed).

It’s worth paying close attention to the case where you need a fractional RI and how that is achieved in the example table provided by AWS. In general, all RDS reserved instances map back to something called normalized units. These normalized units can then be used to match various instance sizes within the same instance family. AWS covers this concept well in this help document.

Lastly on RIs for RDS. The AWS recommendation tool in the console (Billing/Reservations/Recommendations, choose the RDS service) is very good at analyzing your usage and recommending the correct mix of RIs. We found it matched our own calculations and took Aurora I/O-Optimized into account when making a recommendation.

Results

We’ve completed our migration to Aurora I/O-Optimized – what did we learn and what were the results?

On the configuration side, only one detail was missed in the small print – the version of Aurora that supports I/O-Optimized. Specifically, the following versions of Aurora Postgres are required:

Aurora PostgreSQL versions 15.2 and higher, 14.7 and higher, and 13.10 and higher.

In our case we were running 13.9, so needed to update our version of Aurora. This was good housekeeping anyway and was a minor update.

On the savings side, we ended up saving more than we had initially modeled due to originally modeling the compute costs using on-demand pricing rather than reserved instance pricing. As the compute is a smaller percentage of the overall cost when using reserved instances, I/O-Optimized resulted in a bigger saving.

Here’s two examples from the many databases we migrated to Aurora I/O-Optimized. In both cases, these databases are very I/O heavy with relatively low compute requirements. Both examples show the pattern we have seen across all of the databases we migrated – the bulk of the cost prior to migration was Aurora storage I/O and post migration, compute becomes the driving cost factor (which is mitigated with reserved instances).

Database 1, with a 54% cost saving.
Database 2, with a 57% cost saving.

Wrap up

It’s important to keep an eye on new features, functionality, and AWS releases and how they may apply to your stack and environment. (Hint: Subscribe to relevant newsletters to stay up to date, such as the Backup Bulletin).

While the new cost saving features may seem like slam dunks, It’s further important to model any changes that impact cost before starting any work on a migration. In our case, most of our databases made sense to migrate to I/O-Optimized but several databases would have resulted in either no change to cost or even an increased cost by using Aurora I/O-Optimized. We caught this in the modeling phase and planned our migrations accordingly.

In our case, we’re averaging well over a 50% saving by enabling Aurora I/O-Optimized – hopefully this post will enable you to see if it’s worth the switch in your use case!

Are you an avid AWS fan, interested in solving problems like this with solutions like these? You’re in luck– Rewind is hiring.


Profile picture of <a class=DJ Pham">
DJ Pham
DJ Pham is a DevOps Engineer at Rewind. After obtaining a Bachelor of Mathematics from the University of Waterloo, DJ brought his data analysis talents to Rewind. When he isn't automating solutions, DJ enjoys exploring the Ottawa area on his bike or watching every basketball game he can.