polycratia

Your database dashboard shows you the fastest part of the request. That is why it keeps looking innocent.

Query execution gets measured per call. API latency gets paid per request. Different units, and the gap between them is where the seconds live.

Round trips. Two hundred queries at two milliseconds each is four hundred milliseconds of waiting, and every single one of them is genuinely fast. The database is honest: the count is the problem.

Pool acquisition. Time spent waiting for a free connection sits inside no query timer. Under concurrency it dominates, and the database still reports healthy load, because it is not executing anything: it is being queued for.

Scope. A connection held while the handler does non-database work, an external provider call or a file write, is a slot nobody else can use. That turns one slow dependency into a database-shaped outage.

Then serialization: rows come back in milliseconds, hydrating and encoding a deeply nested payload does not.

My rule from years of payment and marketplace backends: measure latency in the request's frame of reference, not the database's. Per request, record queries issued, connections acquired, time spent waiting for one, bytes serialized.

A fast database sitting next to a slow API usually means the time is between the queries, not inside them.

I go deeper on this kind of thing on my blog: https://polycratia.com/c/cdbfbb8f

Last time you chased this, where did it actually turn out to be: query count, pool wait, or serialization?

react

$ new-project --brief

or email hey@polycratia.com