Skip to content

Instantly share code, notes, and snippets.

@turtlemonvh
Created February 3, 2018 17:54
Show Gist options
  • Save turtlemonvh/852101dc206f9ee9d954cb425f56ad5e to your computer and use it in GitHub Desktop.
Save turtlemonvh/852101dc206f9ee9d954cb425f56ad5e to your computer and use it in GitHub Desktop.
Compare the hourly price for RDS vs EC2 instances
## Instance pricing per hour
# The following variables should already be set
# - ec2_pricing, postgres_pricing, postgres_pricing_ar, mysql_pricing_ar
# An easy way create these is to grab the tables off the page and use the %paste function in ipython to set the variables
# From the following lists:
# https://aws.amazon.com/ec2/pricing/on-demand/
# https://aws.amazon.com/rds/postgresql/pricing/
# https://aws.amazon.com/rds/aurora/pricing/
# Turn blocks of text into dictionaries with instance type as key and price per hour as the value
ec2_pricing_d = dict((p[0], float(p[-3].lstrip("$"))) for p in [l.split() for l in ec2_pricing.split("\n") if len(l)])
postgres_pricing_d = dict((k, float(v.lstrip("$"))) for (k,v) in [l.split() for l in postgres_pricing.split("\n")])
postgres_pricing_ar_d = dict((k, float(v.lstrip("$"))) for (k,v) in [l.split() for l in postgres_pricing_ar.split("\n")])
mysql_pricing_ar_d = dict((k, float(v.lstrip("$"))) for (k,v) in [l.split() for l in mysql_pricing_ar.split("\n")])
# Join prices for all categores
price_comparisons = [(k, [ ec2_pricing_d.get(k, 0), postgres_pricing_d.get(j,0), postgres_pricing_ar_d.get(j,0), mysql_pricing_ar_d.get(j,0) ]) for k,j,v in [(k, 'db.'+k, v) for k,v in ec2_pricing_d.items() ] ]
# Filter out and calculate relative cost (using EC2 as a baseline)
price_comparisons_f = [(item,pl,[float(p)/pl[0] for p in pl]) for item,pl in price_comparisons if sum((1 if p>0 else 0) for p in pl) > 1 ]
# Print prices
# Order is: ec2, RDS Postgres, RDS Aurora Postgres, RDS Aurora MySQL
for i, p, rp in price_comparisons_f:
print("{:15} {:5.3f} {:5.3f} {:5.3f} {:5.3f}".format(i, *p))
# Print relative prices
for i, p, rp in price_comparisons_f:
print("{:15} {:5.3f} {:5.3f} {:5.3f} {:5.3f}".format(i, *rp))

RDS Pricing Markup

Looking at what the markup is on per-hour price of on-demand RDS instances vs on-demand EC2 instances.

See the python code for the analysis.

In the columns below

  • ec2 = base EC2 instances from us-east-1
  • p = RDS Postgres flavor
  • a-p = RDS Aurora Postgres flavor
  • a-my = RDS Aurora MySQL flavor

Prices

Instance class  ec2   p     a-p   a-my
r4.8xlarge      2.128 4.000 4.640 4.640
r4.large        0.133 0.250 0.290 0.290
m4.xlarge       0.200 0.365 0.000 0.000
r3.large        0.166 0.250 0.000 0.290
r4.4xlarge      1.064 2.000 2.320 2.320
m4.10xlarge     2.000 3.654 0.000 0.000
t2.large        0.093 0.145 0.000 0.000
m3.large        0.133 0.195 0.000 0.000
r3.8xlarge      2.660 3.980 0.000 4.640
t2.xlarge       0.186 0.290 0.000 0.000
r4.2xlarge      0.532 1.000 1.160 1.160
r3.2xlarge      0.665 0.995 0.000 1.160
t2.medium       0.046 0.073 0.000 0.082
r3.xlarge       0.333 0.500 0.000 0.580
m4.16xlarge     3.200 5.844 0.000 0.000
t2.small        0.023 0.036 0.000 0.041
m3.xlarge       0.266 0.390 0.000 0.000
m3.2xlarge      0.532 0.775 0.000 0.000
r4.16xlarge     4.256 8.000 9.280 9.280
t2.2xlarge      0.371 0.580 0.000 0.000
t2.micro        0.012 0.018 0.000 0.000
m4.large        0.100 0.182 0.000 0.000
r3.4xlarge      1.330 1.990 0.000 2.320
m4.4xlarge      0.800 1.461 0.000 0.000
m4.2xlarge      0.400 0.730 0.000 0.000
r4.xlarge       0.266 0.500 0.580 0.580
m3.medium       0.067 0.095 0.000 0.000

Relative prices

Instance class  ec2   p     a-p   a-my
r4.8xlarge      1.000 1.880 2.180 2.180
r4.large        1.000 1.880 2.180 2.180
m4.xlarge       1.000 1.825 0.000 0.000
r3.large        1.000 1.506 0.000 1.747
r4.4xlarge      1.000 1.880 2.180 2.180
m4.10xlarge     1.000 1.827 0.000 0.000
t2.large        1.000 1.562 0.000 0.000
m3.large        1.000 1.466 0.000 0.000
r3.8xlarge      1.000 1.496 0.000 1.744
t2.xlarge       1.000 1.562 0.000 0.000
r4.2xlarge      1.000 1.880 2.180 2.180
r3.2xlarge      1.000 1.496 0.000 1.744
t2.medium       1.000 1.573 0.000 1.767
r3.xlarge       1.000 1.502 0.000 1.742
m4.16xlarge     1.000 1.826 0.000 0.000
t2.small        1.000 1.565 0.000 1.783
m3.xlarge       1.000 1.466 0.000 0.000
m3.2xlarge      1.000 1.457 0.000 0.000
r4.16xlarge     1.000 1.880 2.180 2.180
t2.2xlarge      1.000 1.562 0.000 0.000
t2.micro        1.000 1.552 0.000 0.000
m4.large        1.000 1.820 0.000 0.000
r3.4xlarge      1.000 1.496 0.000 1.744
m4.4xlarge      1.000 1.826 0.000 0.000
m4.2xlarge      1.000 1.825 0.000 0.000
r4.xlarge       1.000 1.880 2.180 2.180
m3.medium       1.000 1.418 0.000 0.000

Storage costs

In pricing comparisons you should also consider storage costs. The pricing for MySQL and Postgres RDS instance are the same, as are both flavors of Aurora. Aurora uses a very different pricing model than normal RDS, based off usage instead of privisioned storage (so less like EC2).

For Aurora:

  • Storage Rate $0.10 per GB-month
  • I/O Rate $0.20 per 1 million requests
  • Backup storage is free up to size of depoyed database, extra is based on S3 rates
  • The cost of Multi-AZ deployments is simply the cost of the primary instance plus the cost of each Amazon Aurora Replica.
  • You pay only for the storage and IOs your Amazon Aurora database consumes and do not need to provision in advance.

For MySQL:

  • General purpose SSDs
    • single AZ
      • $0.115 per GB-month
    • Multi-AZ
      • $0.23 per GB-month
  • Provisioned IOPS are extra
    • single AZ
      • $0.125 per GB-month
      • $0.10 per IOPS-month
    • multi AZ
      • $0.25 per GB-month
      • $0.20 per IOPS-month
  • Additional backup storage for your provisioned database storage is billed at $0.095 per GB-month

For Postgres:

  • General purpose SSDs
    • single AZ
      • $0.115 per GB-month
    • Multi-AZ
      • $0.23 per GB-month
  • Provisioned IOPS are extra
    • single AZ
      • $0.125 per GB-month
      • $0.10 per IOPS-month
    • multi AZ
      • $0.25 per GB-month
      • $0.20 per IOPS-month
  • Additional backup storage for your provisioned database storage is billed at $0.095 per GB-month
@turtlemonvh
Copy link
Author

A few helpful articles mention addition points of comparison to consider when selecting between EC2 and RDS.

https://serverguy.com/comparison/pros-cons-rds-vs-ec2-mysql-aws/

  • ease of sizing up and down
  • ease of setting up read replicas
  • patching and updates
  • backups (schedules backups + point in time restores)
  • small performance boost on RDS vs similar EC2 instances

https://blog.pythian.com/mysql-aws-rds-vs-ec2/

  • less flexibility on RDS
  • RDS is easy to set up, but lacks some features like storage engine support and more complex replication topologies

https://medium.com/aubergine-solutions/comparing-rds-vs-ec2-for-postgresql-db-b2ca45c14b55

  • Amazon RDS sends metrics to CloudWatch every minute at no additional charge
  • Easy integration with KMS for encryption

@turtlemonvh
Copy link
Author

turtlemonvh commented Jul 8, 2019

Note that some of these numbers have changed.

One that jumps out to me: Aurora backup is now just $0.021/gb-mo in us-east-1 (https://aws.amazon.com/rds/aurora/pricing/), which is the same price per GB that you get for S3 when storing >500 TB! RDS storage for the other engines is close to EBS pricing, which is closer to $0.10/GB-month.

I mentioned before that it was charged at S3 rates, but they seem to have made the pricing simpler and set that up at a discount.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment