October 29, 2026 · Timothy O’Brien
The Same Machine, Two Different Bills
Google bills cores and RAM as separate SKUs. Azure bills the whole size. It is a tiny difference that only shows up when you run across providers, and it changes how you read your own invoice.

Yesterday’s post was about a quarter-trillion dollars of committed compute (Anthropic’s S-1). Today’s is about the opposite end of the telescope: a billing detail so small that most teams never see it, and only see it at all when they run compute on more than one cloud.
The book is about problems that show up at scale, commitments measured in years and billions. But scale is mostly made of small things repeated, and here is one of the small things. Google and Azure sell you what looks like the same virtual machine, and it lands on the invoice as two completely different objects.
On Azure, you pick a size. Standard_D8s_v6 is a thing: 8 vCPUs, 32 GiB of memory, one SKU ID, one hourly price. The bill shows a line that says you ran hours of that size. The vCPUs and the memory exist only inside the SKU name; there is no separate line for RAM. Microsoft’s own docs describe sizes as “a specific VM configuration, including vCPUs, memory, and accelerators,” and that is how the money is shaped too.1
On Google, the components are the products. Create a custom machine type and Compute Engine bills you separately for the cores and the memory. The current N4 custom pricing is $0.03275 per vCPU-hour and $0.003717 per GiB-hour of memory, listed as two distinct items on the price sheet, with a documented 5% premium over the standard shapes for the flexibility.2 So a machine with 8 vCPUs and 64 GiB is not one line. It is 8 × $0.03275 plus 64 × $0.003717, which is about $0.50 an hour, and it shows up in your billing export as two SKUs, core-hours and GB-hours, that only happen to describe one machine.
Same machine. Two different bills.
Why does this matter, when the total is the total either way? Because the total is not what you manage. What you manage is the story the bill tells, and the two stories are different.
On Google, the story decomposes. If a team resizes from memory-heavy to core-heavy, you can see exactly which component moved: the core line went up, the memory line went down, and the arithmetic of the trade is right there. If you are building any kind of internal showback or unit economics, Google hands you the raw ingredients (chapter 6). A price per core and a price per GiB are the atoms of a compute bill, and you get them pre-atomized. The catch is the reverse of the same coin: committed-use discounts, spot pricing, and premium tiers all apply per component, so the discount story also has twice as many moving parts, and comparing a custom shape to a standard one means remembering that 5% premium is sitting inside one of them.
On Azure, the story is bundled. Memory-vs-core decisions are made at SKU-selection time, and after that the bill only knows sizes, and the shape of a SKU is a product decision (chapter 10). If the same team adds RAM, they do not buy more RAM, they become a different SKU, and the line item changes by whatever the whole-size price difference is. You can still work out the implied per-core and per-GiB rates by dividing, but you are deriving them; Azure never hands them to you. The flip side is that discounting is simpler to follow: reserved instances and savings plans attach to the SKU, one commitment per size, no component arithmetic underneath.
None of this shows up until you run across providers, which is exactly the point. A team on one cloud builds its mental model of “how we are billed” around that cloud’s shape and never notices it is a model of the vendor, not of compute. The moment you operate on two, every reconciliation between them goes through this seam: your per-unit costs are native on one and derived on the other, your discount mechanics live at different layers, and a “comparable” machine is only comparable after you normalize it yourself.
The advice is short. Pick one internal unit of account, a price per vCPU-hour and a price per GiB-hour, and derive it for every provider, including the ones that bill in bundles. That derived rate card is what you compare on and what you allocate on. Keep the provider’s native SKU visible next to it, because reservations and premiums attach to the native SKU, not to your normalization. And when you change a machine’s shape, check which layer of the bill actually moved: on one cloud it will be a line, on the other it will be a name.
It is a small thing, and I nearly left it out of the book for that reason. But this is a book about running across providers, and this is the sort of thing you only learn by doing exactly that, usually at eleven at night with two invoices open next to each other wondering why the same machine adds up differently on each one. After that, you never read a bill the same way again.
Sources
Microsoft Learn, “Sizes for virtual machines in Azure,” updated 2026-09-24: learn.microsoft.com/en-us/azure/virtual-machines/sizes/overview — a size is “a specific VM configuration, including vCPUs, memory, and accelerators”; sizes are selected by name and priced per size, not per component.↩︎
Google Cloud, General-purpose VM pricing, accessed October 29, 2026: cloud.google.com/products/compute/pricing/general-purpose — N4 custom vCPUs $0.03275/1 hour, custom memory $0.003717/1 gibibyte hour, billed as separate line items; “The on-demand prices for custom machine types include a 5% premium over the on-demand prices for standard machine types”; extended memory above 8 GiB per vCPU billed at a separate extended rate.↩︎
