OFFSET says 'skip N rows of whatever the table is now', not 'resume where the reader left off' — the page boundary is recomputed against moved data. Deletes above the boundary pull unseen rows into skipped territory; inserts push seen rows back into view. Keyset (cursor) pagination remembers the last row's sort key and asks WHERE key > last_seen — stable under churn, and incidentally faster.
SELECT name FROM stalls ORDER BY id LIMIT 2 OFFSET 2;
SELECT name FROM stalls WHERE id > 2 ORDER BY id LIMIT 2;
After a stall (id 2) closed between page loads, page 2's OFFSET 2 skipped 'copal' entirely — OFFSET counts rows in the table as it is now, so a delete above the boundary pulls an unseen row into skipped territory; keyset paging on the last id shows it.
Keyset pagination on a unique ordered key; OFFSET only for small, static, jump-to-page-N UIs, eyes open.