polycratia

The catalog list endpoint answered in about three seconds, and I spent the first stretch of that reading query plans.

Indexes first. Then prefetching, then a cache sitting in front of the ORM. Each one helped a little, and none of them moved the number, because the time was never going to the database.

That endpoint returned products for a cross-border storefront, and every row carried a shipping estimate. The estimate came out of carrier integrations: a rate lookup, per destination, per weight. A page of results meant a page's worth of outbound calls, sequential by accident, each one fast enough to look innocent on its own.

What changed in the end was the promise the response made, not the code.

Shipping estimates left the list. Rates got precomputed per destination zone and weight bucket, refreshed on their own schedule, and the exact quote moved to the item view, the one place where a buyer is actually about to commit. The list went back to reading its own tables and answered in a couple hundred milliseconds.

The honest version of that result: I did not make anything faster. I stopped doing work inside a request that never belonged there.

Since then, my first question on a slow list endpoint is not which query is heavy. I ask which fields get computed per row, and whether any of them depend on someone else's uptime. If one does, it is not a field. It is a separate call.

I write up more of how I approach this kind of work on my blog: https://polycratia.com/c/5de6bede

I would like to hear which per-row computation you ended up pulling out of a list response...

react

$ new-project --brief

or email hey@polycratia.com