# LIMIT hints
> A LIMIT usually caps the rows you get back and costs the same. On a clustered table it can also cut the bytes BigQuery reads. Querylab.io checks each query and tells you when that is the case, and only then.
Source: https://docs.querylab.io/writing-sql/limit-hints/
The status bar flags a query where a LIMIT would reduce the data read.
## When a LIMIT saves money
BigQuery normally applies `LIMIT` after the scan. The query reads every block it would read anyway, and you pay for all of it. On a clustered table the data is stored in clustering order, so a query that only needs the first rows it finds can stop reading early.
Querylab.io shows the hint only when all of these hold:
- The query is one `SELECT` that reads one stored table, and that table is clustered. A name defined in a `WITH` clause is a CTE, not a stored table, so it gets no hint.
- It has no `ORDER BY`, `GROUP BY` or `HAVING`, aggregate function such as `SUM` or `COUNT`, `DISTINCT`, window function or `QUALIFY`.
- It has no `JOIN`, no comma join, and no `UNION` or other set operation.
- It reads the table directly, not through a subquery, `UNNEST` or table function, and it has no subquery in the `SELECT` list or `WHERE`, such as `IN (SELECT ...)`, `EXISTS` or a scalar subquery.
- It is not written in pipe syntax or as a parenthesized query.
- BigQuery's dry run does not return an exact estimate. An exact estimate means the bytes read are already fixed, so no `LIMIT` can lower them, and the hint goes away once the estimate arrives.
- For a suggestion, it has no `LIMIT` of its own yet. A query that already has one is covered in [When the query already has a LIMIT](#when-the-query-already-has-a-limit).
**Query 1 · 5.47 GB | ~$0.03**
```sql
SELECT title, views
FROM `bigquery-public-data.wikipedia.pageviews_2024`
WHERE datehour = '2024-01-01 00:00:00'
```
LIMIT 1000 can cut this scan
If Querylab.io can't load the table's schema, it says nothing rather than guess.
## Adding the LIMIT
Click the status bar text. The Insights panel opens on its cost view with a card that explains the hint:
**Prism Insights → cost card**
**PRISM INSIGHTS**
LIMIT and this query
LIMIT 1000 would reduce the data read
BigQuery normally applies a LIMIT after the scan, so it caps the rows
returned without changing the cost. Here it can stop reading storage
blocks as soon as it has enough rows.
bigquery-public-data.wikipedia.pageviews_2024 is clustered on wiki,
title, which gives the scan an order it can stop on.
The estimate above will not change. The saving happens while the query
runs, and a dry run cannot see it.
Add LIMIT 1000
**Add LIMIT 1000** writes the clause at the end of the query in the editor. `Ctrl`+`Z` removes it. If you edited the query after the card appeared and it no longer qualifies, nothing is inserted and the card says so.
## When the query already has a LIMIT
If you wrote the `LIMIT` yourself and the other conditions hold, your `LIMIT` is what can stop the scan early. Querylab.io says so and changes nothing. It never adds a second `LIMIT`, which BigQuery rejects, and it never replaces yours.
The status bar for a query that already has a LIMIT.
The status bar reads _LIMIT 100 may read less_, with your row count. When the count isn't a plain number, for example `LIMIT @n`, it reads _This LIMIT may read less_. Hover it for the reason: the table is clustered, the query has no sort, aggregation or join, and the estimate can be higher than the bill.
Click the text to open the same cost card. Its first line reads _Your LIMIT 100 can stop the scan early_, it names the clustering columns, and it has no **Add LIMIT** button. `LIMIT 100 OFFSET 20` counts too, because BigQuery still stops after 120 rows.
After the run, the card shows the read-versus-estimate line described in the next section.
This text shows in **Suggest it** and **Add it automatically**. **Do nothing** shows nothing. A `LIMIT` under an `ORDER BY`, on an unclustered table or over a `JOIN` gets no text, because it only caps the rows. A negative `LIMIT` gets none either, because BigQuery rejects it.
## Why the estimate doesn't drop
The cost in the status bar comes from a dry run, and a dry run can't see an early stop. The same query estimates the same bytes with and without the `LIMIT`. That's why the hint shows no percentage before the run.
After the run, the card compares the bytes the query read with the estimate, for example _This query read 15.7 MB; the estimate said 5.47 GB._ It shows this line only when the query read less than estimated, and not for a result served from the query cache. It belongs to the query you ran, so it disappears when you edit the query. This applies to a `LIMIT` Querylab.io added and to one you wrote.
## Choosing a mode
Settings → Limits & Costs → **Default LIMIT** → _When a LIMIT would reduce the scan_:
| Mode | What happens |
| ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Suggest it** (default) | The status bar hint and the card. The query is never changed until you click **Add LIMIT**. |
| **Add it automatically** | Qualifying queries are estimated and run with the `LIMIT` appended. The text in your editor stays as you wrote it; the status bar shows _LIMIT 1000 added on run_ and the card says it is added when the query runs. If the dry run then shows the `LIMIT` can't help (an exact estimate), Querylab.io drops it: the query is estimated and run as you wrote it, and the status bar shows nothing. |
| **Do nothing** | No check, no hint. |
**Rows** sets the number used, 1000 by default.
> **A LIMIT changes your results.** Without an `ORDER BY`, which rows come back is up to BigQuery. Use the hint when you want to look at a sample of the data, not when you need every matching row.
Related: [cost limits](https://docs.querylab.io/writing-sql/cost-limits/) stop a query that would scan too much, and [TABLESAMPLE](https://docs.querylab.io/writing-sql/tablesample/) cuts the cost of queries that a `LIMIT` can't help.