Paging Strategies Comparing OFFSET/LIMIT and Keyset Cursor-Based Methods
Lukas Schneider
DevOps Engineer · Leapcell

Introduction
In the realm of web applications and large datasets, efficient data retrieval is paramount. When dealing with potentially millions of records, simply fetching everything at once is rarely feasible or performant. This is where pagination comes into play, allowing us to display data in manageable chunks. Two primary strategies dominate the landscape: the familiar OFFSET/LIMIT
(or SKIP/TAKE
) and the less common but often more powerful Keyset Paging (also known as Cursor-based Paging). While OFFSET/LIMIT
is typically the first choice for its simplicity, it can introduce significant performance bottlenecks as the dataset grows and users navigate deeper into the results. This inherent limitation necessitates a closer look at Keyset Paging, which offers a robust alternative for improving responsiveness and scalability. Understanding the trade-offs between these two approaches is crucial for developers aiming to build high-performance, user-friendly applications that handle large volumes of data effectively. This article will dissect both methods, comparing their underlying mechanics, performance characteristics, and ideal application scenarios to help you make informed decisions.
Body
Before diving into the comparisons, let's establish a common understanding of the core terms:
- Pagination: The process of dividing a large set of data into smaller, discrete pages, allowing users to view or process data in manageable chunks.
- Page Size: The number of records displayed or retrieved per page.
OFFSET/LIMIT
(orSKIP/TAKE
): A SQL clause combination used to retrieve a specific subset of rows from a result set.LIMIT
specifies the maximum number of rows to return, andOFFSET
specifies the number of rows to skip from the beginning of the result set before returning any rows.- Keyset Paging (Cursor-based Paging): A pagination technique that uses the values of specific columns (keys) from the last record of the previous page to determine the starting point for the next page. It effectively "points" to where the next page should begin, avoiding rescanning previous records.
- Cursor: In the context of keyset paging, a cursor refers to the identifying information (typically the values of ordered columns) that marks the last seen record, guiding the retrieval of subsequent records.
OFFSET/LIMIT Paging
Principle:
OFFSET/LIMIT
paging works by first sorting the entire result set and then skipping a specified number of rows (OFFSET
) before returning the next set of rows (LIMIT
). This is quite intuitive and directly maps to page numbers. For example, to get the 3rd page of 10 items per page, you would OFFSET 20 LIMIT 10
.
Implementation Example (SQL):
Let's assume we have a table products
with columns id
, name
, and price
. We want to retrieve products ordered by name
.
Page 1 (first 10 products):
SELECT id, name, price FROM products ORDER BY name LIMIT 10 OFFSET 0;
Page 2 (next 10 products):
SELECT id, name, price FROM products ORDER BY name LIMIT 10 OFFSET 10;
Page N (N-th page of 10 products):
SELECT id, name, price FROM products ORDER BY name LIMIT 10 OFFSET ((N - 1) * 10);
Pros:
- Simplicity: Easy to understand and implement.
- Direct Page Number Access: Allows users to jump directly to any page number.
Cons:
- Performance Degradation: As the
OFFSET
value increases, the database still has to scan and sort all preceding rows up toOFFSET + LIMIT
to identify the starting point. This becomes increasingly inefficient with larger offsets and large datasets, as the database performs more wasted work for each subsequent page. - Inconsistent Results: If records are added or deleted between page requests, a record might appear on multiple pages or be skipped entirely, leading to inconsistent user experience (e.g., seeing duplicates or missing items). If a new record is added that falls within a previously retrieved page, subsequent pages will contain different data than expected.
Applicable Scenarios:
- Small to Medium Datasets: When the total number of records is relatively small (thousands to tens of thousands) and deep pagination is rare.
- Specific Page Jumps: When users frequently need to navigate directly to arbitrary page numbers (e.g., "Go to page 50").
- Data Consistency Less Critical: In scenarios where slight inconsistencies due to data modifications between page loads are acceptable.
Keyset Paging (Cursor-based Paging)
Principle:
Keyset paging avoids the OFFSET
problem by using the values of the last record from the previous page as a "cursor" to fetch the next set of records. Instead of skipping records, it directly identifies where the next page should begin in the sorted order. This requires an ordered and, ideally, unique set of columns to define the cursor.
Implementation Example (SQL):
Continuing with the products
table, ordered by name
. To make the cursor unique and stable, it's often best to include a unique identifier (like id
) as a tie-breaker.
Initial Request (Page 1):
SELECT id, name, price FROM products ORDER BY name ASC, id ASC LIMIT 10;
Suppose the last record returned on Page 1 has name = 'Laptop'
and id = 105
.
Next Page Request (Page 2):
To get the next 10 products, we query for products whose name
is greater than 'Laptop', or if name
is 'Laptop', then id
must be greater than 105.
SELECT id, name, price FROM products WHERE (name > 'Laptop') OR (name = 'Laptop' AND id > 105) ORDER BY name ASC, id ASC LIMIT 10;
Pros:
- Consistent Performance: The query always fetches
LIMIT
rows starting from a specific point. It avoids scanning skipped rows, making performance independent of the page number. This is especially beneficial for large datasets and deep pagination. - Stable Results: New records inserted into previous pages or deletions will not cause records to appear on multiple pages or be skipped. The "cursor" always points to a consistent logical position.
- Index Utilization: This method leverages indexes effectively on the ordering columns, making queries very fast as the database can directly jump to the cursor's position.
Cons:
- No Direct Page Number Access: Users generally cannot jump directly to an arbitrary page number (e.g., "Go to page 50") without knowing the cursor for that page. It's primarily designed for "next page" / "previous page" navigation.
- Complexity: Slightly more complex to implement as it requires managing the cursor (the values of the last record) between requests. The
WHERE
clause can become complex if ordering by multiple columns with tie-breakers. - Requires Stable Order and Unique Tie-breaker: Relies on at least one unique column (or a combination of columns that are unique) to ensure a stable and unambiguous cursor.
Applicable Scenarios:
- Large Datasets: When dealing with millions of records where
OFFSET/LIMIT
becomes prohibitively slow. - Infinite Scrolling / "Next/Previous" Navigation: Ideal for interfaces where users primarily move forward or backward through results, such as social media feeds, product listings, or activity logs.
- High Concurrency/Frequent Data Changes: Guarantees more consistent results in dynamic environments.
- API Paging: A common pattern for REST APIs to paginate results between services.
Conclusion
Choosing between OFFSET/LIMIT
and Keyset Paging boils down to understanding your specific application's needs, dataset size, and user interaction patterns. While OFFSET/LIMIT
offers immediate simplicity and direct page number access, its performance degrades significantly with large datasets and deep pagination, making it prone to inconsistent results in dynamic environments. Keyset Paging, on the other hand, provides superior performance and stability for large datasets and "next/previous" navigation by leveraging indexed columns and avoiding the expensive OFFSET
operation. Ultimately, for applications demanding high scalability and consistent performance with large and dynamic result sets, Keyset Paging is the unequivocally superior choice, even with its slight increase in implementation complexity.
Therefore, for most modern applications dealing with substantial data, prioritize Keyset Paging for performance and stability, reserving OFFSET/LIMIT
for smaller, less performance-critical data sets.