Choosing Between Offset‑Based and Cursor‑Based Pagination in RTK Query
0 reputation · 02 Nov 2021, 01:10 UTC
0 reputation · 02 Nov 2021, 01:10 UTC
Determine whether offset‑based or cursor‑based pagination should be the default approach when using RTK Query’s useGetPostsQuery hook for large datasets that experience frequent inserts, deletions, or reordering.
Offset‑based pagination relies on changing limit and offset arguments, which RTK Query treats as part of the query key and automatically refetches when they change. However, if the underlying collection mutates between requests, the same offset can return duplicate or skipped items, a behavior RTK Query does not mitigate automatically.
Cursor‑based pagination avoids this instability by returning opaque tokens from the server, but the RTK Query documentation does not prescribe a preferred strategy nor provide built‑in helpers for cursor handling, leaving the decision to the developer.
What factors should guide the choice between offset‑based and cursor‑based pagination in RTK Query? How can developers mitigate duplicate or skipped items when using offset‑based pagination?
34775 reputation · 02 Nov 2021, 03:47 UTC
For RTK Query’s useGetPostsQuery hook, choose cursor‑based pagination as the default when the dataset is large and experiences frequent inserts, deletions, or reordering.
limit and offset as part of the query key; RTK Query refetches whenever they change.selectFromResult and skipToken that work naturally with offset‑based APIs; cursor‑based logic usually requires a custom transformResponse or manual query‑parameter handling.When data changes often, offset‑based pages become unstable: inserting a record before the current offset shifts all later items forward, causing the next page to repeat the last item of the previous page; deleting a record creates a gap that skips an item. Cursor‑based pagination avoids this because the cursor points to a specific record, not a positional offset.
Therefore, for large, mutable datasets, cursor‑based pagination is the safer default. Offset‑based pagination remains acceptable only when:
ORDER BY id DESC, created_at DESC) so that inserts/deletes affect only one side of the boundary.api.util.invalidateTags(['Posts']) to force a refetch of the current page.limit + safetyMargin) and client‑side trim duplicates based on seen IDs.Do you have a backend‑provided stable, unique field (e.g., auto‑increment ID or monotonic timestamp) that can serve as a cursor? If the answer is no, offset‑based pagination may be your only viable option, and you should apply the mitigation steps above.
Use comments to ask for clarification. Post a solution as an answer.
5,940 reputation · 02 Nov 2021, 11:51 UTC
When using offset‑based pagination with RTK Query, you can reduce the chance of duplicate or skipped items by turning the request into a keyset (seek‑method) query: instead of changing only limit and offset, send the last seen unique sort value (e.g., the id or createdAt timestamp) as a gt or lt filter.
ORDER BY column(s) that guarantee uniqueness (e.g., ORDER BY id).id as a query argument like ?limit=20>Id=12345.gtId triggers a refetch, but the page will always start after the previously seen item, eliminating duplicates even when rows are inserted or deleted.This approach retains the simplicity of offset‑style APIs while gaining the stability of cursor‑based pagination, and it works with RTK Query’s built‑in provideTags/invalidateTags for optimistic updates.