Guides

Ten settings that keep a Databricks or Fabric bill down

Both platforms bill for compute that is on, whether or not it is doing anything. Every item below is a setting or a habit, not a rewrite, and each one is marked for the platform it applies to. Do them in order; the first three are where most of the money is.

  1. Run scheduled work on job clusters, never on all-purpose clusters

    A job cluster exists for one run and terminates when it ends. An all-purpose cluster left on for a nine-hour working day to host a twenty-minute job costs on the order of fifty times as much for the same result, once the higher per-DBU rate is included.

    Databricks. On Fabric the equivalent is keeping scheduled Spark jobs off interactive notebook sessions.

  2. Set auto-termination to minutes, not hours

    Every all-purpose cluster and SQL warehouse idles after a short wait: ten to twenty minutes for clusters, a few minutes for warehouses with auto stop. "Never" is the default nobody meant to choose.

    Databricks. On Fabric, set the Spark session timeout for notebooks down from its default so a closed laptop does not keep a session alive.

  3. Pause what is not in use

    A Fabric capacity bills every second it is running. Pause development and test capacities outside working hours with a scheduled script, and resume them in the morning; a capacity that runs twelve hours a day costs half of one that runs all day.

    Fabric. On Databricks the same idea is serverless compute, billed only while work runs.

  4. Put a cluster policy, or a capacity, in front of people

    A Databricks cluster policy fixes node types, caps size, enforces auto-termination and requires tags. A Fabric workspace assigned to a small capacity cannot exceed it. Either one stops the accidental 64-node cluster before it exists.

    Both.

  5. Load incrementally, not fully

    A pipeline that reprocesses all history every night pays for all history every night. Auto Loader, streaming reads, change data feed and MERGE on changed rows mean the nightly run touches a day's worth of data. If run time grows with the table rather than with the day's input, this is the item.

    Both.

  6. Use spot or autoscaling for batch workers

    Spot instances for worker nodes cut the virtual machine cost of batch jobs that can tolerate an occasional retry; keep the driver on demand. Autoscaling with a sensible minimum stops a cluster sized for month-end running at that size all month.

    Databricks. On Fabric, autoscale and bursting are capacity settings; check the capacity metrics app before raising the SKU.

  7. Let Power BI read the lake directly

    Every import refresh is compute. On Fabric, Direct Lake reads Delta tables without an import refresh at all. On Databricks, incremental refresh on the Power BI side means the nightly refresh touches a week of rows instead of years.

    Both, different mechanism.

  8. Stop refreshing what nobody reads

    Models refreshed eight times a day for a report opened twice a week are a quiet, permanent cost. Usage metrics show which reports are opened; match the refresh schedule to that, and retire the ones with no viewers for ninety days.

    Both, through Power BI usage metrics.

  9. Set a budget alert that reaches a person

    Databricks account budgets, or a scheduled query over the billing system table, posting to a channel when daily spend crosses a line. The Fabric capacity metrics app shows utilisation; an alert on sustained throttling is the equivalent. A cost surprise should arrive within a day, not at month end.

    Both.

  10. Read the bill once a month, by spender

    Ten minutes with the billing table grouped by cluster, warehouse, job or workspace, looking at the top five. Ask whether each is earning its keep. The untagged cluster named "test 2" that runs every day is found this way and no other.

    Both.

The query for item ten, on Databricks

SELECT usage_date, sku_name,
       coalesce(usage_metadata.cluster_id, usage_metadata.warehouse_id, usage_metadata.job_id) AS spender,
       sum(usage_quantity) AS dbus
FROM system.billing.usage
WHERE usage_date >= current_date() - INTERVAL 30 DAYS
GROUP BY 1, 2, 3
ORDER BY dbus DESC;

On Fabric, the capacity metrics app plays the same role: sort by capacity units consumed per item and the top five are the conversation.

When to ask for help

If items one to three are not already in place, they are an afternoon's work and the saving shows on the next invoice; we put the number in writing first. If the bill is dominated by one pipeline, item five is usually the cause and the fix is a design change rather than a setting.

Related: what a lakehouse costs to run in the FAQ, job cluster in the glossary.

Which of the ten is missing on your platform?

Send the top five spenders from the billing query, names removed. We reply within a working day with the order to fix them in.