When it comes to hosting and running relational database servers, AWS offers a level of flexibility, with the option to either self-host on an EC2 instance or use the AWS Relational Database Service (RDS). With RDS, the database would be fully managed for Aurora, MySQL, PostgreSQL, MariaDB, Oracle BYOL, and MS SQL.
Self-hosting a database server on an AWS EC2 instance
The costs and resources allocated when self-hosting a database server over an EC2 instance make it a strongly discouraged option. The usual tasks include handling patches, covering backups, and ensuring that the database is adequately available. The expensive expert time expected when covering the above requirements and more make self-hosting only logical in the following specific use cases:
- Cases where the legacy codebases in which the schema was not well designed and there is no scope to fix it. In that case, one might have to extract performance by tweaking the database config or stripping volumes to boost IOPS. Even though this is considered an exception where self-hosting is recommended, it’s very rare for this particular route to be optimal in the long term.
This approach is excessively expensive and re-architecting would most probably be the best approach, moving into something like AWS DynamoDB or AWS Aurora might do the trick.
- Cases where the overload in features provided by RDS is not something of good use anymore, for example when back-ups are not required, one can save by skipping on those features’ extra costs. However, such scenarios are scarce.
Using the fully-managed AWS Relational Database Service (RDS)
When it comes to hosting a database, AWS RDS has proven to be the optimal solution. The reliability, efficiency, security, and effectiveness of the service are all major factors in RDS being the preferred choice. By removing routine administration tasks, RDS already saves on both time and resources, causing substantial cost savings. Compared to self-managed service databases, RDS can save over 50% in various costs, specifically in the following ways:
- It can be set up rapidly and offloads time-consuming database administration to AWS:
- It provides multi-AZ, database mirroring, failover clusters, and reads replicas instantly
- It handles security updates
- It manages backups and recovery with a point-in-time recovery
- It is integrated with the AWS ecosystem, including CloudWatch and IAM.
- AWS Aurora is a cloud-optimized version of MySQL and PostgreSQL, and you cannot run it on an EC2 instance.
- AWS Aurora Serverless is designed for unpredictable workloads and has no analogy in self-hosting.
When using AWS RDS you still have to make certain decisions in the following three key areas, which can dramatically affect the total costs of hosting a database server in AWS:
- Strategic set up of RDS
- Using the right license model to reduce database license costs
- Migrating from commercial databases to AWS Aurora
Strategic set up of RDS
Setting up RDS properly is extremely essential to ensure you are leveraging the service’s full potential with the least possible cost:
Choose the AWS region
To minimize the database latency and data transfer charges, place the RDS instance into the AWS region of the application using the database.
The lowest RDS prices are usually in the key U.S. AWS regions (N. Virginia, Oregon), followed by Europe (Ireland). The highest prices are in the South America (São Paulo) region.
Choose the database engine
To properly operate and scale databases in the cloud, AWS provides seven popular engines to choose from Amazon Aurora with MySQL compatibility, Amazon Aurora with PostgreSQL compatibility, MySQL, MariaDB, PostgreSQL, Oracle, and SQL Server with an additional option to deploy on-premises with Amazon RDS on AWS Outposts.
Choosing the proper engine is critical in the cost optimization process. Prices can reach an 80% increase between engines while maintaining the number of availability zones. An example would be a quick price comparison between db.r5.xlarge on-demand instances in single AZ deployments between Amazon RDS for SQL Server ($2.501) and Amazon RDS for MariaDB ($0.48) where the difference is almost 81% in cost.
Thus, maintaining your engine within the logical needs is essential to the cost optimization process. With that being said, we do have some tips regarding engines for brand new database projects:
- It is recommended to use the following AWS flagship databases that are deeply integrated into the AWS ecosystem, and which have superior functionality to any open source databases:
- If you are building a brand-new OLTP solution, choose Amazon DynamoDB (a serverless, potentially global key-pair database with infinite scalability) with segregated OLTP, OLAP, and FTS.
- For legacy applications, we recommend using Amazon Aurora:
- Amazon Aurora for MySQL/PostgreSQL — a potentially global, relational enterprise database for consistent workloads.
- Amazon Aurora Serverless for MySQL V2 for unpredictable workloads (once generally available). It is not recommended to use Amazon Aurora Serverless for MySQL V1 for production workflows.
- The cheapest RDS database engines are MySQL and MariaDB. MariaDB is advertised as an optimized version of MySQL.
- Amazon Aurora is by default multi-AZ, so a pure price comparison cannot be made since the other quotes are for single-AZ.
- For Amazon Aurora, AWS offers two additional services: (1) Enhanced RDS Performance Insights and (2) DevOps Guru for RDS, which dramatically reduce the amount of database administration required.
- For most use cases, Amazon Aurora can fully replace MS SQL Server or Oracle databases.
Right-Size the database instances
After choosing the proper engine type to suit your business use case, it’s really important to choose the right size of the database, especially considering the price variation between one size and the other.
Based on that, there are some general recommendations to stick to when choosing the size of the instance. For example, it’s generally recommended to use memory-optimized instances for production workloads.
The business use would include anything considered high-performance, distributed web-scale caching, or anything involving real-time processing. Memory-optimized instances include db.r5 (Graviton) and db.r6/db.x2g (Graviton2) with the latter being recommended for Amazon Aurora, MySQL, MariaDB, and PostgreSQL.
Choose the storage class
For Amazon Aurora, there is only one storage class. However, AWS offers three storage classes for other RDS database engines: Magnetic Storage (cheapest), General Purpose SSD, and Provisioned IOPS SSD (most expensive).
The table below presents a storage class comparison:
|Storage Class||Price for RDS (MySQL in single AZ)||Volume Sizes||Advantages||Disadvantages|
|Magnetic Storage||$0.1 per GB-month + $0.1 per 1m requests||20 GiB to 3 TiB||Cost-effective, useful for time-insensitive workloads, such as compliance||Max IOPS 200, max throughput 90 MiB/s|
|General Purpose SSD (Recommended)||$0.115 per GB-month||20 GiB to 64 TiB||The max throughput and IOPS increases with the volume using the credit system / you will not be charged for the I/Os you consume.||The optimal performance for most workloads reached on the provisioned drives larger than 1 TB|
|Provisioned IOPS SSD||$0.125 per GB-month + $0.1 per IOPS-month||100 GiB to 64 TiB||IOPS from 1,000 to 80,000.||Not many database workloads can make use of the provisioned performance|
Right-size the database storage
For Amazon Aurora, AWS only charges for the amount of storage actually used and it provisions the storage automatically, which makes it an optimal option for various use cases.
For other RDS database engines, AWS charges for the amount of storage provisioned, even if not actually used, and one can only increase the amount of storage provisioned.
However, the only way to reduce the provisioned storage is by creating a new RDS instance with smaller provisioned storage and restoring the original database from a snapshot. This stresses the importance of maintaining the provisioned number appropriate for the use case to optimize costs and resources.
Due to the unidirectional nature of provisioning in RDS, it is always recommended to avoid increasing the provisioned storage unless absolutely necessary. Maintaining a low provisioned storage can be achieved by minimizing the usage (logs, indices, entries, etc.) or by archiving data in S3 buckets. Using Storage Autoscaling for RDS would also be a viable option in keeping the storage usage logical.
Choose the right pricing model
The right pricing model would amount to a major fraction of the bill if not architected properly. As RDS instances are usually billed per hour, it’s best to reduce those hours as much as possible. The on-demand pricing model specifically covers leveraging the per-hour billing model, especially if combined with AWS Instance Scheduler to shut down databases when they are not being used. This model is deemed most useful in development and test environments.
For a production environment, however, it is recommended to purchase reserved database instances after the database configuration has stabilized.
Multi-AZ increases the availability of a database server by creating a secondary database instance in another availability zone (AZ) of the same AWS region and synchronously replicating all data to it. While it doesn’t serve the purpose of a read-replica, it certainly can replace the main database in the unlikely case of failure.
Amazon Aurora is multi-AZ by default. For other RDS engines, enable multi-AZ only for use cases requiring very high availability because using multi-AZ can double database instance costs and is rarely required in other scenarios.
Choose the optimal back-up retention period
RDS gives you the option to choose a retention period between 0-35 days, thus enabling point-in-time recovery within the chosen timeframe. Although the backups would be automatic, these backups are billable, making choosing the retention period an important factor in cost optimization.
Similarly, AWS supports manual snapshots of a database. To minimize storage costs, any unused snapshots should be removed.
Using the right license model to reduce database license costs
Database license costs are often one of the largest billable charges, and it is common for a license to not be fully utilized.
In particular, the Oracle Enterprise Edition and MS SQL Server Enterprise Edition database servers are primarily designed for on-premises installation, and thus duplicate functionalities of AWS RDS such as multi-availability or scalability.
Migrating from commercial databases to AWS Aurora
AWS Aurora for MySQL / PostgreSQL is designed in a way that would easily and deeply be integrated with other AWS services. For example, RDS Performance Insights and DevOps for RDS are two services that complement AWS Aurora, dramatically reducing the amount of database administration.
Aurora can easily replace the expensive MS SQL Server or Oracle database servers for most enterprise database workloads.
- For MS SQL Server, AWS introduced Babelfish for Aurora PostgreSQL which allows running MS SQL Server applications with little code change for a limited set of workloads.
- For Oracle, AWS offers the Amazon Database Migration Accelerator (DMA) Connect program.
For additional cost optimization strategies, check out CloudFix, the only AWS cost optimization tool that finds AND fixes AWS-recommended opportunities.