BigQuery Table Storage by Last Query Date
Storage costs in BigQuery are often overlooked because they're small compared to compute costs. But over time, accumulating stale tables that nobody queries can add up to significant monthly expenses. This query shows every table sorted by when it was last queried, along with its storage cost.
Why This Matters
Large organisations can accumulate thousands of tables that are no longer used — leftover from old pipelines, one-off analyses, or deprecated features. These tables silently accrue storage charges every month. By identifying tables that haven't been queried in weeks or months, you can archive, delete, or convert them to cheaper storage tiers.
How It Works
The query joins INFORMATION_SCHEMA.JOBS_BY_PROJECT (to find the last query time per table) with TABLE_STORAGE (for size data) and TABLE_OPTIONS (to determine logical vs physical billing model). It calculates storage cost based on active vs long-term bytes using Google's published per-GiB pricing.
SQL Query
Fill in your details to get a ready-to-run query:
-- Find stale tables sorted by last query date with storage cost
DECLARE lookback_days INT64 DEFAULT 30;
-- US multi-region pricing ($/GiB/month)
DECLARE logical_active_price NUMERIC DEFAULT 0.02;
DECLARE logical_longterm_price NUMERIC DEFAULT 0.01;
DECLARE physical_active_price NUMERIC DEFAULT 0.04;
DECLARE physical_longterm_price NUMERIC DEFAULT 0.02;
WITH last_access AS (
SELECT
ref.project_id, ref.dataset_id, ref.table_id,
MAX(j.creation_time) AS last_query_at
FROM `your-project`.`region-us`.INFORMATION_SCHEMA.JOBS_BY_PROJECT j,
UNNEST(j.referenced_tables) ref
WHERE j.state = 'DONE' AND j.job_type = 'QUERY'
AND j.creation_time >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL lookback_days DAY)
GROUP BY 1, 2, 3
),
storage_info AS (
SELECT
s.project_id,
s.table_schema AS dataset_id,
s.table_name AS table_id,
IFNULL(opt.option_value, 'LOGICAL') AS model,
IF(opt.option_value = 'PHYSICAL', s.total_physical_bytes, s.total_logical_bytes) AS size_bytes,
IF(opt.option_value = 'PHYSICAL', s.active_physical_bytes, s.active_logical_bytes) AS active_bytes,
IF(opt.option_value = 'PHYSICAL', s.long_term_physical_bytes, s.long_term_logical_bytes) AS lt_bytes
FROM `your-project`.`region-us`.INFORMATION_SCHEMA.TABLE_STORAGE s
...Query Explanation
The query cross-references two data sources: job metadata (for last query time per table) and table storage metadata (for size and billing model). Tables that were never queried in the lookback window appear first (NULLS FIRST). Storage cost is calculated using active vs long-term bytes with the appropriate pricing for logical or physical billing model.
Key Insights
Tables at the top of the list (never queried or queried long ago) are prime candidates for deletion or archival.
Large tables that haven't been queried may still be referenced by other systems — verify before deleting.
Tables older than 90 days automatically get long-term pricing (50% cheaper), but deleting unused tables saves 100%.
Physical billing model tables cost 2x per GiB but benefit from compression — check if your tables are highly compressible.
Best Practices
- 1
Set up a monthly review of tables not queried in the past 30 days.
- 2
Implement table expiration policies (default_table_expiration_ms on datasets) for temporary data.
- 3
Archive important but unused tables to Google Cloud Storage (cheaper than BigQuery storage).
- 4
Switch datasets with high compression ratios to physical billing model for up to 70% storage savings.
Want CloudClerk to find these savings automatically?
Our platform connects to your BigQuery project, runs these analyses automatically, and delivers AI-powered optimisation recommendations — all with your data fully anonymised.
Related Guides
BigQuery Cost Analysis by Query
Analyze every individual query's cost, slot usage, and execution time. Get a detailed breakdown of on-demand cost per query execution.
Read guideBigQuery Top Queries by Cost
Find the most expensive BigQuery queries by on-demand cost. Rank queries by total bytes billed to identify the biggest cost drivers in your project.
Read guideBigQuery On-Demand vs Editions: Per-Query Cost Comparison
Compare on-demand vs BigQuery Editions pricing for every query. Get per-query recommendations for Standard, Enterprise, and Enterprise Plus editions.
Read guideBigQuery Cost Analysis by Project
Track BigQuery costs across GCP projects. Use INFORMATION_SCHEMA to compare project-level spending and find the most expensive projects in your organization.
Read guide