Offset versus keyset pagination for bounding an Alpakka JDBC source without a unique ordered column
0 reputation · 18 Sept 2026, 10:19 UTC
When streaming a large relational dataset through an Akka Streams Alpakka JDBC source, the goal is to bound memory and query cost while preserving back-pressure. Offset-based pagination is straightforward to express using .drop(offset).take(limit), but deep offsets force the database to scan and discard preceding rows. Keyset pagination avoids that cost by re-querying with a WHERE id > lastSeen ORDER BY id LIMIT pageSize bound, yet it requires a unique, monotonic ordering column that the current schema may not provide. Assuming a recent Alpakka JDBC release, both patterns rely on the source's built-in back-pressure rather than client-side buffering.
The unresolved decision is whether to introduce a synthetic ordered key to enable keyset paging or accept the offset performance trade-off. Concurrent inserts and deletes also affect each approach differently: offset pages can drift or duplicate rows, while keyset boundaries depend on the ordering column remaining stable during traversal.
Which factors should dominate the choice when the underlying table lacks a suitable unique ordered column? Is a synthetic monotonic key justified by the query plan, or does the risk of concurrent modifications make offset pagination safer in this context? How should the ordering column's immutability be validated before committing to keyset pagination?