Frank’s AWS Pricing Investigation

Summary tables

Intro

At Strategic Blue, we care about the money, and we’ve been collecting prices of AWS and other cloud vendors for a while. Another characteristic of Strategic Blue is that we are curious and love digging into the numbers, checking common assumptions, and find new ways to save money.

  • The first article in the series focused on finding the cost of Windows on AWS and make some basic comparison with Azure
  • second article show an anomaly in AWS pricing probably due to a human error

This article extends on those researches to split AWS pricing into three components:

  1. the cost of the infrastructure
  2. the cost of the OS licence
  3. the cost of the software (SQL Server) license running on those instances

This is based only on EC2 data but could be replicated on other AWS services.

Note that for all tables there are some exceptions which are covered at the end of this article

Executive Summary

  • All the pricing are consistent, showing great care on AWS part to charge consistently in each region
  • There are lots of little exceptions that seem to be more human errors in entering the data

POMO

Purpose: to find if a good approximation of the cost of the infrastructure, Os, and software licensing on AWS
Objective: being able to separate infrastructure and licensing costs
Method: SQL queries on AWS pricing table
Outcome: A set of tables license price list for AWS

Assumptions:

  • Work is done on shared instances
  • the infrastructure cost is the cost of a Linux VM
  • The OS cost is instance price inc. OS – Linux instance price
  • The Software cost is the hourly price – infrastructure price – os license price
  • Based on April 2020 prices

Other possible experiments:

  • check RI pricing logic – are RI calculated on the infrastructure cost then a license is added
  • try to extract the different components of the infrastructure by making assumptions
  • improve the queries
  • make this analysis automated
  • play with the estimated cost of DC supply (e.g. real-estate, electricity) between regions

Summary tables

Linux

is always 0 and is considered the price of the infrastructure.

Suse

SUSE being not standard the list is long

gensizeososlicprice
m410xlargeSUSE0.100
c512xlargeSUSE0.100
c5d12xlargeSUSE0.100
g4dn12xlargeSUSE0.150
i3en12xlargeSUSE0.150
m512xlargeSUSE0.100
m5a12xlargeSUSE0.150
m5ad12xlargeSUSE0.150
m5d12xlargeSUSE0.100
m5dn12xlargeSUSE0.150
m5n12xlargeSUSE0.150
m6g12xlargeSUSE0.150
r512xlargeSUSE0.150
r5a12xlargeSUSE0.150
r5ad12xlargeSUSE0.150
r5d12xlargeSUSE0.150
r5dn12xlargeSUSE0.150
r5n12xlargeSUSE0.150
z1d12xlargeSUSE0.150
f116xlargeSUSE0.100
g316xlargeSUSE0.100
g4dn16xlargeSUSE0.150
h116xlargeSUSE0.100
i316xlargeSUSE0.100
m416xlargeSUSE0.100
m516xlargeSUSE0.100
m5a16xlargeSUSE0.150
m5ad16xlargeSUSE0.150
m5d16xlargeSUSE0.100
m5dn16xlargeSUSE0.150
m5n16xlargeSUSE0.150
m6g16xlargeSUSE0.150
p216xlargeSUSE0.100
p316xlargeSUSE0.100
r416xlargeSUSE0.100
r516xlargeSUSE0.150
r5a16xlargeSUSE0.150
r5ad16xlargeSUSE0.150
r5d16xlargeSUSE0.150
r5dn16xlargeSUSE0.150
r5n16xlargeSUSE0.150
x116xlargeSUSE0.100
x1e16xlargeSUSE0.100
c518xlargeSUSE0.100
c5d18xlargeSUSE0.100
c5n18xlargeSUSE0.150
c524xlargeSUSE0.100
c5d24xlargeSUSE0.100
i3en24xlargeSUSE0.150
inf124xlargeSUSE0.150
m524xlargeSUSE0.100
m5a24xlargeSUSE0.150
m5ad24xlargeSUSE0.150
m5d24xlargeSUSE0.100
m5dn24xlargeSUSE0.150
m5n24xlargeSUSE0.150
p3dn24xlargeSUSE0.150
r524xlargeSUSE0.150
r5a24xlargeSUSE0.150
r5ad24xlargeSUSE0.150
r5d24xlargeSUSE0.150
r5dn24xlargeSUSE0.150
r5n24xlargeSUSE0.150
a12xlargeSUSE0.150
c42xlargeSUSE0.100
c52xlargeSUSE0.100
c5d2xlargeSUSE0.100
c5n2xlargeSUSE0.150
d22xlargeSUSE0.100
f12xlargeSUSE0.100
g4dn2xlargeSUSE0.150
h12xlargeSUSE0.100
i32xlargeSUSE0.100
i3en2xlargeSUSE0.150
inf12xlargeSUSE0.150
m42xlargeSUSE0.100
m52xlargeSUSE0.100
m5a2xlargeSUSE0.150
m5ad2xlargeSUSE0.150
m5d2xlargeSUSE0.100
m5dn2xlargeSUSE0.150
m5n2xlargeSUSE0.150
m6g2xlargeSUSE0.150
p32xlargeSUSE0.100
r42xlargeSUSE0.100
r52xlargeSUSE0.150
r5a2xlargeSUSE0.150
r5ad2xlargeSUSE0.150
r5d2xlargeSUSE0.150
r5dn2xlargeSUSE0.150
r5n2xlargeSUSE0.150
t22xlargeSUSE0.100
t32xlargeSUSE0.150
t3a2xlargeSUSE0.150
x1e2xlargeSUSE0.100
z1d2xlargeSUSE0.150
x132xlargeSUSE0.100
x1e32xlargeSUSE0.100
i3en3xlargeSUSE0.150
z1d3xlargeSUSE0.150
a14xlargeSUSE0.150
c44xlargeSUSE0.100
c54xlargeSUSE0.100
c5d4xlargeSUSE0.100
c5n4xlargeSUSE0.150
d24xlargeSUSE0.100
f14xlargeSUSE0.100
g34xlargeSUSE0.100
g4dn4xlargeSUSE0.150
h14xlargeSUSE0.100
i34xlargeSUSE0.100
m44xlargeSUSE0.100
m54xlargeSUSE0.100
m5a4xlargeSUSE0.150
m5ad4xlargeSUSE0.150
m5d4xlargeSUSE0.100
m5dn4xlargeSUSE0.150
m5n4xlargeSUSE0.150
m6g4xlargeSUSE0.150
r44xlargeSUSE0.100
r54xlargeSUSE0.150
r5a4xlargeSUSE0.150
r5ad4xlargeSUSE0.150
r5d4xlargeSUSE0.150
r5dn4xlargeSUSE0.150
r5n4xlargeSUSE0.150
x1e4xlargeSUSE0.100
i3en6xlargeSUSE0.150
inf16xlargeSUSE0.150
z1d6xlargeSUSE0.150
c48xlargeSUSE0.100
d28xlargeSUSE0.100
g38xlargeSUSE0.100
g4dn8xlargeSUSE0.150
h18xlargeSUSE0.100
i38xlargeSUSE0.100
m58xlargeSUSE0.100
m5a8xlargeSUSE0.150
m5ad8xlargeSUSE0.150
m5d8xlargeSUSE0.100
m5dn8xlargeSUSE0.150
m5n8xlargeSUSE0.150
m6g8xlargeSUSE0.150
p28xlargeSUSE0.100
p38xlargeSUSE0.100
r48xlargeSUSE0.100
r58xlargeSUSE0.150
r5a8xlargeSUSE0.150
r5ad8xlargeSUSE0.150
r5d8xlargeSUSE0.150
r5dn8xlargeSUSE0.150
r5n8xlargeSUSE0.150
x1e8xlargeSUSE0.100
c59xlargeSUSE0.100
c5d9xlargeSUSE0.100
c5n9xlargeSUSE0.150
a1largeSUSE0.063
c4largeSUSE0.100
c5largeSUSE0.100
c5dlargeSUSE0.100
c5nlargeSUSE0.063
i3largeSUSE0.100
i3enlargeSUSE0.063
m4largeSUSE0.100
m5largeSUSE0.100
m5alargeSUSE0.063
m5adlargeSUSE0.063
m5dlargeSUSE0.100
m5dnlargeSUSE0.063
m5nlargeSUSE0.063
m6glargeSUSE0.063
r4largeSUSE0.100
r5largeSUSE0.063
r5alargeSUSE0.063
r5adlargeSUSE0.063
r5dlargeSUSE0.063
r5dnlargeSUSE0.063
r5nlargeSUSE0.063
t2largeSUSE0.100
t3largeSUSE0.063
t3alargeSUSE0.063
z1dlargeSUSE0.063
a1mediumSUSE0.031
m6gmediumSUSE0.031
t2mediumSUSE0.100
t3mediumSUSE0.063
t3amediumSUSE0.063
t2microSUSE0.010
t2microSUSE0.012
t2microSUSE0.100
t3microSUSE0.000
t3amicroSUSE0.000
t2nanoSUSE0.010
t2nanoSUSE0.011
t2nanoSUSE0.100
t3nanoSUSE0.000
t3ananoSUSE0.000
t2smallSUSE0.030
t2smallSUSE0.034
t2smallSUSE0.100
t3smallSUSE0.031
t3asmallSUSE0.031
a1xlargeSUSE0.125
c4xlargeSUSE0.100
c5xlargeSUSE0.100
c5dxlargeSUSE0.100
c5nxlargeSUSE0.125
d2xlargeSUSE0.100
g3sxlargeSUSE0.125
g4dnxlargeSUSE0.125
i3xlargeSUSE0.100
i3enxlargeSUSE0.125
inf1xlargeSUSE0.125
m4xlargeSUSE0.100
m5xlargeSUSE0.100
m5axlargeSUSE0.125
m5adxlargeSUSE0.125
m5dxlargeSUSE0.100
m5dnxlargeSUSE0.125
m5nxlargeSUSE0.125
m6gxlargeSUSE0.125
p2xlargeSUSE0.100
r4xlargeSUSE0.100
r5xlargeSUSE0.125
r5axlargeSUSE0.125
r5adxlargeSUSE0.125
r5dxlargeSUSE0.125
r5dnxlargeSUSE0.125
r5nxlargeSUSE0.125
t2xlargeSUSE0.100
t3xlargeSUSE0.125
t3axlargeSUSE0.125
x1exlargeSUSE0.100
z1dxlargeSUSE0.125
SELECT  gen, size, os, oslicprice
    FROM public.v_aws_infra_os_sfw
    where os = 'SUSE'
    group by gen, size, os, oslicprice
    order by size, gen, oslicprice
    ;

RedHat

sizeososlicprice
10xlargeRHEL0.130
12xlargeRHEL0.130
16xlargeRHEL0.130
18xlargeRHEL0.130
24xlargeRHEL0.130
2xlargeRHEL0.130
32xlargeRHEL0.130
3xlargeRHEL0.130
4xlargeRHEL0.130
6xlargeRHEL0.130
8xlargeRHEL0.130
9xlargeRHEL0.130
largeRHEL0.060
mediumRHEL0.060
microRHEL0.060
smallRHEL0.060
xlargeRHEL0.060

For an unknown reason (mistake?) the r4.xlarge costs $0.13 when for all other families the price for xlarge is .06

gensizeoslicprice
r4xlarge0.130
SELECT  size, os, oslicprice
    FROM public.v_aws_infra_os_sfw
    where os = 'RHEL'
    group by size, os, oslicprice
    order by size, oslicprice
    ;

windows

sizeososlicpricecount
10xlargeWindows1.84015
12xlargeWindows2.208240
16xlargeWindows2.944291
18xlargeWindows3.31250
24xlargeWindows4.416214
2xlargeWindows0.368335
32xlargeWindows5.88827
3xlargeWindows0.55227
4xlargeWindows0.736309
6xlargeWindows1.10427
8xlargeWindows1.472261
9xlargeWindows1.65650
largeWindows0.092291
xlargeWindows0.184340
SELECT  size, os, oslicprice, COUNT(*)
    FROM public.v_aws_infra_os_sfw
    where os = 'Windows'
    AND software = 'NA'
    AND gen NOT LIKE 't%'
    AND gen NOT LIKE 'd2'
    AND gen NOT LIKE 'c4'
    group by size, os, oslicprice
    order by size, oslicprice
    ;

anomalies

d2 are priced differently

sizeososlicpricecount
2xlargeWindows0.2218
2xlargeWindows0.36810
4xlargeWindows0.3028
4xlargeWindows0.73610
8xlargeWindows0.6788
8xlargeWindows1.65610
xlargeWindows0.1318
xlargeWindows0.18410

c4.8xlarge are priced differently

sizeososlicpricecount
8xlargeWindows1.5003
8xlargeWindows1.5231
8xlargeWindows1.5431
8xlargeWindows1.65610

SQL Web

sizesoftwaresfwpricecpucounting
largeSQL Web0.072597
xlargeSQL Web0.074656
2xlargeSQL Web0.148652
4xlargeSQL Web0.2716557
4xlargeSQL Web0.281660
6xlargeSQL Web0.412456
8xlargeSQL Web0.5432420
8xlargeSQL Web0.563235
9xlargeSQL Web0.6136100
10xlargeSQL Web0.684015
12xlargeSQL Web0.8148480
16xlargeSQL Web1.0864450
16xlargeSQL Web1.136449
18xlargeSQL Web1.2272100
24xlargeSQL Web1.6296422
32xlargeSQL Web2.1612839

The query ignore when the number of occurrence of a price are < 12, this eliminates most strange behaviour in the pricing.

SELECT t1.size, software, ROUND(sfwprice,2) sfwprice, cpu, count(*) counting
    FROM public.v_aws_infra_os_sfw t1 JOIN aws_size2cpu t2 ON t1.size = t2.size
    where software = 'SQL Web'
    AND current_generation = 'Yes'
    AND gen NOT LIKE 't%'
    GROUP BY software, t1.size, cpu,  ROUND(sfwprice,2)
    HAVING count(*)  > 12
    ORDER BY cpu, software, sfwprice,  counting desc
    ;

Anomalies

There are some Negative SQL Web pricing making it cheaper to get a Windows + SQL Web versus Windows only

regionsizeososlicpricesfwpricecount
Asia Pacific (Sydney)2xlargeWindows0.368-0.1131
EU (Frankfurt)2xlargeWindows0.368-0.1131
EU (Ireland)2xlargeWindows0.368-0.1131
US East (N. Virginia)2xlargeWindows0.368-0.1131
US East (Ohio)2xlargeWindows0.368-0.1131
US West (N. California)2xlargeWindows0.368-0.1131
US West (Oregon)2xlargeWindows0.368-0.1131
SELECT  region, size, os, oslicprice, sfwprice, COUNT(*)
    FROM public.v_aws_infra_os_sfw
    where os = 'Windows'
    AND software = 'SQL Web'
    AND gen LIKE 'r4'
    AND size = '2xlarge'
    AND sfwprice < 0
    group by size, os, oslicprice, sfwprice, region
    order by size, oslicprice
    ;

SQL Standard

sizesoftwaresfwpricecpucounting
largeSQL Std0.482597
xlargeSQL Std0.484657
2xlargeSQL Std0.968665
4xlargeSQL Std1.9216607
6xlargeSQL Std2.882456
8xlargeSQL Std3.8432454
9xlargeSQL Std4.3236100
10xlargeSQL Std4.804030
12xlargeSQL Std5.7648479
16xlargeSQL Std7.6864510
18xlargeSQL Std8.6472100
24xlargeSQL Std11.5296422
32xlargeSQL Std15.3612854

The query ignore when the number of occurrence of a price are < 12, this eliminates most strange behaviour in the pricing.

SELECT t1.size, software, ROUND(sfwprice,2) sfwprice, cpu, count(*) counting
    FROM public.v_aws_infra_os_sfw t1 JOIN aws_size2cpu t2 ON t1.size = t2.size
    where software = 'SQL Std'
    AND current_generation = 'Yes'
    AND gen NOT LIKE 't%'
  AND gen NOT LIKE 'd2'
    GROUP BY software, t1.size, cpu,  ROUND(sfwprice,2)
    HAVING count(*)  > 12
    ORDER BY cpu, software, sfwprice,  counting desc
    ;
SELECT  size, os, oslicprice, COUNT(*)
    FROM public.v_aws_infra_os_sfw
    where os = 'Windows'
    AND software = 'NA'
    AND gen LIKE 'c4'
    AND size = '8xlarge'
    group by size, os, oslicprice
    order by size, oslicprice
    ;

SQL Enterprise

sizesoftwaresfwpricecpucounting
xlargeSQL Ent1.504700
2xlargeSQL Ent3.008708
4xlargeSQL Ent6.0016650
6xlargeSQL Ent9.002456
8xlargeSQL Ent12.0032455
8xlargeSQL Ent13.503244
9xlargeSQL Ent13.5036100
10xlargeSQL Ent15.004030
12xlargeSQL Ent18.0048480
16xlargeSQL Ent24.0064512
18xlargeSQL Ent27.0072100
24xlargeSQL Ent36.0096422
32xlargeSQL Ent48.0012854

The query ignore when the number of occurrence of a price are < 12, this eliminates most strange behaviour in the pricing.

SELECT t1.size, software, ROUND(sfwprice,2) sfwprice, cpu, count(*) counting
    FROM public.v_aws_infra_os_sfw t1 JOIN aws_size2cpu t2 ON t1.size = t2.size
    where software = 'SQL Ent'
    AND current_generation = 'Yes'
    AND gen NOT LIKE 't%'
    GROUP BY software, t1.size, cpu,  ROUND(sfwprice,2)
    HAVING count(*)  > 12
    ORDER BY cpu, software, sfwprice,  counting desc
    ;

Infrastructure

The price per CPU per generation seems consistent. Here is a summary table (the big one is 1.2M of text)

genLowest priceMean priceMax priceStandard Deviation (smaller is better)
a10.0130.0250.0330.006
c40.0500.0580.0780.007
c50.0430.0500.0660.006
c5d0.0480.0570.0750.006
c5n0.0540.0610.0710.006
d20.1730.1980.2390.018
f10.2060.2220.2480.016
g30.0710.0880.1100.013
g3s0.1880.2270.2890.034
g4dn0.0680.1050.2240.031
h10.0590.0600.0650.003
i30.0780.0910.1250.010
i3en0.1130.1310.1800.015
inf10.0730.0810.0920.007
m40.0500.0590.0800.007
m50.0480.0570.0770.007
m5a0.0280.0490.0690.009
m5ad0.0340.0600.0830.010
m5d0.0570.0670.0900.008
m5dn0.0680.0760.0880.008
m5n0.0600.0670.0770.007
m6g0.0190.0360.0390.007
p20.2250.3250.4300.083
p30.3830.4560.5290.061
p3dn0.3250.3620.4460.051
r40.0670.0790.1400.017
r50.0630.0730.1010.008
r5a0.0360.0640.0910.011
r5ad0.0420.0740.1040.013
r5d0.0720.0840.1140.009
r5dn0.0840.0920.1020.008
r5n0.0750.0820.0910.007
t20.0030.0350.0740.022
t30.0030.0330.0670.020
t3a0.0020.0290.0610.017
x10.1040.1360.2030.027
x1e0.2090.2590.4060.045
z1d0.0930.1050.1140.008
SELECT gen, MIN(ROUND(infraprice/t2.cpu,3)) percpuprice_min, ROUND(AVG(infraprice/t2.cpu),3) percpuprice_avg, MAX(ROUND(infraprice/t2.cpu,3)) percpuprice_max, ROUND(stddev_samp(infraprice/t2.cpu),3) percpuprice_standard_deviation
    FROM public.v_aws_infra_os_sfw t1 JOIN aws_size2cpu t2 ON t1.size = t2.size
    where current_generation = 'Yes'
    GROUP BY gen  
    ORDER BY gen
    ;

Related Posts:

About Us

Strategic Blue helps organisations buy cloud on terms to suit their needs, helping them accelerate innovation in the cloud and optimise long-term cloud costs.

Let’s Socialise:

Popular Posts: