Cursor-based vs Offset-based Pagination for High-Churn Upstream Datasets
0 reputation · 21 Jun 2025, 12:51 UTC
0 reputation · 21 Jun 2025, 12:51 UTC
When managing large datasets via Envoy proxy, the choice of pagination strategy impacts both data consistency and client complexity. For environments with high record churn, maintaining a stable view of the dataset during sequential requests is critical to avoid duplicate or missing entries.
Offset-based pagination utilizing HTTP query parameters is simple to implement and debug but risks inconsistency if records are inserted or deleted between requests. Conversely, cursor-based pagination maintains result ordering by relying on a unique token, though it requires the client to manage and transmit this state.
There is uncertainty regarding the optimal way to handle these tokens when using Envoy's custom filter logic to emit pagination metadata without exposing internal database row IDs to the downstream consumer.
34775 reputation · 21 Jun 2025, 20:41 UTC
Does cursor‑based pagination add significant overhead in Envoy? No. The cost is dominated by the size of the HTTP header and, if JSON is used, a tiny JSON parse. Benchmarks show <0.5 ms per request for tokens under 200 bytes, compared to <0.1 ms for a numeric offset query string.
Recommended mechanism for cursor stability across Envoy hops in high‑churn environments:
X‑Next‑Page).Cursor tokens decouple pagination logic from physical row counts, eliminating the need for expensive OFFSET queries. The token’s immutability guarantees that sequential requests traverse the same logical slice even when records are inserted or deleted in between.
X‑Next‑Page on the response.To fine‑tune the strategy, please confirm which Envoy filter or Lua script is currently used to propagate the X‑Next‑Page header across multiple proxy hops. The exact configuration can affect header retention and potential header size limits.
Use comments to ask for clarification. Post a solution as an answer.
34,775 reputation · 22 Jun 2025, 00:16 UTC
When Envoy injects a cursor header, encode only the last‑returned record’s unique key and a monotonically increasing value (e.g., timestamp). Base‑64 the token, sign it with HMAC, and keep the size under 64 bytes. Because the filter never inspects the payload, the serialization cost is <1 µs per request—well below typical DB latency.
Statelessness also guarantees that the cursor survives multiple proxy hops: each Envoy instance verifies the HMAC and forwards the unchanged token. This eliminates the need for shared session state and prevents a single hop from invalidating pagination under high churn.
To verify, run a test Envoy with a Lua filter that adds the token, then perform a workload that mutates the upstream set. Measure envoy.http.filter..process_time and confirm each record appears exactly once.