polycratia

The endpoint returned 24 products. It took 3 seconds to do that, and the products were not the slow part.

Broad catalog searches on a cross-border shop kept timing out. The plan for the page itself looked fine: filtered, indexed, 24 rows, milliseconds.

Then I logged the statements separately. One of them was the page. The second was the exact total for pagination: a count over the same filtered set, no limit, walking the whole matching range so the UI could print a number and render page links.

Nobody needed that number. It came from serializer defaults set years earlier, and it was the only query in the request whose cost grew with the catalog instead of with the page.

I swapped it for limit+1: fetch one extra row, tell the client whether a next page exists, and keep exact totals only where a human acts on them (moderation queues, reconciliation reports).

What I kept from it: in a read endpoint, look first for the work whose cost scales with the dataset instead of with the response. Usually that is totals, facets and aggregates bolted onto a payload that is cheap by itself.

So the first question I now ask of a list API is who reads the total, and what they do with it. More often than expected, nobody.

Probably worth checking where your own list endpoints still compute an exact count...

react

$ new-project --brief

or email hey@polycratia.com