Build an Infrastructure Cost Attribution System
cost-optimization cloud-infrastructure observability
System Design Deep Dive
Infrastructure Cost Attribution System
Tagging every cloud resource to its owner and catching spend anomalies before the CFO sees the bill
Cloud bills arrive once a month and look like a 10,000-line spreadsheet from a foreign country. Every row tells you what was charged but almost nothing about why. The compute line for us-east-1 says $84,000 - but which team ran those instances? Which service spawned that Lambda burst? Which data pipeline forgot to shut down its Redshift cluster? Without answers to those questions, you cannot optimize what you cannot see, you cannot hold teams accountable for costs they don’t know they incur, and you cannot catch the engineer who accidentally left a GPU cluster running over a long weekend.
Think of it like a shared office building where every team uses electricity, water, and HVAC but pays one collective bill. You could split it evenly, but that punishes frugal tenants and lets wasteful ones hide. The right model is submetering: put a meter on every circuit, attribute each kilowatt to the team drawing it, and send individual breakdowns. Cloud cost attribution is exactly this - putting a software meter on every compute instance, storage bucket, network byte, and managed service call, then routing each charge to the owning team in near real-time rather than at month’s end.
The engineering challenge is more subtle than slapping tags on resources. Tags drift: engineers forget them, resources get created by automation without tags, and shared infrastructure like a VPC NAT gateway or a centralized logging cluster genuinely belongs to multiple teams simultaneously. You need a resource tagging strategy that spans manual and automated creation paths. You need cost allocation rules that handle the messy middle - partial ownership, time-bound attribution, and costs that legitimately should be split. And you need shared resource apportionment that distributes infrastructure-level costs fairly without double-counting or under-counting.
On top of the attribution problem sits a temporal one. Cloud providers emit billing data with variable delay - AWS Cost and Usage Reports (CUR) lag 8-24 hours, while usage metrics from CloudWatch can be near real-time. Bridging that gap requires a real-time spend ingestion layer that fuses early signals (usage events) with confirmed cost data (billing records) to give teams hour-granularity visibility rather than day-old snapshots. Layer in anomaly scoring and budget alerting, and we’re solving for attribution accuracy, data freshness, anomaly detection sensitivity, and alert fatigue simultaneously.
Requirements and Constraints
Functional Requirements
- Tag every cloud resource (compute, storage, network, managed services) to an owning team and service
- Apply allocation rules to split shared resource costs across multiple teams by configurable proportions
- Ingest billing events and usage metrics in near real-time (under 30-minute lag from cloud provider emission)
- Surface per-team, per-service, and per-tag-dimension cost breakdowns queryable via API and dashboard
- Detect anomalous spend spikes and dispatch alerts within 15 minutes of the anomaly onset
- Support both showback (informational cost reports) and chargeback (actual internal billing/transfers)
- Provide budget management: teams set monthly budgets, system alerts at configurable thresholds (50%, 80%, 100%)
- Track untagged resource costs separately and expose them for remediation workflows
- Support multi-cloud (AWS, GCP, Azure) with a unified cost model
Non-Functional Requirements
- Ingest up to 5 million billing line items per hour across all cloud accounts
- Query cost breakdowns with p95 latency under 200ms for 30-day aggregations
- Store 24 months of daily-grain cost data and 90 days of hourly-grain data
- System availability: 99.9% uptime (8.7 hours/year downtime tolerance)
- Attribution accuracy: fewer than 0.1% of costs in the “unattributed” bucket after 48 hours
- Anomaly alerts delivered within 15 minutes of a 2-sigma spend deviation
- Support 500 teams and 10,000 individually tracked services
Constraints and Assumptions
- Cloud provider billing APIs are the source of truth; we do not attempt to re-derive costs from usage
- Tag schema is centrally managed (teams cannot create arbitrary tag keys without approval)
- Chargeback triggers actual internal fund transfers via a finance system API - outside the scope of this design
- We assume a single currency; multi-currency conversion is a downstream concern
- We do not handle reserved instance or savings plan optimization recommendations - only attribution
High-Level Architecture
The system has six major components arranged in a pipeline with a feedback loop for tag remediation.
Cloud Source Connectors pull billing and usage data from AWS CUR S3 exports, GCP BigQuery billing exports, and Azure Cost Management APIs. Each connector normalizes vendor-specific schemas into a common CostEvent protobuf.
Tag Ingestion Pipeline is a Kafka-backed stream processor that enriches each CostEvent with team and service tags from the Tag Registry. Resources without tags are routed to a separate dead-letter topic for manual remediation.
Cost Allocation Engine is the core workhorse. It applies allocation rules - splitting shared resource costs by configurable proportions - and writes attributed TeamCostRecord rows to the Cost Store. It also maintains a running tally of unattributed spend.
Shared Resource Apportionment handles resources that are genuinely multi-tenant: NAT gateways, load balancers, centralized log aggregators. It distributes costs by configurable metrics (request count, data transfer volume, CPU utilization) sampled from the metrics tier.
Anomaly Detection Engine runs a rolling z-score model over hourly spend per team, scoring each new cost batch and publishing anomaly events when spend deviates beyond a threshold.
Alert Manager consumes anomaly events and budget-threshold events, deduplicates, rate-limits, and dispatches to Slack, PagerDuty, and email via a notification fanout.
Data flows like this: cloud providers emit billing records, connectors poll or subscribe every 15 minutes, the ingestion pipeline enriches and routes events, the allocation engine attributes and persists costs, and the anomaly detector scores in parallel. The dashboard and cost API read from the Cost Store directly, using pre-computed rollup tables for the common aggregations.
The most important architectural decision is separating tag enrichment from cost allocation - they run at different cadences (enrichment is near real-time, allocation may need to wait for confirmed billing data) and have different failure modes (a missing tag is recoverable; an incorrect split ratio is not).
The Tag Registry and Resource Tagging Strategy
The Tag Registry is the single source of truth for which resource belongs to which team and service. Without it, every component in the system would need its own lookup logic, and drift between copies would corrupt attribution.
Premium Content
Unlock the full article along with everything else in the archive — all in one place.