Stage 4 — Run
Why two billing sources
Databricks bills the platform units your workloads consume. Your cloud provider bills the machines those units run on, plus their storage and data transfer. Neither source is complete on its own.
In a case we measured, the infrastructure half was the larger of the two — a virtual machine line of €1.94 against €1.54 of platform units. A figure taken from one source alone understates a product by roughly half, and understates it silently, because both sources look complete when read on their own.
| COMPONENT | READ FROM | COVERS |
|---|---|---|
| Platform units | Databricks system tables | DBU consumption, classic and serverless |
| Infrastructure | Azure Cost Management | VMs, managed disks, NICs, public IPs, NAT gateways |
| Storage | Azure Cost Management | Storage attached to running compute |
| Data transfer | Azure Cost Management | Bandwidth and egress |
Each component has exactly one owning source. Databricks charges appear in Azure Cost Management too, so the Databricks service line is dropped on ingestion — without that, every serverless product would report roughly twice what it cost.
Attribution is a tag, and the tag is enforced
A cloud bill knows about subscriptions and resource groups. It knows nothing about data products. The only thing that can carry a product identity onto a machine is a tag, and the only tag that reaches the machine is one set on the cluster.
Databricks propagates workspace, pool and cluster tags onto the resources it creates. A job-level tag never reaches them. So the attribution tag goes in the cluster block's custom_tags, not the job's own tags. Serverless jobs and pipelines have no cluster, so the same tag also goes on the job or pipeline itself; Finowl reads it from the job's definition, not from the bill.
Untagged spend is never guessed at. It is left unattributed, and the product page says which half is missing rather than presenting the remainder as the total. Setup details in Actual cost.
What Run puts side by side
Three numbers, and the comparisons between them answer different questions.
| COMPARISON | ANSWERS |
|---|---|
| Baseline vs bill | Did we plan this product correctly? A gap here is an estimation problem and feeds Stage 5. |
| CLI projection vs bill's compute | Is our pricing model right? A gap here is a modelling problem — a workload word that is wrong, a schedule that does not run as declared. |
| Budget vs bill | Are we overspending right now? This is the operational question, and the only one that needs an answer this month. |
Keeping them separate matters. A product over budget because the estimate was wrong needs a different conversation from one over budget because a job runs four times more often than the schedule says.
When figures appear, and what as-of means
Retrieval runs once a day and re-reads from the first of the previous month through today, replacing what it holds. Both sources revise figures for days afterwards, so a window that never looked back would freeze whatever a day happened to cost the first time it was read.
Every figure carries an as-of date, and it is the last date the source actually covered — not today. The most recent day or two are always partial. A figure presented as current when it is not reads as an unexplained dip, and somebody investigates a drop that never happened.
When platform units cannot be read at all
Databricks system tables can only be queried from a workspace enabled for Unity Catalog. With no such workspace anywhere in the account, platform units are unavailable. Classic infrastructure still arrives from Cost Management, and the product page says which half is missing.
Who acts on this stage
- FinOps reads the gaps and decides which are worth chasing.
- The product owner owns the response — descope, optimize, or ask for more budget.
- Engineering acts on modelling gaps, because a projection that disagrees with the bill usually means the bundle does not describe what actually runs.