Fun with Learning Technology
LearnCoursesQuestionsTracksToolsNewsExplorePractice
Fun with Learning Technology

A new problem, explained clearly, every day.

Subscribe
Learn
  • Lessons
  • Topics
  • News
  • Tools
  • Courses
  • Career tracks
  • Everything
Site
  • About
  • Contact
  • Support
  • Privacy
  • Terms
Get the daily one

One email per new problem. No spam.

Request a tutorial

Requests shape what gets made next.

© 2026 Fun with Learning TechnologyRSS
Home›Courses›SQL›Limiting Results — LIMIT and OFFSET

Basics

Limiting Results — LIMIT and OFFSET

Limiting results involves restricting the number of rows returned by a query, while offsetting allows skipping a specific number of records. These techniques are essential for managing large datasets by processing or displaying data in manageable portions. You reach for these clauses whenever you implement pagination, performance optimization, or need to retrieve a subset like 'top N' records.

The Fundamental Purpose of LIMIT

The LIMIT clause serves as a critical mechanism for resource management and data exploration within a relational database. When you execute a query without any constraints, the database engine retrieves every row that satisfies the specified criteria, which can lead to excessive memory consumption, slow network transfer times, and an overwhelming volume of data for the client application to handle. By applying a LIMIT, you instruct the database engine to halt the retrieval process as soon as it has collected the requested number of records. This is not merely a cosmetic choice but a performance optimization strategy that reduces I/O pressure on the server and improves the responsiveness of your applications. Understanding this allows you to reason about how databases handle massive tables, knowing that the engine prioritizes completing the request quickly rather than exhaustive scanning when a cap is defined. This is the cornerstone of query efficiency, especially when exploring tables that hold millions of distinct entries.

-- Retrieve only the five most recent orders placed in the system.
-- This prevents loading thousands of historical records into memory.
SELECT order_id, customer_id, order_date 
FROM orders 
ORDER BY order_date DESC 
LIMIT 5;

Achieving Deterministic Results

A common misconception among developers is that a LIMIT clause will always return the same records regardless of the query structure. In reality, relational databases do not guarantee any inherent order for data retrieval unless an ORDER BY clause is present. Without a specific sorting instruction, the database engine returns records in the order it finds them, which might change depending on storage location, indexes, or maintenance operations. Therefore, to ensure that your limit behaves reliably, you must combine it with a deterministic sorting condition. By defining an explicit column order—such as chronological or numerical—you force the database to yield a predictable subset every time the query runs. This logical pairing is vital when designing systems where data consistency is paramount, such as logs or transaction histories, where the 'top' items must always satisfy the same business-defined logic regardless of the table's underlying physical storage state or background processing updates.

-- Ensure the top 10 highest-valued transactions are retrieved consistently.
-- Always pair LIMIT with ORDER BY for predictable results.
SELECT transaction_id, amount 
FROM transactions 
ORDER BY amount DESC 
LIMIT 10;

Introducing OFFSET for Pagination

Once you master limiting, the logical next step is accessing data beyond the first set of results. The OFFSET clause enables you to skip a designated number of initial records before the database begins returning the data requested by the LIMIT clause. This is the backbone of pagination, allowing an interface to display discrete segments of a large dataset to a user. When you use OFFSET, the database engine effectively scans past the skipped rows but does not include them in the final result set. While this is extremely powerful, it is important to understand that the database still performs the work of identifying those rows before discarding them. As the offset value increases, the performance cost grows linearly because the database must process the skipped records to verify the sequence. This realization helps you reason about scaling; while simple pagination is fine for small tables, very large datasets might require indexed keys instead of simple offsets for high performance.

-- Skip the first 20 products and retrieve the next 10 items.
-- This is the standard pattern for page 3 of a list (if page size is 10).
SELECT product_name, price 
FROM products 
ORDER BY product_name ASC 
LIMIT 10 OFFSET 20;

Combining LIMIT and OFFSET Logic

The interaction between LIMIT and OFFSET is best understood as a windowing function that slides across your result set. When you define both, the database engine first applies the sorting criteria, effectively constructing an ordered list of all matching records. The OFFSET value serves as the starting point, acting as an index that defines the 'skip' threshold, while the LIMIT value defines the size of the 'window' of data to capture immediately after that threshold. Because the database engine calculates these values in sequence, you can reason about complex data slicing requirements by visualizing the data as an array. This approach allows you to implement 'infinite scroll' features or 'next page' functionality by dynamically calculating the offset based on the current page number. Understanding this flow is essential for debugging queries where you expect specific data points but receive unexpected results because the offset count was miscalculated relative to the intended window.

-- Calculate an offset for dynamic pagination.
-- Here, we retrieve rows 11 through 15 from the employee table.
SELECT employee_name, department 
FROM employees 
ORDER BY hire_date 
LIMIT 5 OFFSET 10;

Performance Considerations and Constraints

While LIMIT and OFFSET are indispensable for user interfaces, they carry implicit performance costs that you must acknowledge when designing high-throughput systems. Because the database must account for the offset rows, processing an offset of 10,000 is significantly more expensive than an offset of 10. The engine must traverse the index or perform a full sort before it can even begin to output the data you requested. To optimize your queries, you should strive to minimize large offsets and instead rely on keyset pagination—filtering by the last seen ID or timestamp—whenever possible. This is a crucial distinction for advanced developers; while LIMIT/OFFSET is the standard syntax for initial implementations, it is not always the most scalable solution for massive data sets. By understanding that these commands force the database to do sequential work before returning the result, you can design your data access patterns to be far more efficient, ensuring your database remains performant even under heavy load.

-- A large offset can be slow on massive tables.
-- Consider filtering by ID directly if large jumps are needed.
SELECT log_message 
FROM application_logs 
ORDER BY log_id DESC 
LIMIT 50 OFFSET 10000;

Key points

  • LIMIT restricts the number of rows returned to manage memory and performance.
  • OFFSET allows the query to skip a specific number of records before returning data.
  • The combination of ORDER BY and LIMIT is required for consistent, deterministic results.
  • Pagination is typically implemented by combining LIMIT for page size and OFFSET for current position.
  • Database engines process OFFSET records even though they are excluded from the final output.
  • Performance degrades as the OFFSET value increases because the database performs more internal traversal.
  • Large offsets can be avoided by using keyset pagination where the next set is requested based on the last row's unique identifier.
  • Use these tools to prevent over-fetching data that the application layer does not actually require.

Common mistakes

  • Mistake: Expecting LIMIT and OFFSET to return the same results without an ORDER BY clause. Why it's wrong: SQL does not guarantee row order; without explicit sorting, the database engine may return rows in any arbitrary order. Fix: Always pair LIMIT and OFFSET with an ORDER BY clause to ensure consistent, deterministic results.
  • Mistake: Assuming OFFSET 10 means you are retrieving the 10th row. Why it's wrong: OFFSET counts the number of rows to skip, not the position. OFFSET 10 skips the first 10 rows and starts at the 11th. Fix: Use OFFSET N-1 to begin retrieving data starting from the Nth row.
  • Mistake: Using LIMIT to perform pagination without sorting. Why it's wrong: If the underlying data changes (inserts or deletes) between queries, unsorted pagination will lead to skipped or duplicated records across pages. Fix: Use a stable sort key (like a unique ID) alongside ORDER BY to maintain data consistency during pagination.
  • Mistake: Including OFFSET without a LIMIT clause in certain SQL dialects. Why it's wrong: Many database engines enforce that OFFSET must be accompanied by a LIMIT clause, or they simply do not support OFFSET alone. Fix: Always provide a LIMIT value when using OFFSET to define the size of the result set.
  • Mistake: Attempting to use LIMIT in a subquery or CTE without an ORDER BY. Why it's wrong: LIMIT within a subquery is often ignored by query optimizers if the result set is considered unordered, leading to unexpected results. Fix: Ensure the subquery explicitly sorts data before applying the LIMIT.

Interview questions

What is the primary purpose of the LIMIT clause in SQL?

The LIMIT clause is used to restrict the number of rows returned by a query result set. It is essential for performance and user experience, especially when dealing with large datasets. By using LIMIT, you prevent the database from sending more records than the application can process or display at once. For example, if you execute 'SELECT * FROM users LIMIT 10;', the database will stop searching and return only the first ten rows found, which significantly reduces network traffic and memory usage.

How does the OFFSET clause function, and why is it usually paired with LIMIT?

The OFFSET clause tells the database how many rows to skip before beginning to return the actual results. It is rarely used in isolation because, without a LIMIT clause, it would simply return all remaining records after the skipped ones. When paired with LIMIT, they form the foundation of pagination. For instance, 'SELECT * FROM products ORDER BY price LIMIT 20 OFFSET 40;' fetches products 41 through 60, allowing users to navigate through large catalogs page by page.

Why is it critical to include an ORDER BY clause when using LIMIT and OFFSET?

In SQL, result sets are not guaranteed to be returned in any specific order unless an ORDER BY clause is explicitly used. If you paginate results using LIMIT and OFFSET without sorting, you might encounter inconsistent data where rows appear on multiple pages or disappear entirely during subsequent requests because the underlying physical storage order can change. Including a consistent sorting criteria ensures that the data maintains the same logical sequence across different paginated views, providing a stable experience.

How can you implement pagination for a high-performance system using LIMIT and OFFSET, and what is its limitation?

To implement pagination, you calculate the OFFSET as (page_number - 1) * page_size and combine it with the LIMIT clause. While this is simple to implement, the limitation is performance degradation on very large datasets. As the OFFSET value increases, the database engine must still scan and discard all the rows prior to the offset. If you need to skip 100,000 rows to get to the next page, the query becomes increasingly resource-intensive and slower over time.

Compare the 'OFFSET' approach to pagination with the 'Keyset Pagination' (or Seek Method) approach.

The OFFSET approach uses a simple integer-based skip, which is easy to code but suffers from performance issues at high offsets and data drift where items might be skipped or duplicated if rows are inserted or deleted. In contrast, Keyset Pagination uses a 'WHERE' clause to filter based on the last seen value—such as 'WHERE id > last_seen_id LIMIT 20'. This is significantly faster because the database can use an index to jump directly to the target rows, avoiding a full scan of the discarded items.

Explain how you would handle a scenario where multiple rows share the same values in an ORDER BY column when using LIMIT and OFFSET.

When rows have identical values in the column specified by ORDER BY, the relative order of those rows is non-deterministic. If you use LIMIT and OFFSET on such a set, pagination results might become unstable. To resolve this, you must always include a tie-breaker column, such as a unique primary key, in your ORDER BY clause. For example, 'ORDER BY created_at DESC, id ASC' ensures that even if two rows were created at the exact same time, their order remains fixed, preventing inconsistent data presentation.

All SQL interview questions →

Check yourself

1. Which of the following is the most reliable way to implement pagination in SQL?

  • A.Using LIMIT without any other clauses
  • B.Using OFFSET only to navigate to specific page numbers
  • C.Using ORDER BY a unique column, followed by LIMIT and OFFSET
  • D.Using a WHERE clause to filter IDs without sorting
Show answer

C. Using ORDER BY a unique column, followed by LIMIT and OFFSET
Option 3 is correct because sorting by a unique column ensures the order of rows remains stable between pagination requests. Option 1 is unreliable due to non-deterministic row order. Option 2 is incorrect as OFFSET alone cannot define the number of items returned. Option 4 does not guarantee the sequence of rows retrieved.

2. If you have 100 rows and execute 'SELECT * FROM users ORDER BY id LIMIT 10 OFFSET 20', which rows are returned?

  • A.Rows 20 through 30
  • B.Rows 21 through 30
  • C.Rows 1 through 10
  • D.Rows 10 through 20
Show answer

B. Rows 21 through 30
Option 2 is correct because OFFSET 20 skips the first 20 rows, and LIMIT 10 fetches the next 10 (rows 21-30). Option 1 is incorrect because it confuses OFFSET with 1-based indexing. Option 3 ignores the OFFSET, and Option 4 misinterprets the syntax.

3. Why is ORDER BY mandatory when using OFFSET for pagination?

  • A.To improve the performance of the query execution
  • B.To ensure that the database engine can find the offset point
  • C.To guarantee that rows are skipped consistently across multiple queries
  • D.To prevent the error that occurs when OFFSET is used without sorting
Show answer

C. To guarantee that rows are skipped consistently across multiple queries
Option 3 is correct because relational databases do not have a natural order; without sorting, the 'previous' page and 'next' page might return the same rows. Option 1 is incorrect as sorting usually adds overhead. Option 2 and 4 are false as most engines do not require ORDER BY for syntax, but for logical consistency.

4. What happens if the LIMIT value is greater than the number of remaining rows after applying the OFFSET?

  • A.The query returns an error
  • B.The database returns all remaining rows up to the end of the set
  • C.The query returns an empty result set
  • D.The query hangs until more data is inserted
Show answer

B. The database returns all remaining rows up to the end of the set
Option 2 is correct; LIMIT specifies the maximum number of rows, so if fewer rows exist, the engine returns all available rows. Option 1 and 3 are incorrect as the query remains valid and yields existing data. Option 4 is false as SQL queries are independent of future data state.

5. If a table has 50 rows and you use 'LIMIT 10 OFFSET 45', what is the result?

  • A.The query returns 10 rows
  • B.The query returns 5 rows
  • C.The query returns an error because 45+10 > 50
  • D.The query returns 0 rows
Show answer

B. The query returns 5 rows
Option 2 is correct because after skipping 45 rows, only 5 rows remain, so the database returns all of them. Option 1 is incorrect as it assumes the LIMIT overrides availability. Option 3 is false as there is no overflow error. Option 4 is incorrect because there is data left after the offset.

Take the full SQL quiz →

← PreviousSorting with ORDER BYNext →NULL Values and IS NULL

SQL

32 lessons, free to read.

All lessons →

Track your progress

Sign in to mark lessons done, score quizzes and keep notes.

Open in the app