Playground API
DocsStatsBlogStudio
Documentation Tree
Technical BlogFeature Deep Dives
  • Introduction
  • Quickstart
    5 min
  • How It Works
  • Recipes & Cookbooks
  • Platform Comparisons
  • Real-World Showcase
  • Interactive Studio
    Studio
  • GraphiQL IDE
    IDE
  • Session Quotas & Activity
  • Network Chaos Simulator
  • Atomic Sandbox Reset
  • Overview & Models
    Hub
  • Users Resource
  • Posts Resource
  • Comments Resource
  • Todos Resource
  • Custom Collections
    Custom
  • Multipart File Uploads
    Upload
  • Dynamic SVG Avatars
    SVG
  • Image Thumbnails
    CDN
  • Relational Filtering
  • Full-Text Search
  • Dynamic Sorting
  • Offset Pagination
  • Cursor Pagination
    Scroll
  • CSV & Excel Export & Import
    IO
  • Custom Collections
    CRUD
  • Overview & Architecture
    Hub
  • JWT Auth Flow
  • Refresh Token Rotation
    Mutex
  • RBAC Permission Matrix
    Roles
  • Expiry Simulation
  • Clock Skew Drift
  • Password Recovery Loop
  • Dual-Mode Sandboxing
  • GraphiQL IDE
    IDE
  • Relational Queries
  • Stateful Mutations
  • Realtime Subscriptions
  • Overview & Flowcharts
    Hub
  • Hosted Checkout
    Stripe
  • Payment Intents API
  • 3DS Challenge Modal
    Modal
  • Customers Vault
  • Charges & Refunds
  • Test Cards Catalog
  • Overview & Channels
    Hub
  • Virtual Email Mailbox
    Mailtrap
  • Virtual SMS Terminal
    Phone
  • In-App Notifications
  • Message Dispatcher
  • Realtime Studio
    Studio
  • Native WebSocket (/ws)
  • Socket.io Gateway
  • Presence & Echo Bot
  • Server-Sent Events (SSE)
    SSE
  • Analytics Telemetry
  • Webhook Subscriptions
  • HMAC SHA-256 Signatures
  • Delivery Logs
  • Manual Retry Simulator
  • Network Latency Delay
  • HTTP Status Codes
  • Rate-Limit Simulator
    429
  • Flaky Network & Jitter
    Chaos
  • Session Quotas & Activity
  • JSON Snapshots
    JSON
  • Headless CI/CD Testing
    CI
  • Mobile QR Code Sync
  • System Metrics & Health
  • Atomic Sandbox Reset
  • Official TypeScript SDK
  • Multi-Language Generators
  • DevTools Extension
  • OpenAPI 3.1 Spec
    JSON
  • Postman Collection v2.1
  • Bruno Collection
  • Insomnia Workspace
  • TypeScript .d.ts
    .d.ts
  • AI Prompt Rules
    Rules
  • Context Index (llms.txt)
  • Full Schema (llms-full.txt)
  • Manifest (product.json)
  • All Feature Articles
    Blog
  • React CRUD Without Backend
    Deep Dive
  • Why Static APIs Fail
  • Mocking Stateful Auth
  • WebSockets & SSE Guide
Technical Blog
Articles

In-depth articles explaining stateful mock APIs, WebSockets, payments, and frontend resilience.

Read Articles
PreviousOffset Pagination
NextCSV & Excel Export & Import
Data & Query Engine

Cursor-Based Pagination

Engineered for infinite scrolling feeds, mobile applications, and high-frequency real-time updates. Eliminates page drift and prevents duplicate items when new records are continuously added to the top of collections.

Live Cursor Window Runner

Fetch initial slice, or test passing an opaque _cursor token:

Requesting initial cursor window (start of collection).GET /posts?_limit=5
Method: GET

Live Request Console

GET
response.json
1
{
2
// Click "Send" above to execute this request against the live server.
3
}

Architectural Comparison: Offset vs Cursor

Understand the trade-offs between traditional offset numbering and modern opaque cursors:

Evaluation MetricOffset Pagination (?_page=2)Cursor Pagination (?_cursor=...)
Page Drift VulnerabilityHigh. If a new post is inserted while reading page 1, item #10 shifts to page 2 and is seen twice.Zero. Pointer anchors to the exact record boundary regardless of new items created above.
Database Query PerformanceDegrades at scale (OFFSET 50000 scans and discards 50,000 rows).Instant O(1) indexed seek (WHERE id < cursor LIMIT 10).
Direct Page Number JumpSupported. Users can jump directly to "Page 14" via table pagination bars.Sequential only. Ideal for infinite scrolling, feeds, and "Load More" buttons.
Payload Signature{ total, totalPages, page, limit }{ nextCursor, hasMore, limit, total }

Infinite Feed Client Recipes

Production patterns for TanStack Query Infinite and custom React feeds:

hooks/useInfinitePosts.ts
1
// hooks/useInfinitePosts.ts
2
import { useInfiniteQuery } from '@tanstack/react-query';
3
4
interface CursorPaginationResponse {
5
data: any[];
6
pagination: {
7
limit: number;
8
total: number;
9
nextCursor: string | null;
10
hasMore: boolean;
11
};
12
}
13
14
export function useInfinitePosts(pageSize = 10) {
15
return useInfiniteQuery<CursorPaginationResponse>({
16
queryKey: ['posts', 'infinite', pageSize],
17
queryFn: async ({ pageParam }) => {
18
const cursorParam = pageParam ? &_cursor=${encodeURIComponent(String(pageParam))} : '';
19
const res = await fetch(
20
https://playground.nileslabs.com/api/v1/posts?_limit=${pageSize}${cursorParam}`,
21
{ credentials: 'include' }
22
);
23
if (!res.ok) throw new Error('Failed to fetch cursor page');
24
return res.json();
25
},
26
initialPageParam: null,
27
// Extract opaque nextCursor returned by server
28
getNextPageParam: (lastPage) => lastPage.pagination.hasMore ? lastPage.pagination.nextCursor : null
29
});
30
}
31
32
// In your feed component:
33
// const { data, fetchNextPage, hasNextPage, isFetchingNextPage } = useInfinitePosts(10);
34
// const allPosts = data?.pages.flatMap((page) => page.data) || [];
Next Query Feature

CSV & Excel Export & Import

Related Query Feature

Offset-Based Pagination