# Cursor pagination

Newest-first pages over canonical records.

## Read a page


```ts
const first = await db.from("todos").author(pubkey).page(20);
if (first.meta?.nextCursor) {
  const second = await db.from("todos").author(pubkey).page(20, {
    cursor: first.meta.nextCursor,
  });
}
```

Rows sort by newest update timestamp, then lowest event ID. Tokens include the namespace, table, timestamp, and event ID. Tokens from another namespace or table are rejected. Keep the same author and field filters across pages; the token does not bind those filters or freeze a snapshot. Keep public and private cursors separate.

Pages cannot use custom `order()` or `range()`. The SDK narrows requests with `until`, refreshes candidate addresses without that bound, and applies the cursor after latest-version resolution. Private pages do the same on ciphertext. `.local()` pages read the cache only.

Relays can cap results, omit records, or prune history. A full page can produce a cursor even when the next page is empty. Concurrent edits can move rows between pages. Requests and deletion checks can require multiple bounded relay rounds. This does not provide global pagination or SQL snapshots.
