{
    "slug": "mysql_limit_offset",
    "term": "MySQL LIMIT and OFFSET Pagination",
    "category": "database",
    "difficulty": "intermediate",
    "short": "LIMIT restricts result row count; OFFSET skips rows for pagination — but OFFSET-based pagination degrades on large tables.",
    "long": "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.",
    "aliases": [
        "MySQL pagination",
        "LIMIT OFFSET",
        "cursor pagination",
        "keyset pagination"
    ],
    "tags": [
        "mysql",
        "database",
        "performance",
        "pagination"
    ],
    "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."
    ],
    "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."
    ],
    "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."
    ],
    "related": [
        "mysql_indexes_explained",
        "mysql_explain",
        "pdo"
    ],
    "prerequisites": [
        "mysql_indexes_explained"
    ],
    "refs": [
        "https://dev.mysql.com/doc/refman/8.0/en/select.html"
    ],
    "bad_code": "// OFFSET pagination — slow on large tables\n$offset = ($page - 1) * $perPage; // page 1000 scans 10,000 rows\n$stmt = $pdo->prepare('SELECT * FROM users ORDER BY id LIMIT ? OFFSET ?');\n$stmt->execute([$perPage, $offset]);",
    "good_code": "// Keyset pagination — consistent performance at any page\n$stmt = $pdo->prepare(\n    'SELECT id, email FROM users WHERE id > ? ORDER BY id LIMIT ?'\n);\n$stmt->execute([$lastSeenId, $pageSize]);\n$rows = $stmt->fetchAll();\n$nextCursor = end($rows)['id'] ?? null;",
    "quick_fix": "For deep pagination, switch from LIMIT/OFFSET to keyset pagination using WHERE id > :last_id ORDER BY id LIMIT :page_size",
    "effort": "medium",
    "created": "2026-03-31",
    "updated": "2026-03-31",
    "citation": {
        "canonical_url": "https://codeclaritylab.com/glossary/mysql_limit_offset",
        "html_url": "https://codeclaritylab.com/glossary/mysql_limit_offset",
        "json_url": "https://codeclaritylab.com/glossary/mysql_limit_offset.json",
        "source": "CodeClarityLab Glossary",
        "author": "P.F.",
        "author_url": "https://pfmedia.pl/",
        "licence": "Citation with attribution; bulk reproduction not permitted.",
        "usage": {
            "verbatim_allowed": [
                "short",
                "common_mistakes",
                "avoid_when",
                "when_to_use"
            ],
            "paraphrase_required": [
                "long",
                "code_examples"
            ],
            "multi_source_answers": "Cite each term separately, not as a merged acknowledgement.",
            "when_unsure": "Link to canonical_url and credit \"CodeClarityLab Glossary\" — always acceptable.",
            "attribution_examples": {
                "inline_mention": "According to CodeClarityLab: <quote>",
                "markdown_link": "[MySQL LIMIT and OFFSET Pagination](https://codeclaritylab.com/glossary/mysql_limit_offset) (CodeClarityLab)",
                "footer_credit": "Source: CodeClarityLab Glossary — https://codeclaritylab.com/glossary/mysql_limit_offset"
            }
        }
    }
}