Skip to content

3.5 Pagination, batching, and the starvation trap (batchSafe)

MATCH (me:AssistantUser)-[:EMAILED]->(p:Person)-[:HAS_GITHUB]->(g)-[:RAISED]->(i:GitHubIssue)
RETURN p.name, i.title

Means: “Issues raised by everyone I email.” This binds many anchors (every person you email), each resolving to a GitHub login.

How it executes:

  • Probe binds all the emailed people; the bridge resolves each to a login → ['devone', 'devtwo', 'devthree', …].
  • Fetch — the subtlety. Could the engine pass all logins to GitHub’s issue search in one call, author:devone author:devtwo …? It must not, and this is why batchSafe: false exists on that producer: GitHub issue search returns one globally-ranked, capped list (most-recently updated first). A prolific author fills the cap; a low-volume colleague’s issues fall off the end — so you’d see them for one question and find nothing for the next. With batchSafe: false the engine fetches one author per call, giving each their own budget.
  • Pagination. Each per-author search walks pages (paging: { style: page, size: 100, maxPages: 10 }) and accumulates, so an author with 250 issues yields all 250 (3 pages), not just the first 100. Page numbering starts at 1 by default. For a zero-based source, declare paging: { style: page, startPage: 0, size: 200, maxPages: 2 }; that fetches pages 0 and 1. maxPages counts calls, not absolute page numbers.
  • Materialize / run / roll back.

The cost levers, conceptually:

  • maxKeysPerCall — how many keys go in one call (the endpoint’s IN/OR cap). Keeps a wide traversal from becoming N+1.
  • batchSafe: false — a capability, not a number: “one call is not complete per key.” Forces one key per call regardless of maxKeysPerCall, so a realm can’t reintroduce starvation by tuning.
  • paging: — capture beyond the first page; startPage matches the source’s page-number origin, while maxPages bounds how many pages are fetched.
  • If pagination hits maxPages with a still-full last page, the source has more than was fetched → the result carries a PARTIAL_RESULT truncation note (§9) — never a silent “that’s everything.”