Writing ·
Where Your Cloud Bill Actually Goes

Cloud bills grow quietly. Every change is made by someone with a good reason, each new line is small, and nobody owns the total. The bill reaches finance a month after the money is spent, and the engineers who could change it rarely see it. So nobody notices until the finance team asks why it’s gone up so much.
In my experience, most of what can be saved isn’t hidden in clever discounts. It sits in a few predictable places: things left running, things sized for a peak that never comes, and architecture decisions that have outlived their reasons. My examples come from Azure (where I’ve worked for more than ten years) and AWS, but the shape is much the same elsewhere.
Start with where the money goes
Break the bill down by service, by environment (production, staging, development) and by team. Between them, they tell you what’s expensive, whether it serves customers, and who can change it.
For that you need tags: labels such as team: payments attached to each cloud resource. Then cost reports can group the data by those tags. An untagged bill tells you that databases cost a lot, but not to whom they belong, whether they’re in production, or who can agree to switching one off. A cost with no owner never gets cut. Put tags in your infrastructure-as-code templates (the files that describe your environment and create it), so nobody has to remember them, and use a separate subscription or account for each environment where you can.
Start now, and don’t count on tags to explain the past. Azure’s Cost Management can apply resource group and subscription tags to the current month’s usage (on Enterprise Agreement, Microsoft Customer Agreement and Microsoft Partner Agreement accounts, not pay-as-you-go), and AWS can backfill up to twelve months, but only for tags that were already on the resources.
Then make the bill arrive sooner. Both providers let you set budgets that alert on actual or forecast spending, and both can flag spending that breaks from its recent pattern (Azure’s cost anomaly alerts, AWS Cost Anomaly Detection). If you send those alerts to the team that owns the cost, not only to finance, then a mistake will surface within a day or two, rather than at the end of the month.
Waste: the usual suspects
Forgotten things. Depending on how a server was created and deleted, its disks can outlive it and go on being billed. Old snapshots (saved copies of disks) are billed for the data they hold, and AWS charges for the public IPv4 addresses it provides, regardless of whether or not they are in use. And what about last year’s proof-of-concept database? Once somebody has confirmed that they are no longer needed, these are the lowest-risk savings there are.
Sized for a peak that never comes. Services get sized at launch for a guess, and nobody sizes them down, because nobody is thanked when it’s fine and everybody remembers when it wasn’t. Look at real usage over a period that includes your busiest times, then size for that with headroom, or use autoscaling (adding and removing capacity as load changes) if the load really varies.
Half-empty clusters. In Kubernetes (a system for running containers across a pool of servers), each container declares how much CPU and memory it requests, and the scheduler places containers so that the requests on each server never add up to more than its capacity (strictly, its allocatable capacity: what’s left after the system’s own reservations), whatever the containers actually use. Generous requests, set once and never revisited, leave you paying for servers that are full on paper and mostly idle in practice. The servers are ordinary virtual machines, billed as such.
Non-production environments that never switch off. I’ve seen more than one client whose forgotten development and test environments cost more than production. To see how, imagine a development environment used ten hours a day, five days a week: 50 of the 168 hours in a week, so it’s idle about 70% of the time that you’re paying for it. Stopping it out of hours saves the compute cost (on Azure the server must be deallocated, releasing its hardware, not only shut down from inside, and disks are billed either way). One catch: if it’s covered by a reservation (see below), the reserved part of its cost is paid whether it runs or not.
Cutting waste saves energy as well as money, which is part of why efficiency matters to me.
Environments on demand
Better still is not keeping the environment at all. Once an environment can be created from code, it can be made to exist only while a piece of work needs it: created when the work starts, torn down when it’s done. The speed usually matters more than the saving, because nobody queues for a shared environment. The automation takes real effort to build and maintain, so it pays off when you have many environments or create them often. For one stable staging environment, an overnight shutdown may be all you need.
Architecture decisions that outlived their reasons
Always-on versus serverless. With functions-as-a-service such as AWS Lambda or Azure Functions, the provider runs your code only when a request arrives, and charges per request and for running time, weighted by memory (allocated or, on some plans, used). That’s cheap for spiky or low traffic. For steady, heavy traffic, a busy server can cost less, so going back to always-on can be the saving. Not all “serverless” is billed this way: AWS Fargate, which runs containers, charges for the resources you reserve while a task runs. Make sure you read the pricing model, not the label.
Managed services. A managed service is one the provider runs for you. Azure SQL Database, for example, handles upgrades, patching, backups and monitoring for you, with high availability built in. Compare its price with a server plus the billed hours all of that support would take, not with the server alone. It earns its premium when that work would otherwise fall on your engineers, and not when you pay for a tier you don’t need.
Licences. On Azure, Windows Server and SQL Server licences can be a large part of what you pay for a server or database. If you already own licences with Software Assurance (or qualifying subscription licences), Azure Hybrid Benefit lets you use them in Azure and pay a lower rate. Where SQL Server isn’t earning its keep, moving to a database with no licence fee, such as PostgreSQL, can save more, though the migration has its own cost. Licensing terms are specific and they change, so read them before relying on them.
Storing data. Cooler storage tiers cost less to store and more to read, and can carry charges if data leaves them early. Azure’s archive tier can take up to fifteen hours to return data (at standard priority; high priority can take under an hour for smaller files), while some AWS archive classes take milliseconds, so choose by how fast you’d need it in a restore as well as how often you read it. And Azure Monitor Logs charges mainly by the volume of data you send it, so verbose logging switched on during an incident and never switched off grows quietly.
Moving data. Data coming in from the internet is free on both Azure and AWS. Data going out (egress) is charged by the amount of data, after a small monthly allowance, under their standard bandwidth pricing, though content delivery networks (services that serve your content from locations near your users) and some plans charge differently.
Traffic inside a provider can cost money too. AWS charges for many kinds of traffic between Availability Zones (groups of one or more separate data centres within a region, with redundant power and networking); Azure currently doesn’t. An AWS NAT gateway, which lets private servers reach the internet, is billed hourly and for every GB it processes.
Ask whether you need the cloud at all
Your own hardware, owned or rented, can cost far less than the public cloud, so it’s always worth asking whether the cloud is the right answer. It depends on which of the cloud’s benefits you actually need. If you rely on its resilience and redundancy, or your usage swings so widely that paying by the hour beats owning enough for the peak, the premium may well be worth it. If your workload is steady and you don’t need those things, you may be paying a lot for benefits you never use. Either way, count the operational work the cloud was doing for you.
If you do leave, AWS and Azure will both credit back egress charges for customers moving their data out, if you arrange it with support first and finish within their deadline (60 days on Azure, or 180 for UK customers leaving UK data centres; 180 days on AWS, with separate terms in the UK and EU). Azure also requires you to cancel all your subscriptions before you claim. Read the conditions.
Commitments come last
Azure Reservations commit you to a specific product, such as a server size in a region, for one or three years. Savings plans (Azure’s savings plan for compute, AWS Savings Plans) commit you instead to spending a fixed amount per hour for one or three years, and the most flexible kinds follow you across server sizes and regions. AWS also has Reserved Instances, but now recommends Savings Plans over them.
The discount is real, and so is the commitment: unused hours are lost, some commitments can’t be cancelled at all, and from February 2027 Microsoft is ending exchanges for most compute and database reservations (existing ones get one final exchange). I checked these terms against Microsoft’s and AWS’s documentation in October 2026; check them again before you buy.
If you commit first and optimise later, you lock the waste in: a three-year reservation on an oversized server pays to keep the mistake. Clean up, right-size and decide where the workload should run, then commit only to the steady baseline that’s left.
What not to cut
Every saving trades against something, and a good review says what. Don’t cut backups, or the restore tests that prove that they work. Keep redundancy in production wherever an outage would cost more than the spare capacity, and keep monitoring (cut the noise, not the signal), security controls, and headroom for peaks you know are coming.
Development environments rarely need the same redundancy, and data kept beyond what your recovery, investigation and legal requirements call for can often move to a cheaper tier. The “wrong” answer is sometimes fine: a single server with no failover suits an internal tool where an hour’s outage costs little.
What a good cost review gives you
A prioritised list of changes, each with its expected saving, risk and effort. Usually that means forgotten resources first, then schedules and right-sizing, then architecture, with commitments last. It should also leave you with tags and owners, so the bill doesn’t creep back.
The lasting fix, though, isn’t a review. It’s making cost something engineers see while they work: cost per customer or per transaction, on the same dashboards as latency and errors. Then a change that doubles the cost of a request shows up in the sprint that made it, not in next quarter’s bill.
If your cloud bill has been growing faster than your business, read more about cloud cost reduction, or get in touch.