To reduce BigQuery storage and query costs, you treat the two halves of the bill separately. Query cost is driven by bytes scanned, so anything that lets a query touch less data saves money immediately. Storage cost is driven by bytes held and how often they change, so the wins there come from layout, lifecycle, and pruning. Done in order, these moves routinely take a BigQuery bill down by a third or more without touching the data team's workflow.
This article links up to our complete guide to Google Cloud cost optimization, the pillar for this cluster. The first decision before any of this is whether you are on the right pricing model, which we cover in BigQuery on-demand vs Editions; the techniques below cut cost under either model.
On-demand pricing charges per byte scanned. Every technique that lets a query read fewer bytes, partitioning, clustering, selecting columns, is a direct cost cut. Under Editions, the same techniques free up slots for other work.
Step 1: Partition tables on the column you filter by
Partitioning splits a table into segments, usually by date or an integer range, so a query that filters on the partitioning column reads only the relevant segments instead of the whole table. A query for last week against a table partitioned by day scans a few partitions rather than years of history. Partition the large tables on the column your queries filter most, almost always a date or timestamp, and the per-query scan drops sharply. Set a partition expiration so old partitions age out automatically rather than accumulating storage forever.
Step 2: Cluster on the columns you filter and join on
Clustering sorts the data within each partition by up to four columns, so filters and joins on those columns can skip blocks that cannot match. Clustering pairs with partitioning: partition on the time dimension, cluster on the high-cardinality columns you filter or group by, such as customer or region. Together they can cut scanned bytes dramatically on selective queries at no extra storage cost.
Step 3: Exploit long-term storage pricing
BigQuery automatically drops the storage price for any table or partition that has not been modified for 90 consecutive days, to roughly half the active storage rate, with no action required and no query performance change. The implication is that you should avoid needlessly rewriting old partitions, since any modification resets the 90-day clock and pushes the data back to the active rate. Where you genuinely need cheaper storage, the physical storage billing model can also be cheaper than logical for highly compressible data. These pricing behaviors reflect Google Cloud as of May 2026; verify current rates in the BigQuery pricing documentation.
Want your data platform spend cut?
Our Google Cloud cost audit profiles your largest tables and most expensive queries, applies partitioning, clustering and storage fixes, and quantifies the saving before any change ships. On the performance model, you pay only from realized savings. No savings, no fee.
Book a GCP cost audit →Step 4: Stop queries from scanning what they do not need
Query hygiene is the fastest win because it needs no schema change. Select only the columns you use rather than SELECT star, since BigQuery is columnar and you pay for every column scanned. Filter on the partitioning column so partition pruning kicks in. Materialize repeated heavy aggregations into summary tables or materialized views so dashboards do not re-scan raw data on every refresh. Use the query validator and the dry-run byte estimate to see what a query will scan before you run it, and cache results where the same query repeats.
Step 5: Put guardrails around runaway spend
Set a maximum bytes billed limit on queries and custom quotas per project or user so a single query cannot scan an unbounded amount. Route this into the wider cost controls you set across the estate, the same way you handle Cloud Billing reports and BigQuery billing export to see where the spend actually lands by team and query.
| Move | What it cuts |
|---|---|
| Partition large tables by date | Bytes scanned per query |
| Cluster on filter/join columns | Bytes scanned on selective queries |
| Leave old partitions untouched | Storage (long-term rate kicks in) |
| Select columns, not SELECT star | Bytes scanned per query |
| Materialize repeated aggregations | Repeated scan cost on dashboards |
| Max bytes billed + quotas | Runaway query risk |
The Google Cloud Cost Optimization Field Guide includes the BigQuery query-cost audit queries and the partitioning checklist we use on data platforms. It is the downloadable companion to this guide.
Common questions about cutting BigQuery costs
Does partitioning or clustering cost extra?
No. Partitioning and clustering are free to apply and do not add storage cost. They reduce the bytes a query scans, so they save money on on-demand pricing and free up slots under Editions. There is no downside to applying them to large, frequently queried tables.
How much can clustering actually save?
It depends on selectivity. On a query that filters tightly on a clustered column, BigQuery can skip most of the blocks and scan a small fraction of the data. On a query that reads the whole table regardless, clustering helps little. The gain is largest on selective filters and joins.
What is long-term storage and how do I qualify?
Any table or partition not modified for 90 consecutive days automatically drops to roughly half the active storage rate, with no action needed. To keep the discount, avoid rewriting old partitions, since any modification resets the 90-day clock and returns that data to the active rate.
The short version
To reduce BigQuery storage and query costs, partition tables on the column you filter by, cluster on your filter and join columns, leave old partitions untouched so long-term storage pricing applies, write queries that scan only the columns and partitions they need, and cap bytes billed as a guardrail. When you want the largest tables and queries audited and fixed across the platform, that is what our Google Cloud cost optimization service delivers.