Skip to content

feat: Search pipeline run API uses pagination cursor#131

Open
yuechao-qin wants to merge 1 commit intographite-base/131from
ycq/search-pipeline-run-pagination-cursor
Open

feat: Search pipeline run API uses pagination cursor#131
yuechao-qin wants to merge 1 commit intographite-base/131from
ycq/search-pipeline-run-pagination-cursor

Conversation

@yuechao-qin
Copy link
Collaborator

@yuechao-qin yuechao-qin commented Feb 26, 2026

TL;DR

Replaced offset-based pagination with cursor-based pagination for searching pipeline runs.

Old format (offset-based, base64-encoded)

The page_token was a base64-encoded JSON blob containing offset, filter, and filter_query:

base64({"offset": 10, "filter": null, "filter_query": null})
  = eyJvZmZzZXQiOiAxMCwgImZpbH=

API request for page 2:

GET /api/pipeline_runs?page_token=eyJvZmZzZXQiOiAxMCwgImZpbH=

New format (cursor-based, plain text)

The page_token is now a plain-text created_at~id cursor pointing to the last row of the previous page:

2024-02-01T09:00:00+00:00~018d8fff

API request for page 2:

GET /api/pipeline_runs?page_token=2024-02-01T09:00:00+00:00~018d8fff

What changed?

Functional

  • Pagination mechanism: Switched from offset/limit to cursor-based pagination using created_at and id fields

Other

  • Database optimization: Added composite index ix_pr_created_at_desc_id_desc on (created_at DESC, id DESC) for efficient cursor queries
  • Query structure: Modified SQL queries to use tuple comparison (created_at, id) < (cursor_created_at, cursor_id) instead of OFFSET
  • API compatibility: Maintained existing page_token parameter while changing internal implementation

How to test?

uv run pytest tests/test_api_server_sql.py tests/test_filter_query_sql.py
  • Verify pagination works correctly with multiple pages of pipeline runs
  • Test that cursor pagination maintains stable ordering even when new records are inserted between page requests
  • Confirm no duplicate records appear across paginated results
  • Validate that invalid page tokens raise appropriate errors
  • Test pagination combined with filter queries

Why make this change?

Cursor-based pagination provides several advantages over offset-based pagination:

  • Performance: Eliminates expensive OFFSET (reads all rows that are skipped) operations on large datasets
  • Consistency: Prevents duplicate or missing records when data is inserted/deleted during pagination
  • Scalability: Query performance remains constant regardless of page depth
  • Stability: Results remain consistent even with concurrent modifications to the dataset

@yuechao-qin yuechao-qin marked this pull request as ready for review February 26, 2026 14:57
@yuechao-qin yuechao-qin requested a review from Ark-kun as a code owner February 26, 2026 14:57
@yuechao-qin yuechao-qin force-pushed the ycq/search-pipeline-run-pagination-cursor branch 2 times, most recently from ec33395 to 5a5675d Compare February 27, 2026 21:55
@yuechao-qin yuechao-qin force-pushed the ycq/search-pipeline-run-date-range branch from 1f4e7d9 to 300d652 Compare February 27, 2026 21:55
@yuechao-qin yuechao-qin changed the base branch from ycq/search-pipeline-run-date-range to graphite-base/131 February 28, 2026 10:25
@yuechao-qin yuechao-qin force-pushed the ycq/search-pipeline-run-pagination-cursor branch from 5a5675d to 8b74a37 Compare February 28, 2026 10:26
@yuechao-qin yuechao-qin changed the base branch from graphite-base/131 to ycq/search-pipeline-run-date-range February 28, 2026 10:26
@yuechao-qin yuechao-qin changed the base branch from ycq/search-pipeline-run-date-range to graphite-base/131 March 1, 2026 03:23
@yuechao-qin yuechao-qin force-pushed the ycq/search-pipeline-run-pagination-cursor branch from 8b74a37 to 9b0355f Compare March 1, 2026 03:23
@yuechao-qin yuechao-qin changed the base branch from graphite-base/131 to ycq/search-pipeline-run-date-range March 1, 2026 03:23
@yuechao-qin yuechao-qin changed the base branch from ycq/search-pipeline-run-date-range to graphite-base/131 March 2, 2026 23:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant