# Quota exceeded: Your project exceeded quota for free query bytes scanned > You used the 1 TiB of free monthly query processing and the account has no paid billing attached. Nothing you change in the query fixes it. Here is what counts against the TiB and what does not. Source: https://docs.querylab.io/bigquery-errors/quota-exceeded-free-query-bytes-scanned/ Updated: 2026-10-25 ```text Your project exceeded quota for free query bytes scanned ``` ## What BigQuery means The free usage tier gives each billing account 1 TiB of query processing per month. You have used it, and the account has no paid Cloud Billing attached, so there is nothing to charge the next byte to. This is not a rate limit. Waiting a few minutes does nothing. Rewriting the query does nothing, because even a cheap query needs some budget and there is none. Two ways out, and they are the only two: wait for the calendar month to roll over, or upgrade the account to paid Cloud Billing. Google's resolution for this error is the upgrade. ## Who sees it Mostly people in the BigQuery sandbox, which is BigQuery without a credit card. It is the same 1 TiB. A single `SELECT *` over a wide public table can be a large fraction of it. If you are on a paid account you will not see this message. You will see a bill, or you will hit `maximum_bytes_billed` or a custom quota, which are different errors. ## What counts against the 1 TiB The number is bytes **processed** by query jobs, which is not the same as the size of your tables or the size of your results. Charged: - the full uncompressed size of every column a query reads, for the partitions it reads - the same bytes again on every re-run, unless the result came from cache - metadata. An `INFORMATION_SCHEMA` query is a query job. It bills a minimum of 10 MiB even when it reads less, and it is never served from cache, so every run costs again. Not charged: - a cache hit. The same query text against unchanged tables reads nothing. See [Query cache](https://docs.querylab.io/bigquery/query-cache/). - a dry run. Validating a query is free, however many times you do it. - batch loading, copying a table within one region, exporting with an extract job, and deleting datasets, tables, partitions, views or functions. Those are free operations. The `EXPORT DATA` SQL statement is a query, so that one is billed. Storage is a separate free allowance, 10 GiB per month, with its own meter. ## Making the TiB go further - **Name your columns.** BigQuery is columnar, so `SELECT *` on a 200-column table reads 200 columns. `SELECT * EXCEPT (big_json_blob)` is already a large saving. This is the single biggest lever. - **Filter on the partitioning column.** A `WHERE` on a partitioned table's partition column skips whole partitions. A `WHERE` on any other column reads everything and then discards. See [Partitioning](https://docs.querylab.io/bigquery/partitioning/). - **`LIMIT` does not reduce what is read.** `SELECT * FROM t LIMIT 10` on an unclustered table scans the whole table. It is the most common misunderstanding about BigQuery billing. - **Preview instead of querying.** The table preview in the console and the Preview tab in Querylab.io's [schema browser](https://docs.querylab.io/schema-browser/table-information/) read rows without a query job, so they cost nothing. - **Use `TABLESAMPLE` while you are developing.** `TABLESAMPLE SYSTEM (1 PERCENT)` reads about a hundredth of the data. See [TABLESAMPLE](https://docs.querylab.io/bigquery/table-sampling/). - **Dry-run before you run.** The dry run tells you the byte count for free, so a mistake costs nothing. ## Related quota errors Over the wire the message comes back inside an HTTP 403 whose body reads `Quota exceeded: ...` with `"reason": "quotaExceeded"`, so you may see it with that prefix. | Message | What it is | | ----------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | | `Custom quota exceeded: Your usage exceeded the custom quota for QueryUsagePerDay` | a daily byte cap an admin set on the project. See [Quotas and limits](https://docs.querylab.io/bigquery/quotas-and-limits/). | | `Custom quota exceeded: Your usage exceeded the custom quota for QueryUsagePerUserPerDay` | the same thing, per user | | `Exceeded rate limits: too many table update operations for this table` | `rateLimitExceeded`, a short-term limit. Retry with backoff. | | `Your table exceeded quota for imports or query appends per table` | too many loads or appends to one table in a day | The `reason` field in the error payload tells you which kind you have. `rateLimitExceeded` is worth retrying after a few seconds with backoff. `quotaExceeded` is not. Google's general advice for it is to wait ten minutes, but that does nothing for this particular quota, which resets monthly. ## In Querylab.io Querylab.io shows the dry-run byte estimate before you run anything, and you can set a maximum GB per query so a query above it does not get sent. See [Cost limits](https://docs.querylab.io/writing-sql/cost-limits/) and [Controlling costs](https://docs.querylab.io/bigquery/controlling-costs/). ## Sources Based on the BigQuery documentation by Google, CC BY 4.0, rewritten with examples checked against BigQuery: - [Troubleshoot quota and limit errors, Your project exceeded quota for free query bytes scanned](https://cloud.google.com/bigquery/docs/troubleshoot-quotas#your_project_exceeded_quota_for_free_query_bytes_scanned) - [BigQuery pricing, free usage tier](https://cloud.google.com/bigquery/pricing#free-usage-tier) - [BigQuery sandbox](https://cloud.google.com/bigquery/docs/sandbox)