TL;DR: Filter on the partition column and shrink the window. The billing export table is partitioned by day, so a query without a partition filter scans the entire history to answer 'last week's spend'. Add a WHERE clause on _PARTITIONTIME and the query drops from timeout to seconds.

```text
Query timed out: billing export scan billed 4.2 TB, quota exceeded for dataset billing-export
```

1. Inspect the agent's query: confirm there is no _PARTITIONTIME filter on the export table. Expected: a full table scan, which explains the timeout.
2. Add the partition filter: `WHERE _PARTITIONTIME >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 90 DAY)`, adjusted to the window you actually need. Expected: bytes billed drop to a small fraction of the full scan.
3. Select only the columns you need instead of SELECT star. Expected: less data scanned per row, faster query.
4. If the agent genuinely needs the full 18 months, chunk it: run per-month queries and combine the results, or aggregate once into a summary table. Expected: each chunk completes inside quota and timeout.
5. For recurring agent queries, materialize a scheduled daily or monthly aggregate into a small table and point the agent at that. Expected: the agent never touches the raw export table again.

## Use this when
- BigQuery billing-export queries time out or blow the bytes quota
- The agent queries the raw gcp_billing_export table
- The BigQuery bill shows large scan costs from the export analysis itself
- A query that used to work started failing as export history grew

## Not for this skill when
- The export table does not exist (that is an export-setup problem, not a query problem)
- The query is slow because of a huge JOIN (optimize the join; partitioning will not save you)
- You are on the free tier and any scan hurts (go straight to the summary-table approach in step 5)
- The timeout is on a non-partitioned table (different optimization problem)

## Variant phrasings
- BigQuery billing export timeout
- gcp_billing_export query too slow
- billing export bytes billed quota exceeded
- partition filter billing export table

## Why it happens
The export table grows every day and BigQuery charges by bytes scanned. Without a partition filter, even 'last week's spend' reads all 18 months of history. Queries that worked when the export was young start timing out months later as history accumulates, so the failure appears out of nowhere with no code change.

## Edge cases
- Check your table's actual partition column in the schema: older exports partition on _PARTITIONTIME, newer setups may differ
- Today's partition can be incomplete: note the as-of time so the agent does not treat partial data as final
- The export dataset's location affects cross-region query pricing: keep the analysis in the same region
- If the agent runs the query hourly, the bytes add up fast: cache aggressively or use the summary table
- Partition pruning only works with literal or simple range filters: wrapping _PARTITIONTIME in a function can defeat it

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_2-PtpOfVP_voqmgIKyyMwA
