polycratia

A fast database and a slow API do not contradict each other. Usually it's the same story: your query time is fine, your connection acquisition time is not.

The mechanic goes like this.

A request checks out a database connection, and somewhere inside that scope it calls someone else's system: a carrier rate lookup, a KYC provider, a payment gateway. The query itself has already finished. The connection stays checked out anyway, doing nothing but waiting on a socket you don't control.

So the pool becomes a budget, and an upstream you don't own is spending it. One carrier gets slow and every endpoint in the service degrades, including the ones that never touch that carrier. The database stays fast the whole time, and your query metrics keep saying so, which is why the investigation lands in the wrong place.

What I do about it:

Measure pool acquisition wait as its own number, separate from query execution. If you only have one latency metric for the database, you can't see this at all.

Don't hold a transaction open across an external HTTP call. Commit before, or defer the call after, but don't straddle the two.

Give every third-party client a timeout shorter than the pool's wait, plus its own concurrency limit, so a degraded upstream starves itself instead of the shared pool.

The general rule: latency accrues to whatever resource is held longest, not to whatever is slowest.

I went deeper on how this plays out in payment and delivery integrations on the blog: https://polycratia.com/c/6b118266

Worth knowing where your pool gets drained first: an external provider, or something internal you had stopped thinking of as a network call...

react

$ new-project --brief

or email hey@polycratia.com