How to reduce costs in AWS
Templates may use configurations adding up unnecessary expenses. Here's my journey to move away from this config to reduce this project's AWS cost.
It was easy to set up a production-ready database in Amazon Web Services (AWS). Select the production template, hit the Create database button, and ship it! Easy.
However, templates may use configurations adding up unnecessary expenses. Here's my journey to move away from this config to reduce this project's AWS cost.
💸 The price is right:
AWS serves infrastructure options easily to its users à la carte in the form of simple UI. Just click on a drop-down, select a radio button, or move the slider to get scale resources up or down. However, due to the number of options, I often encounter choice paralysis. It takes time to research each option, and within an option, it opens up more infrastructure decisions.
To help in some instances AWS offers templates for an easy setup. The drawback is that the out-of-box configurations may be too expensive and overkill for a project. For this project's production environment I chose the production template for AWS Relational Databases Service (RDS). However, I notice the billing is higher than other projects that required more back-end resources than this one. It's time to take a step back and reevaluate! Maybe the production template does not fit my project's needs. Where do I begin? Do I just guess?
Thankfully AWS provides a pricing calculator: https://calculator.aws/, I will use this extensively to figure out ways to reduce the bill.
📝 Configure the price calculator:
The first step is to replicate and configure the service in the calculator.
- AWS service: Amazon RDS for PostgreSQL
- region: us-east-1
- instance: db.m5.xlarge (vCPU: 4, Memory: 16 GiB)
- storage: 100 GiB
- provisioned IOPS: 3000
- Multi-AZ: Yes, secondary zone us-east-1b
The calculator is useful because I can see the breakdown of the price, I can interact with different configurations to see the price difference, and it provides links to documentation to learn more about the terms and prices. After putting in my config I see that it adds up close to the actual bill. Now I can start my cost-saving journey.
🔎 Examine the bill:
First, take a look at the bill in the AWS console. It provides an itemized receipt to help pinpoint the different options I can look to scale down or remove.
RDS Proxy - This project stack uses AWS Serverless Lambdas. That means each lambda function call makes a database connection, and due to the nature of lambdas they can scale to tens of thousands of concurrent connections using database resources. Each database connection consumes memory and CPU resources. An RDS Proxy automatically handles the db connection pools. (https://aws.amazon.com/blogs/compute/using-amazon-rds-proxy-with-aws-lambda)
- Since our stack uses Serverless RDS Proxy is required.
Multi-AZ instance - A redundancy option to synchronously replicate the database into a different availability zone. For example, if us-east-1a fails, it'll fall back to us-east-1b.
- Note that region failover provides an extra instance so 2X the cost. However, for a production environment reliability is necessary.
Hardware - AWS has different instance tiers of computation power, memory, and bandwidth. There are different focuses such as general purpose for diverse workloads, memory optimized for processing large data sets, and burstable to burst above a baseline hardware spec for increased loads.
- Based on monitoring, the database never hits the CPU limit so I can try lowering the tier from db.m5.xlarge to db.m5.large.
Storage - AWS has different storage types: general purpose is charged for storage provision, IOPS focuses on input and output capacity, and magnetic previous generation storage for backward compatibility.
- The default was set to IOPS which is really expensive. IOPS is meant for intensive read/write per second. Currently, the app only hits a max of 3 IOPS. I can try switching the storage type to General SSD.
- General SSD does provide IOPS at the rate of 3x the size, so 100 GB/month will provide 300 IOPS included in the price. (https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_Storage.html)
🛠️ Tweaking the settings:
After examining the bill I've decided to make two changes:
- Lower the instance tier db.m5.xlarge @ 4 cpus, 16 gig, 4750 mbps to db.m5.large @ 2 cpus, 8 gig, 4750 mbps
- Change storage type from IOPS @ 3000 IOPS to General SSD @ 100 GB per month
The calculator dropped from $1,144.76 to $259.88, saving $884.88 (77%)!
After making the two changes, I can see that the bill was reduced from $1275.39 to $239.93 (81%) after a month with the new configuration! I've also monitored and looked at the metrics never reaching the hardware limits.
It's totally worth utilizing the calculator and exploring other configurations to reduce costs. Even if the project cost is right, it's still an excellent exercise to take a second to evaluate the costs.