A travel platform of Expedia's kind offers a cursor-paginated API at 100 records per page. A partner must sync 12 million records nightly inside a 4-hour window. Roughly how long does that take serially, and what does the arithmetic rule out?
Show the full answer Hide the answer
The assumptions, stated
12 million records, 100 per page, a round-trip time of 80 ms to the partner's region, and 20 ms of server time per page. Pages must be fetched in sequence, because each cursor comes from the previous response.
The arithmetic
pages = 12,000,000 / 100 = 120,000
time per page = 80 ms RTT + 20 ms server = 100 ms
serial time = 120,000 × 0.1 s = 12,000 s ≈ 3.3 hours
Inside a 4-hour window with almost nothing to spare - and that is the optimistic case, with no retries, no rate limiting and no slow pages. One pause of a few minutes, or one p99 page at 2 seconds every hundred pages, and the window is missed.
The structural problem is visible in the ratio: of the 100 ms per page, 80 ms is waiting for the network. The system spends 80% of a 3.3-hour job doing nothing, because cursor pagination is inherently sequential.
What changes it, in order of effect
- A larger page. 1,000 records per page cuts the round trips to 12,000 and the serial time to 20 minutes, a tenfold improvement from one parameter. The costs are real and manageable: bigger responses, longer server-side queries, and a worse retry granularity - a failed page now loses 1,000 records' worth of work.
- Partitioned parallelism. Split the key space - by region, by supplier, by id range - into 10 independent cursor streams the partner can fetch concurrently. This is an API design decision, not a client tuning choice: without a partitionable cursor, the partner cannot parallelise at all, and a cursor that encodes a single global ordering forbids it by construction.
- A bulk export. For a full nightly snapshot, the right answer is usually not an API at all: produce a compressed file per partition in object storage and hand over a signed URL. 12 million records at 500 bytes is about 6 GB, 1.5 GB compressed, which transfers in minutes and costs a fraction of 120,000 requests to serve.
- Incremental sync. If only 2% of records change daily, the nightly job should move 240,000 records, not 12 million - which needs a reliable change timestamp or a change feed, and that is the real deliverable.
Which assumption dominates the error
The round-trip time, not the page size or the server. At 20 ms RTT the serial job is 50 minutes and nobody notices the design; at 200 ms it is 6.7 hours and no page size saves it. Partner latency is therefore part of your API's capacity model, and a design validated against a same-region client will fail for a partner on another continent.
What the number rules out
It rules out "100 per page, fetched serially" as a bulk-transfer mechanism at this volume - the margin is too thin to survive normal variance. A paginated API is a browsing interface being used as a data pipe, which works up to a few hundred thousand records and stops working somewhere around a million.
When this is the wrong thing to optimise
When the partner needs changes rather than everything, and the change volume is small - a few thousand records an hour through a cursor endpoint is exactly what the design is for, and a bulk export would be heavier machinery for less timely data. The rule: cursors for deltas, files for snapshots.