AWS Database Blog

Evaluating the right fit for your Amazon Aurora workloads: provisioned or Serverless v2

Amazon Aurora is a global-scale managed relational database service, purpose-built for the cloud with full MySQL and PostgreSQL compatibility. It is designed to offer the performance and availability of commercial grade databases at one-tenth the cost. Aurora uses a distributed architecture that separates compute capacity from storage. This architecture allows Aurora to provide storage replicated both within and across three Availability Zones (AZ), along with an update model driven by quorum writes, Aurora is designed to deliver high performance and 99.99% availability while easily and efficiently scaling to up to 128 TB of storage.

In this post, we cover important concepts of Aurora provisioned and Aurora Serverless v2 databases including cost, performance, features, and how to determine which to use for your workload type.

Important concepts

Clusters and Instances

An Amazon Aurora cluster consists of two main components. The first is the cluster. The cluster is the storage volume and is where all persistent data is stored. The second component is the collection of instances. An Amazon Aurora cluster may exist with no instances. This is known as a headless cluster. The primary use case for a headless cluster is in a secondary region of a Global Database. In most cases however, a cluster will have between 1-16 instances. The first instance is always a writer, and then instances 2-15 are readers.

The cluster stores the data, while the instances provide the computing power to access and manipulate that data. Instances do not contain any persistent data themselves.

There are many advantages to this architecture. One of which is the ability to quickly add or remove nodes from a cluster. Since each instance operates simply as a compute head, attached to the common storage volume, there is no need to copy the database between nodes of the cluster. This allows for rapid creation of new nodes. Since it is fast and easy to create and delete new nodes, it makes easier to test different compute configurations in your Aurora cluster. For example, you may have a writer and a single large reader. Perhaps your specific workload would perform better running on 3 smaller readers.

Provisioned instances

Aurora offers a variety of instance classes. The original instance class types include memory-optimized (db.r3, db.r4, db.r5,db.r6i, db.r6g, db.r7g, and db.x2g), burstable-performance (db.t2, db.t3, and db.t4g) and for the Amazon Aurora Postgres Compatible Edition, optimized-reads (db.r6gd and db.r6id). All of these instance types are what are commonly referred to as provisioned instances because you are provisioning a certain number of vCPUs, memory and network throughput.

Aurora Serverless

In 2018, AWS launched Aurora Serverless, which is now referred to as Aurora Serverless v1. Aurora Serverless v1 enabled users to automatically scale the size of an Aurora instance based on workload, rather than pre-provisioning compute resources using provisioned instances. Flash forward to 2022 when AWS launched Amazon Aurora Serverless v2. Aurora Serverless v2 was a major leap forward over version one. The primary difference between the two being that while Aurora Serverless v1 required a specific type of cluster (Aurora Serverless cluster), Aurora Serverless v2 was implemented as a new instance type. This enabled a richer feature compatibility with provisioned instances. Additionally, given how fast, and inexpensive it is to test different instance types within an Aurora cluster, it is easy to see if Aurora Serverless v2 is a right fit for your workload.

Capacity

Aurora Serverless v2 capacity is defined by Aurora Capacity Unit (ACU). Each ACU provides approximately 2 GiB of memory with the corresponding CPU and networking. As of this writing, the minimum ACU an Aurora Serverless v2 instance can have is 0.5 (1 GiB of memory) and the maximum is 256 ACU (512 GiB of memory). For workloads where more than 512 GiB of memory are required, a provisioned instance will be needed.

Pricing

With Amazon Aurora, there are 3 main pricing components. This includes data storage, I/O and compute. Since Aurora Serverless v2 is an instance construct, only the instance pricing changes when using Aurora Serverless v2.

With provisioned instances, the price depends on the type and size of instance and is billed per hour. Given the static nature of provisioned instances, this is a fairly straightforward calculation.

However, Aurora Serverless v2 scales dynamically. Whereas you may have a provisioned instance that is online and runs 24×7 for an entire month, a Serverless v2 instance may scale up and down hundreds or thousands of times in the same month. As such, Serverless v2 pricing is based on ACU-hours. If, for example you had a Serverless v2 instance that ran at 10 ACUs 8 hours per day, and then scaled down to 2 ACUs during off hours:

10 x 8 = 80 ACU-hours
+ 2 x 16 = 32 ACU-hours
————————-
112 ACU-hours

This comes out to 112 ACU-hours for the day. The primary advantage for this workload is that if we used a provisioned instance instead of a Serverless v2 instance, we would have been overprovisioned for 2/3 of the day (16 hours). What’s more, though we used full hours above to calculate our cost, Aurora Serverless v2 measures ACUs by the second. This ensures the most precise fit of resources to your workload, resulting in optimized cost. Ultimately, if your workload is variable like the preceding example, it may be a great fit for Aurora Serverless v2.

Version support

Aurora Serverless v2 is available in all regions where Amazon Aurora is available. For the MySQL compatible engine, Aurora Serverless runs on Aurora MySQL 3. For the PostgreSQL compatible engine, Aurora Serverless runs on Aurora PostgreSQL 13 and higher. Since Aurora Serverless v2 is simply an instance type, these versions are the same versions that run on provisioned instances. For workloads requiring more than 512 GiB of memory, a provisioned instance is necessary.

Features and upgrades

One of the main design goals with Aurora Serverless v2 was to ensure feature compatibility. By implementing Aurora Serverless v2 at the instance level, we have been able so far to ensure that all of the features that work with Aurora provisioned instances also work with Aurora Serverless instances, with the exception of 2:

Since Aurora Serverless v2 supports the same features as provisioned instances, upgrades to an Aurora Serverless v2 instance are the same as for provisioned instances.

Performance

When planning for performance with Aurora Serverless v2, there are additional factors to consider. One of those considerations are the minimum ACU and the maximum ACU, which are set at the cluster level. By default, the Minimum ACU value is set to 0.5 and the Maximum ACU value is set to 256.

Since ACUs are tied to CPU, memory and networking, certain workloads may require a minimum ACU value greater than the default 0.5. Additionally, the rate at which Aurora Serverless v2 instance scales is related to the current capacity. The higher the current capacity, the faster the instance scales. It is recommended to specify a minimum ACU for your cluster to maintain both baseline performance as well as the ability to scale at a rate appropriate for your workload.

In order to control cost, one may also consider setting a maximum ACU for a cluster which is lower than the default value of 256. However, remember that specifying a lower maximum ACU limits how much the instance can scale which may hamper database performance if you encounter a large spike in traffic.

Buffer pool

With relational databases, data is stored in fixed blocks called pages. When the database performs any I/O operation, it is done at the page level. For example, Aurora MySQL uses 16 KB pages and Aurora PostgreSQL uses 8 KB pages. When these pages are accessed, they are stored in memory in something called the buffer pool. This enables fast access to these pages rather than having to access the disk for every I/O operation. The amount of memory allocated to the buffer pool is controlled via a parameter group parameter called innodb_buffer_pool_size for MySQL and shared_buffers for PostgreSQL. If you look up this parameter in a parameter group, you will see that the default value is a formula based on the amount of memory on the instance. In short, the size of the buffer pool is directly related to the amount of memory that the instance has. For provisioned instances, again this is pretty straightforward. However, with an instance that changes size, and therefore the amount of available memory many times throughout the day, one may ask how the buffer pool is managed on an Aurora Serverless v2 instance. When an Aurora Serverless v2 instance scales up, there is no problem, because the buffer pool will grow. However, when a Serverless v2 instance scales down, we use a combination of least frequently used (LFU) and least recently used (LRU) algorithms. This ensures that the most important pages remain in the buffer pool. However, if your application requires a certain buffer pool size, we do recommend specifying a minimum ACU to ensure that you always have a large enough buffer pool.

High availability

Amazon Aurora provides a cluster endpoint which always points to the current writer node in the cluster. In the event of a failover, it is a best practice to have at least one reader node in the cluster of the same size and type as the writer. In this case, both the writer and the reader specified by its promotion tier will reboot and then the switch happens. The cluster endpoint will be updated automatically to point to the new writer. This is all the same when we talk about Aurora Serverless v2. It is important to note that if the writer and reader are Aurora Serverless v2 instances, any reader using a promotion tier of 0 or 1 will automatically scale to the same ACUs as the writer. This is to ensure that during failover, the writer will be replaced by the same size instance, so that it can continue to handle the writer’s load. Any Aurora Serverless v2 instances in your cluster used for read scalability, should have a promotion tier of 2 or higher to ensure that they are a lower priority failover partner to the writer, and therefore less likely to participate in a failover.

Aurora Global database

Aurora Global Database provides the ability to maintain a live copy of your database cluster in up to 5 additional AWS Regions. This is useful for disaster recovery scenarios, migrating to a new Region or just providing local reads to customers around the globe. In the case of disaster recovery, there are 3 modes in which you may run a secondary cluster. The first would be to run the same configuration as your primary cluster. This ensures that during a failover, your application can pick up rapidly, as all of the compute resources are already in place providing the very best recovery time objective (RTO). This can be expensive though, as you are paying for all of those compute resources that are not in use. Another configuration is known as a headless cluster. As we discussed previously in this post, the storage itself is completely separate from the compute instances. Global Database replicates at the storage layer, and as such you don’t actually need any compute resources in the secondary region to maintain a copy of your data. However, in the event that you need to failover to that secondary region, it will take some time to provision those compute resources, leading to a much longer RTO. The third option involves using Serverless v2 instances. This provides a much faster RTO than a headless cluster as you will already have some compute resources online in the secondary region which can scale rapidly. However, it will result in a fraction of the cost of running a fully provisioned cluster in the secondary region.

Testing

As with any change to your infrastructure, you will want to test Aurora Serverless v2 instances before deploying them to production. Fortunately, this is easy to do using the Aurora cloning feature. Clones are a fast, inexpensive and reliable way to test changes to your clusters, including testing out new instance types like Aurora Serverless v2.

You can add an Aurora Serverless v2 read replica to an existing cluster of provisioned instances. This allows you to scale out read traffic by directing a subset of the application’s read operations to the Serverless v2 replica, so you can evaluate its performance for your specific workload.

The following diagram illustrates an Aurora Cluster with both provisioned and Serverless v2 instance options.

Choosing between provisioned and serverless

Another great benefit of implementing Aurora Serverless v2 at the instance level is that a given Aurora cluster may be comprised of all provisioned instances, all Aurora Serverless v2 instances or some combination thereof. You don’t have to commit to one or the other and you can easily change the ratio over time to meet your needs. All that is needed is to add new instances of either provisioned or Aurora Serverless v2 and to delete the old instances. If you are looking to replace the writer, simply add a new instance of your choice with the same promotion tier as your writer and then initiate a failover.

For workloads that provide a steady, stable database workload around the clock, provisioned instances will almost always be the best instance choice. Since the workload is steady, dynamically sizing the instance will provide little advantage. Additionally, for the same level of CPU, memory and network resources, provisioned instances will be less expensive than Aurora Serverless v2.

For workloads that see significant peaks and valleys, Aurora Serverless v2 might be the best fit. Let’s say that your company is regionally based and you happen to know that nearly all of your database traffic happens on weekdays during local business hours, and though there is some traffic outside of these hours, it is markedly less. In this scenario, Aurora Serverless v2 can automatically scale to meet the traffic generated during the day and then automatically scale down during off hours, thereby saving you money. What’s more, Aurora Serverless v2 scales frequently and in increments as small as 0.5 ACUs throughout the day to efficiently match resources to the demand curve. This ensures optimal resource allocation 24 hours a day.

Summary

In this post, we discussed the differences between provisioned instances and Aurora Serverless v2 instances, including pricing, performance, and scaling. We identified how to determine which mix of provisioned and Aurora Serverless v2 instances will best fit your workload and how to validate those assumptions. In short, for spiky or intermittent workloads, Aurora Serverless v2 is the best fit, whereas provisioned instances remain the best choice for steady state workloads. With full interoperability between provisioned and serverless instances, the only thing that remains is for you to test your workload to see if you can benefit from Aurora Serverless v2. Get started today!


About the Authors

Kiran Mulupuru is a Database Specialist Technical Account Manager at Amazon Web Services. She focuses on Amazon RDS and Amazon Aurora databases. She works with enterprise customers, providing technical assistance on database operational performance and sharing database best practices.

Chetan Nandikanti is a Senior Database Specialist Solutions Architect at Amazon Web Services based out of Grapevine, Texas. He works with our customers to provide assistance with designing, migrating, and optimizing database solutions on AWS, including integrating operational data with Storage, Analytics, and AI/ML services.

Steve Abraham is a Principal Solutions Architect for Amazon Web Services. He works with our customers to provide guidance and technical assistance on database projects, helping them improve the value of their solutions when using AWS.