Skip to content

Add Cursor-Based Pagination to Settlement and Event Listing Endpoints #259

Description

@therealjhay

Category: New Features & Improvements
Difficulty: High

Description:
The /api/events endpoint (indexer, line 235) and /api/settlements endpoints use offset-based pagination (limit + offset). Offset pagination has known problems for large datasets:

  • Skipped/duplicate results when rows are inserted or deleted between pages
  • Performance degradation: OFFSET 10000 LIMIT 50 still scans 10,050 rows
  • Inconsistent total counts under write-heavy workloads (the total may change between pages)

Cursor-based pagination using indexed columns (initiatedAt, ledger, indexedAt) should be added as an alternative, following common patterns (e.g., Relay GraphQL Cursor Connections Spec).

Location:
services/indexer/src/index.ts:235–260, services/settlement-engine/src/index.ts:320–341, services/api-gateway/src/index.ts:772–796

Acceptance Criteria:

  • Add cursor-based pagination params to PaginationQuery in shared/validation/schemas.ts: cursor (opaque string), after (ISO date), first (int, replaces limit)
  • Implement a encodeCursor(row) / decodeCursor(cursor) pair using base64 encoding
  • Add cursor pagination support to the indexer's GET /api/events
  • Add cursor pagination support to the settlement engine's GET /api/settlements
  • Add cursor pagination support to the gateway's GET /api/settlements
  • Keep offset pagination as a fallback for backward compatibility
  • Return pageInfo: { hasNextPage, endCursor } in paginated responses
  • Write tests for cursor pagination with insertions during pagination

Technical Notes:

  • For cursor pagination with initiatedAt, use WHERE initiatedAt < :cursorDate ORDER BY initiatedAt DESC LIMIT :first.
  • Ensure the column used for cursor has a database index.
  • Encode cursor as base64(JSON.stringify({ id, date })).

Metadata

Metadata

Assignees

Labels

GrantFox OSSIssue tracked in GrantFox OSSMaybe RewardedIssue may be eligible for a GrantFox rewardOfficial Campaign | FWC26Campaign: Official Campaign | FWC26

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions