Page-number pagination

  • The classic “Page 1, Page 2, Page 3…” you see in Google
  • Ask for ?page=3&limit=20 and the server skips the first 40 records and returns records 41-60.
  • The problem,
    • If new data is inserted or deleted between page requests, records can shift — you might see duplicates or skip items entirely.
    • It also gets slower on large datasets because the database has to count/skip all the preceding rows.

Cursor-based pagination 

  • Says “give me the next N items after this specific point.”
  • The “cursor” is an opaque token (could be an encoded timestamp, a transaction hash, a DynamoDB LastEvaluatedKey, etc.) that acts as a bookmark.
  • The problem,
    • You can’t jump directly to “page 5.” It’s strictly forward (or backward) sequential navigation.
  • Advantages,
    • Stable results - new transactions arriving don’t cause items to shift between pages
    • Fast on DynamoDB — DynamoDB natively returns a LastEvaluatedKey that works exactly as a cursor; page-number pagination would require scanning and discarding rows
    • Works well with real-time data - blockchain transactions are continuously being added, so offset-based pagination would constantly produce inconsistent results
Request 1: GET /transactions?limit=20
 
Response:  { transactions: [...20 items...], hasMore: true, nextCursor: "eyJ0cyI6MTcwOTAwMH0=" }
 
Request 2: GET /transactions?limit=20&cursor=eyJ0cyI6MTcwOTAwMH0=
 
Response:  { transactions: [...20 items...], hasMore: true, nextCursor: "eyJ0cyI6MTcwODUwMH0=" }
 
Request 3: GET /transactions?limit=20&cursor=eyJ0cyI6MTcwODUwMH0=
 
Response:  { transactions: [...12 items...], hasMore: false }