It seems like a strange thing to come across, but sometimes when you are dealing with clients who are utilizing Amazon Web Services (AWS) for their resources, you find wasted opportunities to save money. Sometimes it is nervousness about performance and over-sizing their instances, or not understanding the size and needs of their databases.
Where I see the easiest way to save that often isn't taken advantage of is with what is called Reserved Instances.
AWS Reserved Instances
The name alone might inspire confusion. In some cases, "Reserved" typically means that you are reserving resources by paying some amount in case you need it later, or it might imply that you are paying extra to reserve dedicated resources for the execution of your instance and not run on resources shared with other users - the latter does exist, but those are called "Dedicated Hosts".
In AWS, a Reserved Instance basically means that you commit in advance for one or three years to receive a discount on the cost of running the instance. In a way you are reserving that particular instance type, but you are actually paying less over the lifetime of the instance. You have different options as well - you can commit but still pay monthly, pay partially up-front and a lower monthly cost, or pay all up-front and not pay anything monthly for the maximum discount.
Here is the main confusion that often keeps people from committing to paying up front - you don't commit for a specific instance (i.e. a VM, like a web server), but rather just an instance type (say, an "m5.large"). You are only committing to pay for that instance type for the time period, whether you run it or not. This is probably best explained by example. Let's start with the basics.
Let's say I have 3 Linux instances - web server, which is a "t3.large", an application server which is an "m5.large", and a database which is an "r5.large", all in the us-east-1 region. Using current on-demand pricing, my average monthly cost (using 730 hours for the calculation) for the instances would be $60.77 + $70.08 + $91.98 = $222.83. After 12 months I would pay $2,673.96.
If I'm confident that I will run those specific instance types for 12 months, I can pre-pay fully up-front for all three for one year and pay $35.50 + $41.75 + $54.08 = $131.33 per month or $1,576.00 per year. That's a 41% savings for the year!
If I want to commit to three years, the amounts per month are $823 + $968 + $1,307 = $3,098.00 per year versus an on-demand cost of $8,021.88 - that's a savings of $4,923.88 or over 61%!
To add some flexibility, AWS now treats Reserved Instances within a given instance family (say, "t3"), as a number of "units" of compute power, with a "small" equaling 1 unit, a "medium" as 2 units etc. and follows roughly the amount of compute power doubling that the instances have - for instance, a "2xlarge" is 16 units since it is roughly 16x the power of a small. In the “t” series, a micro is 0.5 and a nano is 0.25. When it comes time to allocate the Reserved Instance savings against your monthly bill, the units are computed for what you have run and then the discounts are applied based on what you purchased. If, for example, we had a RI for a "t3.2xlarge", we could run one "t3.2xlarge", or two "t3.xlarge", or sixteen "t3.small" instances! Note this “flexible” option does not currently apply to any Windows OS instances, RHEL or SLES Linux instances, or for dedicated or "g4" instances.
What it doesn't allow is for you to change the instance family of a Reserved Instance. Let's say you've reserved an older "t2" instance, but the "t3" instances are slightly faster and have some newer features such as enhanced networking. Assuming the underlying OS has everything it needs to run on the new instance type, all it usually takes is a reboot to change types - but unfortunately, if you paid for a standard reserved instance of "t2", you then start paying on-demand pricing on the "t3" instance and the "t2" reservation goes unused, unless you create a new instance. For that reason, if I'm getting long-term reservations, before the reservations are up, I plan for a "technology upgrade", just as if I knew I had to replace physical hardware, and when I renew the reservations I reserve the latest instance type.
To be a bit more flexible, AWS now offers what are called "Convertible Reserved Instances". These are like the standard RIs, but have a smaller discount, if you decide to change instance family or OS. At any time you can convert a convertible RI as long as the new one is for an equal or greater cost - so if I had a convertible "t3.xlarge" RI, and decided I needed a full "m5.xlarge" instead, I can just pay the difference.
With all this it can still be a bit confusing. My recommendation is to reserve your production systems 100%, as they aren't likely to be replaced frequently. Evaluate the remaining instances and the instance types they are using and try to predict how long those instance types and quantity will be used - it doesn't necessarily matter what they do, but how many would exist at any given time, and reserve those. Even if it's not perfect, say within 10%, you'd still be saving significant money compared to on-demand pricing.
For environments such as agile development where there are systems that are start up and then shut down after a short amount of time when the work is done, it may not be worth trying to figure out the reservations as they may not exist long enough for a discount to be worth it.
AWS Cost Explorer
To help you out, the AWS Cost Explorer has a section on Reservations, with several options.
“Utilization Report” will tell you what reservations you have and if any are under 100%, which means you can spin up more instances of that type without added on-demand costs. The report still breaks things down by instance size per reservation, so if you reserved 4 “m5.large” and 2 “m5.small”, they will appear as separate line items. The report also defaults to a “Last 3 months” view and reports unused capacity in hours, but if I’m trying to figure out how much capacity I really have available I like to shorten the time frame to one day (click on the time range, find the day you want to check and double-click it to set the range to just that day), and choose “Normalized Units” (if flexible units apply as stated above). I would then add up all the values in the “Normalized Units Unused” column for a given type (like “m5.*”), and then divide by 24 (because the number still represents days, while “1 unit” represents 1 hour of runtime of a “small” unit). Then I know how many units I can still run…if it is 2, I can run a “medium” unit, or 2 “smalls” etc. Keep in mind that reservations are region-specific, and this report will list line items in all regions by default but there are filters you can add.
“Coverage Report” flips that and tells you how many hours/units you are running overall, and then tells you how much of that is covered by reservations, and how much is on-demand. It even tells you how much you are paying in on-demand cost over the period. This will tell you where you might be able to save more money to help you evaluate how much you want to reserve.
In addition, there is a “Recommendations” report that will advise you on what you should purchase for reservations and how much you may save. You should look at this report very closely, however, and make your own determinations since it does not know what instances may be temporary or other factors that can play a role.
I hope you now understand AWS Reserved Instances better and are now ready to tell your bosses how you can save money! If you would like to discuss further, please contact us.