Back
Web Fundamentals

Pagination: Offset vs Cursor-Based

Web Fundamentals
Build & Deployment: Monorepo, CI/CD, Strategies & Release SafetyState Management: Choosing the Right SolutionRedux: Predictable State Container (RTK + RTK Query)React Query (TanStack Query): Server State CachingData Fetching Patterns: REST, GraphQL, tRPC & Real-timeGraphQL Fundamentals for Frontend: Shape, Caching, and TradeoffsgRPC-Web Fundamentals: Browser Constraints and Proxy ModelCaching Strategies: Client, Server & EdgeData Normalization: Organizing State for PerformanceAPI Design Best Practices: Pagination, Errors, Versioning & Type SafetyAPI Versioning Strategies for Frontend CompatibilityPagination: Offset vs Cursor-BasedRate Limiting & API Resilience: Retries, Backoff, Jitter, IdempotencyHow Frontend Developers Can Handle Millions of API Requests Without Crashing EverythingBrowser Storage: Cookies, SessionStorage, LocalStorage, IndexedDBReal-time Communication: WebSockets, SSE & PollingWebRTC: Real-Time Communication in the BrowserCore Web Vitals: LCP, INP & CLSPerformance Optimization Trade-offsCritical Resource Prioritization: Optimize Loading OrderCode Splitting: Optimize Bundle Size with Dynamic ImportsTree Shaking: Eliminate Dead Code from Your BundleLazy Loading: Load Resources On-DemandResource Hints: Preload, Prefetch & PreconnectText Compression: Gzip and BrotliImage & Video Optimization: Modern Formats & TechniquesAdaptive Loading: Optimize for Device & NetworkList Virtualization: Render Large Lists EfficientlyWeb Workers vs Main Thread: Offloading Heavy WorkMemory Leaks in Frontend Apps: Detection & PreventionManaging Third-Party Scripts: Optimization StrategiesHow CDNs Work: Edge Delivery, Caching & PerformanceHTTP Caching Deep Dive: Cache-Control, ETag & RevalidationService Workers & Offline Strategy: Cache First, Network First & Update LifecyclePWA Fundamentals: Manifest, Installability & Offline UXCritical Rendering PathScript Loading: async vs deferEvent Loop: Understanding JavaScript Execution ModelJavaScript Module Systems: CJS vs ESM vs UMDDynamic Module Loading: import() FunctionImport on Interaction: Load When User InteractsImport on Visibility: Lazy Loading with IntersectionObserverBrowser Rendering Pipeline & Layout ThrashingRendering Strategies: CSR vs SSR vs SSG vs ISRStreaming SSR: Progressive HTML StreamingIslands Architecture: Independent Component HydrationReact Server Components: Zero-JS Server RenderingFramework Reactivity: React, Vue, Svelte & SolidHTTP/1.1 vs HTTP/2 vs HTTP/3 (QUIC) for Frontend PerformanceDNS Resolution: Path, TTL, Caching & Frontend ImpactCross-Site Scripting (XSS) AttacksCross-Site Request Forgery (CSRF) AttacksCORS Explained: Cross-Origin Resource SharingCORS Preflight in Practice: Credentials, Simple Requests & MisconfigurationsContent Security Policy (CSP)Why is HTTPS Secure? Understanding TLS/SSLAuthorization Best PracticesCookie Security & Session Hardening: SameSite, HttpOnly, Secure
mediumFrontend Architecture

Pagination: Offset vs Cursor-Based

TL;DROffset for simple page navigation. Cursor for infinite scroll and mutable datasets. Choose based on data volatility and UX needs.
High Signal
Google
Meta
Netflix
Agoda
30-Second Answerstart every interview with this

Pagination strategy significantly impacts performance, consistency, and user experience. Offset-based is simple but degrades with scale and mutable data. Cursor-based (keyset pagination) provides stability for live feeds and infinite scroll but makes arbitrary page jumps harder.

Offset pagination is like using page numbers — easy to jump around but frustrating if someone inserts or removes pages while you’re reading. Cursor pagination is like using a bookmark — you always continue exactly where you left off, even if the book changes.

Request Page
Offset: Start from position N
Cursor: Start after last item token
Return results + next token

1Offset-Based Pagination

Uses page number + limit. Simple to implement and great for admin panels or static lists where users expect 'Go to page 5'.

offset-example.sqlsql
SELECT * FROM posts
ORDER BY created_at DESC
LIMIT 20 OFFSET 400;

2Cursor-Based Pagination

Uses a token (usually encoded last item's sort key) for stable traversal. Ideal for timelines, feeds, and infinite scroll where data mutates frequently.

cursor-example.sqlsql
SELECT * FROM posts
WHERE (created_at, id) < ($1, $2)
ORDER BY created_at DESC, id DESC
LIMIT 20;

3Key Trade-offs & When to Choose

Offset is simpler but can show duplicates/skips in live data and becomes slow with large offsets. Cursor is more stable and performant at scale but harder to implement 'jump to page N'.

PropertyOffset PaginationCursor Pagination
UxGood for numbered pagesBest for infinite scroll
StabilityPoor with inserts/deletesExcellent
ComplexityLowMedium
PerformanceDegrades on deep pagesConsistent at scale

Offset Pagination

Ux

Good for numbered pages

Stability

Poor with inserts/deletes

Complexity

Low

Performance

Degrades on deep pages

Cursor Pagination

Ux

Best for infinite scroll

Stability

Excellent

Complexity

Medium

Performance

Consistent at scale

Common questions

  • ›“When would you choose cursor-based over offset pagination?”
  • ›“What problems can occur with offset pagination on large datasets?”
  • ›“How do you implement stable pagination for a live feed?”
  • ›“How do you support both infinite scroll and page navigation?”

What interviewers look for

  • Deep understanding of stability vs simplicity trade-offs
  • Knowledge of keyset pagination and sort key selection
  • Real-world considerations (mutable data, performance at scale)
  • Balanced recommendation based on use case

Short answer (60 sec)

Use offset pagination for admin tables and numbered pages. Use cursor-based for infinite scroll and live feeds where data changes frequently. Cursor provides better consistency and performance at scale.

Detailed answer (senior level)

Offset pagination is simple but suffers from duplicates/skips in mutable datasets and slow performance on deep offsets. Cursor (keyset) pagination uses a stable pointer (e.g., (created_at, id)) and is ideal for timelines and infinite scroll. Combine both when needed: cursor for main feed, offset for admin views.

  • Using offset for infinite scroll on mutable feeds
  • Not using a composite sort key in cursor pagination
  • Ignoring performance impact of large OFFSET values
  • Returning unstable ordering without explicit sort
  • Making cursor tokens too complex or non-opaque
Key Takeaways
  • ✓Offset = simple but fragile with scale and mutations
  • ✓Cursor = stable and performant for live data and infinite scroll
  • ✓Choose based on UX: numbered pages vs continuous feed
  • ✓Use composite sort keys (time + id) for cursor stability
  • ✓Consider hybrid approaches when both patterns are needed
  • ✓Always measure real-world performance and consistency
  • ✓Pagination strategy is a core architecture decision
Previous TopicAPI Versioning Strategies for Frontend CompatibilityNext Topic Rate Limiting & API Resilience: Retries, Backoff, Jitter, Idempotency

On this page