Cloud bills that surprise their owners are rarely the result of a bad platform choice. They are the accumulation of resources nobody switched off, instances sized for a load test that ended eighteen months ago, and data moving in a metered direction. The compute line is the part people forecast correctly. Everything around it is where the money goes.
Data egress: the charge that scales with success
Getting data into a cloud provider is generally free. Getting it out is metered per gigabyte, and it is the most common reason a bill diverges from the estimate. Every file a customer downloads, every API response, every backup copied elsewhere, every uncached image is billable outbound traffic.
What makes egress dangerous is that it scales with the thing you are trying to grow. Compute costs track your architecture, which you control; egress tracks user demand, which you do not. A media-heavy or export-heavy product can find traffic becomes its largest line item at exactly the moment it starts working.
Cross-zone and cross-region transfer within the same provider is also charged, which catches out architectures spread across availability zones for resilience, and chatty microservices that talk across a zone boundary on every request. Rules that help: put a CDN in front of anything served repeatedly, keep chatty services in one zone, be deliberate about where backups land, and check the egress terms of any managed service before adopting it. Several providers now waive egress fees when a customer leaves entirely, but that does not touch the day-to-day charges that make up the bill.
Environments nobody turns off
Development, staging, QA, demo and the proof-of-concept from two years ago run continuously, because shutting them down was never anyone’s job. A non-production environment mirroring production is paid for around the clock and used for a fraction of a working week.
The fix is unglamorous: schedule non-production environments off outside working hours, tag every resource with an owner and purpose at creation, refuse to provision anything untagged, and give short-lived environments an enforced expiry. Environments spun up per pull request and destroyed on merge remove the problem for the case that generates the most sprawl. The same applies to anything else running at full capacity for a workload that is not there: batch jobs on always-on instances, over-provisioned staging databases, clusters kept warm for traffic that arrives twice a day.
Oversizing, and the on-premises habit behind it
When you buy a physical server you size it for three years of growth plus a margin, because adding capacity means procurement and a data centre visit. That instinct is correct on-premises and expensive in the cloud, where resizing is a restart. Teams migrating from owned hardware map each machine onto an instance of comparable specification, then pay monthly for headroom they never use.
Measure before you size. CPU and memory utilisation over a representative period, including peaks, tells you what the workload needs. Size close to it, monitor, adjust — reserved or committed-use pricing offers real discounts once you know the steady-state baseline. Commit too early, on pre-migration guesses, and you have locked in the oversizing. Storage tiering is the same discipline: data written once and read almost never does not belong on the fastest tier, and lifecycle rules that age objects into cheaper storage take an afternoon to configure.
Orphaned resources
Cloud platforms are careful not to delete your data, so deleting a server often leaves its parts behind, still billing:
- Detached block volumes from terminated instances, charged at full price to store nothing anyone will read.
- Snapshots on an automated schedule with no retention policy, accumulating for years.
- Static IP addresses reserved and unattached, which several providers charge for precisely because they are idle.
- Load balancers, NAT gateways and endpoints left in front of services that no longer exist, billed hourly regardless of traffic.
- Incomplete multipart uploads in object storage, invisible in the console’s usual view and billed as stored data.
- Log data retained indefinitely by default, which for a busy application becomes a line of its own.
Individually small; across a few years of shipping quickly, a persistent tax on a budget nobody examines. A quarterly sweep for unattached resources, plus retention policies set at creation, keeps it under control.
Lift-and-shift or rearchitect
Lift-and-shift moves the existing system onto cloud instances more or less unchanged. It is fast, low-risk, and does not reduce running costs — you have replaced a capital purchase with a rental of the same shape, plus a margin. It can still be right: expiring hardware, a data centre exit, an urgent resilience gap, or a system nobody understands well enough to rewrite safely.
Rearchitecting — managed databases instead of self-hosted, object storage instead of file servers, autoscaling or serverless for spiky work — is where the economics change, because you stop paying for idle capacity. It costs engineering time and carries more risk.
The pragmatic route is staged: move first, then rearchitect the parts where the numbers justify it, guided by the bill rather than by fashion. Rearchitecting a service that costs a hundred pounds a month is effort spent for no return. The trap is stopping at stage one, calling the migration finished, and wondering for three years why the cloud is expensive.
When a server of your own is simply cheaper
Cloud pricing is optimised for variability: you pay a premium for the ability to scale up in minutes and to pay nothing when idle. If your workload is steady and continuous, you are paying that premium for an option you never exercise.
Dedicated or colocated hardware tends to win when load is flat and known, when you need a lot of storage or serve a lot of outbound traffic, and when you have the operational capability to run it. Cloud wins on spiky or seasonal demand, early-stage products where the load is unknown, small teams with no infrastructure staff, and anything where managed services replace work you would do yourself.
A hybrid arrangement is often the honest answer: predictable baseline on dedicated capacity, burst on cloud. It is more complex to operate, so a real gap between the two has to justify it. And any comparison must include the costs that never appear on an invoice — staff time, out-of-hours cover, hardware refresh, spare parts, and the disaster recovery you would otherwise get as a configuration option.
Data residency after Brexit
UK businesses sit under UK GDPR alongside the Data Protection Act, while the EU regime applies separately to EU personal data. The EU’s adequacy decision permits data to flow from the EU to the UK, but it is periodically reviewed rather than permanent — a live consideration for anyone assuming that flow will always be free.
Region selection is therefore a decision with contractual and legal consequences, not a latency choice. Public sector work, healthcare, financial services and defence supply chains frequently carry explicit UK-residency requirements, and procurement questionnaires routinely ask where data is stored and processed. Losing a tender over a region setting is an avoidable expense.
Trace residency beyond the primary database. Backups, logs, analytics pipelines, error tracking, email delivery, support tooling and any AI service in the path may each process data in a different jurisdiction. Map where every copy goes, not just the one you designed, and confirm it before a customer’s security review rather than during it. Architecture chosen for residency may cost more than the cheapest arrangement; that difference belongs in the estimate.
Estimating before you move
A useful estimate is built from measurement, not the pricing calculator alone. Before committing, gather:
- Actual utilisation over a full business cycle, including month-end and seasonal peaks — not the hardware specification.
- Outbound traffic volume measured at the network edge, and its growth trend. Most often omitted, most often decisive.
- Storage volume by access pattern, and what genuinely must be retained.
- Every non-production environment, costed as if it runs continuously, then again with a shutdown schedule applied.
- One-off migration costs: engineering time, dual running, transfer out of the current provider, retraining, licence changes.
- Current total cost of ownership on the same basis, staff time and hardware amortisation included, so the comparison is like for like.
Then put the controls in before the workloads: tagging enforced from day one, budget alerts at defined thresholds, cost attributed to teams or products, and a named owner reviewing the bill monthly. A cloud bill with no owner grows. The technical work of a migration is the predictable part; the financial discipline around it decides whether the result is cheaper than what you had.