1. Cloud costs are uncontrollable because engineers make daily spend decisions that finance discovers monthly
The situation
A mid-size enterprise running workloads across AWS, Azure, and GCP receives between 50,000 and 200,000 billing line items per month. Finance teams face three problems: the data arrives too late, in too much detail, and in three incompatible formats.
The Flexera 2025 State of the Cloud Report found that 84% of enterprises cite cloud spend management as a top challenge. The FinOps Foundation puts waste at 32-40% of cloud budgets. For $10M annual spend, that is $3.2-4M in waste. At $100M, the numbers move from uncomfortable to career-threatening.
The billing data itself is dense. AWS publishes a Cost and Usage Report (CUR) with hundreds of columns. Azure Cost Management exports use a different schema. GCP billing exports land in BigQuery with their own column names and discount logic. Before FOCUS (see Section 8), every multi-cloud organisation had to build and maintain separate normalisation pipelines for each provider. Many still do.
The complication
Cloud costs do not behave like traditional IT costs. A data centre lease is fixed for years. Cloud spend is variable, consumption-based, and affected by pricing models that differ across providers. A reserved instance on AWS works differently from a committed use discount on GCP. Savings Plans on Azure cover different services than Savings Plans on AWS. Without a shared taxonomy, every cost conversation between finance and engineering becomes a translation exercise where both sides suspect the other is wrong.
The problem compounds with scale. A team running five EC2 instances can track costs in a spreadsheet. A bank running 15,000 instances across three providers, four regions, and twelve business units cannot. The proliferation of microservices, containers, and serverless functions makes attribution harder still: a single customer transaction might touch 30 services, each with its own cost profile.
The resolution: a unified cost taxonomy
The taxonomy below maps every major cost type across all three providers, with the equivalent service name, the most common waste pattern, and the primary optimisation lever. This is the reference table that finance and engineering should both point to when discussing a cost increase. If both sides can identify the same row, the conversation produces a decision. If they cannot, it produces a meeting that schedules another meeting.
Compute
| Cost Type | AWS | Azure | GCP | Typical Waste | Optimisation Lever |
|---|---|---|---|---|---|
| On-demand | EC2 (per-second Linux, per-hour Windows) | Virtual Machines (per-second) | Compute Engine (per-second, 10-min min) | Over-provisioned instances at <20% CPU | Rightsizing based on 14-day P95 utilisation |
| Reserved/Committed | Reserved Instances, Savings Plans (1yr/3yr) | Reserved VM Instances, Savings Plans | Committed Use Discounts (1yr/3yr) | Unused reservations; migrated workloads | Coverage analysis; swap unused RIs |
| Spot/Preemptible | Spot Instances (up to 90% off) | Spot VMs (eviction-based) | Preemptible/Spot VMs (up to 91% off) | Spot-suitable workloads still on-demand | Identify fault-tolerant batch, CI/CD, dev |
| Serverless | Lambda, Fargate | Functions, Container Apps | Cloud Functions, Cloud Run | Over-provisioned memory; excessive triggers | Right-size memory; review trigger frequency |
| Containers | ECS/EKS (EC2 or Fargate) | AKS (free control plane, pay nodes) | GKE (per-cluster + node costs) | Over-provisioned node pools; idle namespaces | Karpenter/Autoscaler; namespace quotas |
Storage
| Cost Type | AWS | Azure | GCP | Typical Waste | Optimisation Lever |
|---|---|---|---|---|---|
| Object storage | S3 (Standard, IA, Glacier, Deep Archive) | Blob (Hot, Cool, Cold, Archive) | Cloud Storage (Standard, Nearline, Coldline, Archive) | No lifecycle policies; data never archived | Lifecycle rules to auto-tier after 30/60/90 days |
| Block storage | EBS (gp3, io2, st1, sc1) | Managed Disks (Premium/Std SSD/HDD) | Persistent Disk (SSD, Balanced, Std) | Orphaned volumes from terminated instances | Weekly orphan scan; auto-delete >7 days |
| Snapshots | EBS Snapshots | Managed Disk Snapshots | Persistent Disk Snapshots | Snapshot sprawl: never purged | Delete >90 days unless tagged retain |
| File storage | EFS, FSx | Azure Files, NetApp Files | Filestore | Provisioned throughput never used | Switch to bursting; review IOPS |
Network and data transfer
| Cost Type | AWS | Azure | GCP | Typical Waste | Optimisation Lever |
|---|---|---|---|---|---|
| Egress (internet) | $0.09/GB first 10TB | $0.087/GB first 10TB | $0.12/GB first 1TB | Architecture pushes data out | CDN; compress; cache at edge |
| Inter-region | $0.01-0.02/GB | $0.01-0.02/GB | $0.01/GB | Services split across regions | Co-locate dependent services |
| NAT Gateway | $0.045/hr + $0.045/GB | NAT Gateway ($0.045/hr + per-GB) | Cloud NAT (per-VM + per-GB) | NAT processing internal traffic | VPC/Private endpoints for S3, DynamoDB |
| Load balancing | ALB/NLB (per-hour + LCU) | App Gateway, LB (per-hour + rules) | Cloud LB (per-rule + per-GB) | Idle LBs for decommissioned services | Audit LBs with zero targets monthly |
| Private connectivity | Direct Connect (port + data) | ExpressRoute (circuit + egress) | Interconnect (attachment + egress) | Over-provisioned bandwidth | Match to utilisation quarterly |
Database
| Cost Type | AWS | Azure | GCP | Typical Waste | Optimisation Lever |
|---|---|---|---|---|---|
| Relational (managed) | RDS, Aurora (instance + storage + I/O) | SQL Database (DTU or vCore) | Cloud SQL, AlloyDB | Dev/test DBs on prod-tier instances | Separate tiers; auto-pause dev DBs |
| NoSQL | DynamoDB (per-RCU/WCU or on-demand) | Cosmos DB (per-RU/s) | Firestore, Bigtable | Provisioned capacity above actual volume | On-demand for variable; review auto-scaling |
| Data warehouse | Redshift (node or Serverless) | Synapse (DWU or serverless) | BigQuery (per-TB or flat-rate) | Full scans; unpartitioned tables | Partition; query limits; archive unused |
AI and ML
| Cost Type | AWS | Azure | GCP | Typical Waste | Optimisation Lever |
|---|---|---|---|---|---|
| GPU instances | P5/P4d/G5 (per-second) | NC/ND series (per-second) | A2/A3 (per-second) | GPUs left running post-training | Auto-shutdown; spot for training |
| Managed ML | SageMaker (endpoints + training) | Azure ML (compute + endpoints) | Vertex AI (training + prediction) | Always-on inference, low traffic | Serverless inference; scale-to-zero |
| LLM APIs | Bedrock (per-token) | Azure OpenAI (per-token) | Vertex AI (per-token/char) | No token budgets; prompt sprawl | Token tracking; prompt optimisation |
| Data labelling | SageMaker Ground Truth | Azure ML Data Labeling | Vertex AI Data Labeling | Over-provisioned workforce | Active learning to reduce volume |
SaaS and licensing
| Cost Type | AWS | Azure | GCP | Typical Waste | Optimisation Lever |
|---|---|---|---|---|---|
| SaaS subscriptions | AWS Marketplace | Azure Marketplace | GCP Marketplace | Unused licences; duplicates | Quarterly audit; centralise procurement |
| OS licensing | Windows/RHEL/SUSE premiums | Windows (some included), RHEL | Windows/RHEL premiums | Paid-OS where Linux suffices | Default Linux; BYOL where possible |
| Database licensing | Oracle/SQL Server on RDS | SQL Server on Azure VMs | Oracle/SQL on Compute Engine | Commercial DB for open-source workloads | PostgreSQL/MySQL migration |
Hidden and indirect costs
| Cost Type | AWS | Azure | GCP | Typical Waste | Optimisation Lever |
|---|---|---|---|---|---|
| Logging/monitoring | CloudWatch ($0.50/GB) | Azure Monitor (per-GB) | Cloud Logging (per-GB after 50GB) | Debug logging in production | Log levels by env; sampling; retention |
| Secrets/config | Secrets Mgr ($0.40/secret/mo) | Key Vault (per-op) | Secret Mgr (per-version) | Unused secrets from old deployments | Quarterly audit; delete unused |
| DNS/certificates | Route 53 + ACM | Azure DNS + Certs | Cloud DNS + Cert Mgr | Zones for unused domains | Annual domain audit |
| Support plans | Business ($100/mo or 10%) | Unified Support (contract) | Premium ($12,500/mo min) | Enterprise on low-spend accounts | Right-tier per account; consolidate |
If finance and engineering cannot point to the same line in this table when discussing a cost increase, the conversation will not produce a decision. The taxonomy is not decorative. It is operational infrastructure.
How to use this taxonomy in practice
Print the taxonomy tables and put them on the wall of the room where you hold cost review meetings. When someone says 'compute costs went up 15% this month,' the conversation starts by identifying which row in the compute table is responsible. On-demand usage increase? Check whether new workloads were deployed without commitment coverage. Spot/preemptible? Check interruption rates and fallback to on-demand. Serverless? Check whether a new function was deployed with over-provisioned memory or excessive trigger frequency. The taxonomy forces precision.
The SaaS and licensing category deserves special attention because it is the fastest-growing source of unmanaged cost in financial services. The average enterprise uses 100+ SaaS applications (Okta). Approximately 50% of SaaS licences are wasted or unused (Zylo). A bank running Salesforce, ServiceNow, Datadog, Splunk, Snowflake, GitHub Enterprise, Confluence, JIRA, Slack, and 90 other SaaS products is paying for thousands of licences that nobody uses. The waste is invisible because SaaS costs often sit on departmental credit cards or procurement purchase orders rather than cloud billing accounts. FinOps programmes that ignore SaaS are ignoring 20-40% of addressable spend.
Hidden costs are called hidden for a reason. CloudWatch logging at $0.50/GB sounds trivial until you discover that a debug-level logging configuration is ingesting 2TB per month in production. That is $1,000 per month for logs that nobody reads. Secrets Manager charges $0.40 per secret per month, which adds up when every microservice has its own set of secrets and nobody audits whether decommissioned services still have active secrets. DNS zones for domains that have not been used in two years. Support plans at enterprise tier on accounts with $500 per month of spend. Each individual cost is small. Collectively, they represent 5-10% of the total bill.
The AI cost problem is different from the infrastructure cost problem
AI and ML costs deserve separate treatment because they follow different patterns than traditional compute. GPU instances are the most expensive resources in any cloud provider's catalogue. A single p5.48xlarge instance on AWS costs $98.32 per hour. Running one 24/7 for a month costs $71,773. A team that forgets to shut down a GPU instance after a training run can generate more waste in a weekend than a team that over-provisions 50 m5.xlarge instances for a month.
LLM API costs add a new dimension: per-token pricing. A GPT-4 Turbo call on Azure OpenAI costs $0.01 per 1K input tokens and $0.03 per 1K output tokens. A single complex query with a long prompt and a detailed response might cost $0.10-0.50. Multiply that by 10,000 developers using an AI coding assistant, each making 50 queries per day, and the daily cost reaches $50,000-250,000. Monthly: $1.5-7.5M. This is the scale at which banks like JPMorgan (200,000+ LLM Suite users) and Barclays (50,000+ Copilot users) are operating. Without per-team token budgets, this spend is invisible until the quarterly bill arrives.
The 98% of FinOps practices now managing AI spend (up from 31% in 2024) reflects urgency, not maturity. Most organisations can tell you that they spend $X on AI/ML. Few can tell you which team spends the most, which model is used most frequently, or what the cost per inference request is. The tooling for AI cost governance (Section 5, Section 9 Gap 3) is at the same maturity level that general cloud cost tooling was in 2018: basic visibility exists, but attribution, forecasting, and optimisation are manual processes.
Prefer the whole thing as one document?
The full 58-page guide, formatted, with every section and all eight appendices. We send it by email the same working day.
Request the PDF