I run a directory site: ~3,500 rows in Postgres, read over PostgREST, rendered by Next.js with revalidate on every route. The headline number in the shell says "Search all 3,516 listings."

For about a day it said "Search all 0 listings" — next to a grid full of listings.

The database was fine by then. Three separate bugs conspired, and all three are the same mistake wearing different clothes: a read that degrades politely on failure, sitting underneath a cache that stores the polite answer.

Bug 1: the cache dropped the header the count lived in

PostgREST returns an exact row count in the Content-Range response header if you ask for it, which is far cheaper than selecting rows and counting them: