Wrapper cache misses
Help: Zero Cache Hits – Hyperdrive Queries Bypassing Cache Straight to DB!
Hey team, I'm scratching my head over this caching mystery. Every query skips the cache and hits my Postgres DB directly (running on a Hetzner VPS), resulting in 0 cache hits for weeks. No performance magic happening here!
Quick Context:
- Using Hyperdrive for connection pooling.
- Drizzle queries are wrapped in a custom runWithDB function (code below). Reason: Prevent CF Workers from opening too many connections
- Is this wrapper the culprit? If so, what's the fix to enable proper caching?
The Suspect Code: runWithDB Function
How I Use It (Example Query):
Any insights or tweaks to get those cache hits working again? Thanks a ton! 🙌
5 Replies
Ah, it's your
prepare: false
setting getting you, probably. The message pattern that that causes the driver to generate does not play well with tx-mode poolers at all, and will often disable caching. I'd recommend removing that.
Also setting max: 1
unless you really know you want multiple concurrent queries during your Worker requests.
That should fix it. Please follow up here if it doesn't and I'll dig furtherThanks @AJR, appreciated.
However, cache hits are still at a zero, here's the updated config:
Do you think the wrapper is the issue?
No, I can't really see how it would be.
I already owe a different user some research on cache misses this week. I'll dig into it and see what I can find. Mind sending me your hyperdrive ID?
Thanks for your help. Heres the id: 6866fe8f0dc34ffc96b69e57ab91ff00
Okay, I spent some time, and got to the bottom of this. This is a rather unfortunate interaction
between the message patterns that postgres.js uses and the way Drizzle builds its queries.
In short, what Drizzle is doing here is taking the existing message pattern that postgres.js uses,
with PDH+BES chunks, and creating them with the "unnamed" prepared statement. This is the same as
what postgres.js does if you set
prepare: false
. This breaks many tx-mode poolers (such as
pgbouncer, for example), and will cause caching to be disabled in Hyperdrive.
Messages with Drizzle+postgres.js:
My suggested fix here is to switch to using Drizzle+node-postgres. It also uses an unnamed prepared
statement, however it structures its messages such that there's only a single roundtrip, which will
have less latency and also works far better with caching.
Messages with Drizzle+node-postgres:
It's also possible there's some way to tell Drizzle to quit overriding the normal behavior of
postgres.js here, and leave in the randomly-generated statement name it usually uses. I couldn't
find such an option after some brief searching, though, so I'm sticking with my "try node-postgres"
suggestion.
FYI @thomasgauvin ^.
TLDR drizzle+postgres.js breaks caching.