← CodeClarityLab Home
Browse by Category
+ added · updated 7d
← Back to glossary

MySQL LIMIT and OFFSET Pagination

database Intermediate

Also Known As

MySQL pagination LIMIT OFFSET cursor pagination keyset pagination

TL;DR

LIMIT restricts result row count; OFFSET skips rows for pagination — but OFFSET-based pagination degrades on large tables.

Explanation

LIMIT n returns the first n rows. LIMIT n OFFSET m skips m rows first. The problem: OFFSET requires MySQL to scan and discard m rows before returning results — OFFSET 10000 scans 10,000 rows. Keyset pagination (cursor-based) avoids this: WHERE id > last_seen_id ORDER BY id LIMIT n. Keyset pagination is O(log n) via the index rather than O(n) for OFFSET.

Common Misconception

OFFSET pagination is fine for large datasets. It gets linearly slower as the offset increases — page 1 and page 10,000 have vastly different response times.

Why It Matters

Page 500 of an OFFSET-paginated 1M-row table scans 5,000 rows to return 10. Keyset pagination returns the same page in a few milliseconds via an index lookup.

Common Mistakes

  • Using OFFSET-based pagination on user-facing APIs without a page count limit.
  • Not using ORDER BY with LIMIT — results are non-deterministic without explicit ordering.
  • Calculating total pages with SELECT COUNT(*) on large tables — can be slow; use approximate counts.

Avoid When

  • Do not use large OFFSET values on production tables — OFFSET 10000 scans 10,000 rows before returning results.
  • Never use LIMIT without ORDER BY — results are non-deterministic.

When To Use

  • Use LIMIT/OFFSET for shallow pagination (first few pages) where performance is acceptable.
  • Use keyset/cursor pagination (WHERE id > :last_id) for deep pagination on large tables.

Code Examples

✗ Vulnerable
// OFFSET pagination — slow on large tables
$offset = ($page - 1) * $perPage; // page 1000 scans 10,000 rows
$stmt = $pdo->prepare('SELECT * FROM users ORDER BY id LIMIT ? OFFSET ?');
$stmt->execute([$perPage, $offset]);
✓ Fixed
// Keyset pagination — consistent performance at any page
$stmt = $pdo->prepare(
    'SELECT id, email FROM users WHERE id > ? ORDER BY id LIMIT ?'
);
$stmt->execute([$lastSeenId, $pageSize]);
$rows = $stmt->fetchAll();
$nextCursor = end($rows)['id'] ?? null;

Added 31 Mar 2026
Views 45
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings W 0 pings T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 0 pings S 0 pings S 0 pings M 2 pings T 5 pings W 3 pings T 4 pings F 0 pings S 1 ping S 0 pings M 3 pings T 6 pings W 1 ping T
ChatGPT 1
ChatGPT 4 Google 1
ChatGPT 30 Google 5 Perplexity 3 Unknown AI 2 Ahrefs 1
crawler 38 crawler_json 3
DEV INTEL Tools & Severity
⚙ Fix effort: Medium
⚡ Quick Fix
For deep pagination, switch from LIMIT/OFFSET to keyset pagination using WHERE id > :last_id ORDER BY id LIMIT :page_size
📦 Applies To
web cli
🔗 Prerequisites
🔍 Detection Hints
LIMIT ? OFFSET ? with large offset values
Auto-detectable: ✗ No
⚠ Related Problems
🤖 AI Agent
Confidence: Medium False Positives: Medium ✗ Manual fix Fix: Medium Context: Line Tests: Update

✓ schema.org compliant