instancefinder

What Arm compute actually costs per unit of work

Published

Price per hour is the number on the invoice. Price per unit of work is the number that matters, and the two disagree often enough to be interesting. We benchmarked Arm instances on AWS, Google Cloud and Oracle Cloud on one Ubuntu 24.04 LTS arm64 image and divided the measured composite score by the on-demand price. Three findings do most of the work: the same Ampere Altra chip costs 2.4× more on one cloud than another, a "memory-optimised" AWS instance costs 48% more than its compute-optimised twin while delivering identical memory bandwidth per core, and the cheapest instance in the set is one of the worst buys.

Index per dollar, and how to read it

The index is a composite of 13 metrics drawn from 10 of the suite's 12 test units — integer work, 7-Zip, OpenSSL AES and SHA, STREAM bandwidth, a latency sweep, zstd, a real compile of a pinned zstd release, Redis, nginx behind wrk and a mixed Python workload — normalised so c8g.4xlarge = 100. Divide by the hourly on-demand price and you get performance per dollar.

Two test units are deliberately not in it: fio and the network test. That matters for a cost article. Our disk numbers measure the provisioned ceiling of the attached volume rather than the instance, so if fio were in the index, every price-per-work figure below would be partly pricing a storage tier we chose. It is not. Likewise the network test, which did not run on every shape.

Read this before reading the table. Index per dollar is only comparable between rows with the same vCPU count. The two 4-vCPU rows at the bottom are separated for that reason: AWS prices c8g.xlarge at exactly a quarter of c8g.4xlarge ($0.1595 × 4 = $0.638 against $0.6381), but the composite only rises from 47 to 100 for four times the cores, because it mixes single-thread scores with all-core ones and because bandwidth per vCPU falls as instances get bigger. A 4-vCPU instance therefore always looks like better value on this metric. It is an artefact of the metric, not a discount.

ShapeCloudCorevCPUIndexUSD/hrIndex per $
VM.Standard.A1.FlexociAmpere Altra (N1)16730.2560285
c9g.4xlargeawsNeoverse V3 (Graviton5)161200.6955173
c4a-highcpu-16gcpAxion (Neoverse V2)161000.6061165
c8g.4xlargeawsNeoverse V2 (Graviton4)161000.6381157
c7g.4xlargeawsNeoverse V1 (Graviton3)16840.5800145
c4a-standard-16gcpAxion (Neoverse V2)161040.7184145
m8g.4xlargeawsNeoverse V2 (Graviton4)161010.7181141
t2a-standard-16gcpAmpere Altra (N1)16730.6160119
c8g.xlargeawsNeoverse V24470.1595295
t4g.xlargeawsNeoverse N1, burstable4240.1344179

Within the eight 16-vCPU rows the spread is wide: 285 down to 119, a factor of 2.4 between best and worst. And the ordering is not the ordering of the hourly prices. The most expensive row is not the worst value, and the cheapest-per-hour 16-vCPU instance is by a distance the best.

The same chip for 2.4× the money

The top and bottom of that table are the same processor. Oracle's VM.Standard.A1.Flex and Google's t2a-standard-16 are both Ampere Altra (Neoverse N1), and at 16 vCPU they returned a composite index of 73 on both, identical to within 0.7%. Oracle charges $0.2560 an hour. Google charges $0.6160. Nothing about the silicon explains the gap; it is a pricing decision, and it is the largest single effect in this dataset.

Same silicon, 16 vCPUIndexUSD/hrUSD/month (730 hr)Index per $
oci VM.Standard.A1.Flex730.2560187285
gcp t2a-standard-16730.6160450119

On a 730-hour month that is about $187 against $450 for the same measured throughput, or roughly $3,150 a year of difference on a single instance (a $0.36/hr gap over 8,760 hours). Multiply by a fleet and it stops being a rounding error.

The t2a price is also hard to defend against AWS, never mind Oracle. c8g.4xlarge scores 100 against t2a's 73 — 37% more work — for $0.6381 against $0.6160, about 3.6% more money. There is no workload profile in this data where t2a is the rational pick on price-performance grounds. If you are on it because it was the Arm option in your GCP region, the Axion families are the upgrade: c4a-highcpu-16 is both faster and cheaper, at 100 index for $0.6061.

Two honest qualifications. First, OCI Flex shape prices are computed from Oracle's published per-OCPU and per-GB rates rather than read off a fixed shape price, so they depend on the memory you configure. Second, this compares compute line items, not bills. Egress, support plans, managed services and the cost of operating in a cloud your team does not know are all outside these numbers, and any of them can swallow a 2.4× compute saving. What the data settles is that the compute line item is not close.

Memory-optimised costs 48% more and delivers the same bandwidth per core

Within AWS, the biggest available saving is not a different generation or a different cloud — it is picking the right family, which at a given vCPU count mostly means picking the cheapest one. At 16 vCPU, five Graviton4 families are one machine with different amounts of RAM attached. On the sysbench integer test, single-core results spread by 0.1% across them and all-core by 0.05%; memory bandwidth spreads by 3%. Those first two are one metric rather than the whole test set - the 7-Zip figures from the same runs scatter by 26% single-thread, much of it measurement noise rather than hardware.

ShapeRAMTriad GB/sGB/s per vCPUDRAM nsUSD/hrvs c8g
i8g.4xlarge124 GiB320.720.01291.3728+115%
c8gn.4xlarge31 GiB317.619.91180.9480+49%
r8g.4xlarge124 GiB320.220.01300.9426+48%
m8g.4xlarge62 GiB311.419.51280.7181+13%
c8g.4xlarge31 GiB313.419.61280.6381

The GB/s per vCPU and "vs c8g" columns are derived by us from the two measured columns either side of them: Triad divided by 16, and each price divided by $0.6381. Everything else in the table is measured. The 3% bandwidth spread across the five families is smaller than the 6.6% spread we measured between three instances of one single shape (298.3, 313.4 and 318.8 GB/s on c8g.4xlarge), so it should not be read as a ranking — it is the reason we say these are one machine. A bandwidth difference below about 3% is not supportable from this data, ours included.

So r8g costs 48% more than c8g for identical compute and identical memory bandwidth per vCPU. You are buying capacity, not bandwidth. The name "memory-optimised" describes how much memory you get, not how fast it is, and a lot of instance-sizing folklore quietly assumes otherwise — that the r-family is where you go for memory-bound work. On Graviton4 at 16 vCPU, it is not: the memory-bound instance and the compute-optimised instance pull the same 20 GB/s per core.

The practical rule is unglamorous. Size on memory footprint alone. If your working set fits in 31 GiB, c8g is the whole answer and every other family in that table is a 13% to 115% premium for nothing you can measure with these tests. If it does not fit, step up to the cheapest family that holds it. The two genuine exceptions are c8gn and i8g. c8gn's network advantage is real but conditional on running multiple parallel streams: 2.7× c8g's aggregate at default placement, 3.3× in a cluster group, and nothing at all on a single flow (see the placement and streams article). Then i8g, which is the storage-optimised member — our disk test measured the attached network volume rather than instance-local storage, so nothing here evaluates what its 115% premium buys. Judge i8g on storage behaviour we did not test.

The burstable trap: 16% cheaper for half the work

Burstable instances are the classic false economy, and this run caught one in the act. We launched t4g.xlarge deliberately with CpuCredits=standard — no unlimited-burst billing — so that the result shows what the shape sustains rather than what it does for the first two minutes. Partway through, the credits ran out. Steal time was 0.00% on every AWS and GCP instance in this study, below 0.7% on the OCI shapes, and up to 35.2% on this one (35.16% and 35.05% across two runs).

4 vCPU, AWSCoreIndexStealUSD/hrIndex per $
c8g.xlargeNeoverse V2470.00%0.1595295
t4g.xlargeNeoverse N1, burstable2435.2%0.1344179

The t4g is 16% cheaper per hour ($0.1344 against $0.1595) and delivers 51% of the work (index 24 against 47). Price-performance is 179 against 295. Buying it to save money on a workload that runs continuously is buying 84% of the price for half the throughput.

Two things are worth separating here, because it would be easy to overclaim. Part of the gap is generational: t4g is a Neoverse N1 core and c8g.xlarge is Neoverse V2, two generations newer, so some of the deficit is simply an older chip. The rest is throttling, and steal above 35% is a large, unambiguous chunk of it. We cannot split the two from this data — we did not run a t4g with credits available — and we are not going to guess at the split.

What we can say cleanly is the shape of the mistake. A burstable instance is priced for a duty cycle, and it is only cheap if you actually have one. If your load is genuinely spiky — a dev box, a cron host, a low-traffic service — t4g is a reasonable buy and the credit model works in your favour. If it is a steady-state service, the burstable family is the most expensive way to buy 4 vCPUs of Arm on AWS per unit of work delivered, and the failure mode is silent: the instance does not error, it just gets slower under sustained load, in a way that shows up as latency in your application and not as anything obvious on the bill.

The steal figure describes a throttled machine, which is the point of including it, but it comes from two runs of one shape (35.16% and 35.05%) and the exact percentage will depend on how long you sustain load and how many credits you had banked. Do not read it as a constant. Read it as evidence that the throttle is severe rather than cosmetic.

A generational refresh that got cheaper per unit of work

New generations usually cost more. The interesting question is whether they cost more per unit of work, because vendors routinely price a refresh to capture its own gain. Across three Graviton generations, AWS did not:

ShapeCoreIndexUSD/hrIndex per $
c7g.4xlargeNeoverse V1 (Graviton3)840.5800145
c8g.4xlargeNeoverse V2 (Graviton4)1000.6381157
c9g.4xlargeNeoverse V3 (Graviton5)1200.6955173

Roughly +19% then +20% on performance, and price-performance improving at each step: 145 to 157 to 173. The newest generation costs 9% more than the one before it ($0.6955 against $0.6381) for 20% more measured performance. For a workload you can move with a redeploy, that is the cheapest performance in the AWS Arm lineup, and staying on c7g to save $0.1155 an hour against c9g costs you 30% of the throughput (84 against 120). Against c8g the saving is $0.0581 an hour and the cost is 16% (84 against 100).

One caution against treating this as a blanket "always take the newest". At 16 vCPU, c9g.4xlarge has less aggregate memory bandwidth than c8g.4xlarge164 GB/s against 310 GB/s, so the older shape delivers about 1.9× as much — alongside materially better DRAM latency, 91 ns against 128 ns. Both bandwidth figures are means: 164.2 across two c9g samples spreading 1.4%, and 310.2 across three c8g samples spreading 6.6%.

Be careful how you read that, because it is a property of the shape and not of the core. On single-threaded STREAM, one c9g core gets 34.61 GB/s against one c8g core's 31.92 — the newer core is 8.4% better fed. It is sixteen of them together that reach only about half the aggregate. So this is about how much of the socket a 16-vCPU slice can reach, not about the microarchitecture getting worse. For spending decisions the practical upshot is unchanged: if your cost driver is a bandwidth-bound job at this size, the newer generation can be the worse buy despite costing more, and the composite index will not tell you so. Measure that one yourself.

Scaling up: the price per vCPU is flat, but a vCPU is worth less

AWS prices the c8g family exactly linearly in vCPU count. Every one of the nine sizes we measured divides to $0.03988 per vCPU per hour — from c8g.medium at $0.03988 to c8g.24xlarge at $3.82848, a 96-fold range, exact at every size. Not approximately linear, linear. Per-vCPU CPU throughput is just as flat: all-core integer performance holds at 1245–1249 per vCPU across the whole 1-to-96 vCPU span we measured, which is as clean a scaling result as you will see anywhere.

Memory bandwidth is not linear at all.

ShapevCPUTriad GB/sGB/s per vCPUBW vs 1 vCPUCPU per vCPU
c8g.medium124.124.11.0×1249
c8g.large248.424.22.0×1248
c8g.xlarge494.623.63.9×1248
c8g.2xlarge8168.821.17.0×1248
c8g.4xlarge16310.219.412.8×1248
c8g.8xlarge32363.511.415.1×1248
c8g.12xlarge48385.18.015.9×1247
c8g.16xlarge64385.66.016.0×1247
c8g.24xlarge96416.14.317.2×1245

Ninety-six times the vCPUs buys 17.2 times the bandwidth. Per-vCPU bandwidth falls from 24.1 GB/s to 4.3 — a factor of 5.6 — while the price per vCPU does not move at all. The sharpest illustration is in the middle of the range, not at the end: going from 48 to 64 vCPU buys 0.1% more bandwidth for 33% more cores (385.1 to 385.6 GB/s). Either side of that plateau it is barely better — 32 to 48 gains 6% for 50% more cores, and 64 to 96 gains 8% for 50% more.

So for a bandwidth-bound workload the usual instinct to consolidate onto fewer, larger machines is the expensive direction, and the arithmetic is unusually clean: price per vCPU is exactly constant while bandwidth per vCPU falls 5.6×, so bandwidth per dollar falls by exactly the same 5.6× between 1 and 96 vCPU. Nothing about that is conditional or extrapolated — every size in the table is both measured and priced. Meanwhile, at 4 vCPU and above a single core pulls about 32 GB/s whatever the instance size; below that the instance itself is the constraint, at 28.5 GB/s on 2 vCPU and 24.3 on 1.

Where that ceiling comes from, we cannot say from this data alone, and the small sizes cut against the obvious guess. If a 1-vCPU instance's single thread gets 24.3 GB/s where a 4-vCPU instance's single thread gets 32.1, then at the small end something is limiting the instance rather than the socket. At the large end the flattening curve is consistent with a shared memory subsystem, but consistent is not the same as demonstrated.

There is a real architectural decision buried in this. If your workload is bandwidth-bound and horizontally scalable, several small instances deliver more aggregate bandwidth per dollar than one large one. If it is CPU-bound, the flat 1245–1249 per vCPU means size is genuinely a matter of indifference and you should choose on operational grounds. The mistake is applying the CPU-bound intuition to a bandwidth-bound job.

Caveats specific to this table. Each bandwidth figure is the mean of that shape's corrected samples, which is why c8g.4xlarge reads 310.2 GB/s here against 313.4 in the family table above — the family table quotes a single sample per shape while this curve uses means. (Four of that table's five rows do come from one batch; the c8g control row does not, which is its own reason to read the 3% family spread as noise rather than ranking.) Three c8g.4xlarge instances spread by 6.6% (298.3, 313.4, 318.8), which is worth holding against the per-vCPU column: the 5.6× fall from 24.1 to 4.3 is far larger than that uncertainty, but the step between any two adjacent rows is not, and the 48-to-64 plateau is inside it. The family also has a 192-vCPU c8g.48xlarge, which we did not run, so the curve past 96 vCPU is unknown and we make no claim about it. One more thing a sceptical reader should know, because it is the obvious way a curve like this could be an artefact: the STREAM working set is not identical across the sweep. The suite sizes it against instance memory up to a 3 GiB cap, so it runs 356 MiB at 1 vCPU, 842 MiB at 2, 1,823 MiB at 4 and 3,072 MiB from 8 vCPU upwards. A working set that fitted in cache would inflate the small instances and manufacture exactly this shape of curve — so we checked, and it does not. Every size exceeds its own last-level cache by at least 9.4×, and that ratio is non-monotonic: it peaks around 59× at 8 vCPU and falls away on both sides, to 9.4× at 1 vCPU and 13.5× at 96. So both ends of the curve are the marginal cases, and the 1-vCPU point is the tighter of the two — but it still clears the conventional 4× threshold by better than a factor of two, as do all nine. Every point is DRAM-resident. The working sets still are not strictly like-for-like, which is worth knowing, but the saturation is not a cache effect. The "bandwidth per dollar" conclusion rests on price per vCPU being constant, and that is not a hedge but a measured fact across the range we tested: exact at all nine sizes.

What is not in these prices

Everything above is Linux on-demand, in us-west-2 (AWS), us-central1 (GCP) and us-ashburn-1 (OCI), read on 2026-08-13 and 2026-08-18. Four things sit outside that and can move a decision:

How much to trust these numbers

The limits of the measurement, stated plainly, because a cost analysis built on a shaky benchmark is worse than no cost analysis.

The short version

Four rules, in descending order of how much money they save.

  1. Do not pay for the same chip twice over. Ampere Altra scored 73 on both OCI and GCP, at $0.2560 and $0.6160. If an older Arm core suits your workload, that is the biggest lever in this dataset by a wide margin.
  2. Within AWS, size on memory footprint and take the cheapest family that fits. At 16 vCPU the Graviton4 families are one machine; r8g costs 48% more than c8g for the same compute and the same 20 GB/s per core.
  3. Take the newest Graviton generation. 9% more money for 20% more work, and price-performance improved at both steps: 145 to 157 to 173 index per dollar. The exception is bandwidth-bound work, where Graviton5's lower bandwidth may outweigh its better latency.
  4. Do not buy burstable for steady-state load. 16% off the hourly rate is not a saving when you get 51% of the throughput, and the throttle shows up as application latency rather than as anything visible on the invoice.

The measurement details behind all of this are in the provider differences article. To check current on-demand rates for any of these shapes, see AWS, GCP and OCI, or line up every provider at once in Compare all.