Redis reads work again after three weeks disabled
Shipped 2026-09-22
getRedisValue() opened with a bare return null. Every Redis read across the
API returned null from 29 August to 22 September — over three weeks in which
the platform served every request uncached and fell through to MySQL each time.
Why nothing alerted
It was asymmetric. Only reads were short-circuited; writes ran normally. So the cache warm-up logged “Successfully set data for news:en” on every boot, the Redis health check passed, and Redis itself was reachable and filling up. There was no error to raise — a read that returns null is indistinguishable from a cache miss, and a cache miss is a normal event.
That is strictly worse than either coherent state. The platform paid the cost of every cache write and received none of the benefit.
It bypassed a switch that already existed
Every Redis accessor gates on
isCacheEnabled()
— CACHE_ENABLED plus SKIP_REDIS_CHECK, configured at app level in
production. That switch is symmetric, covers reads and writes alike, and needs
no deploy to flip.
The return null sat above it. Removing the line restores CACHE_ENABLED as
the single control. If caching genuinely needs disabling, CACHE_ENABLED=false
does it properly.
How it was found
By ESLint’s no-unreachable, once TUN-875
made the linter runnable. npm run lint had never executed in api/ — the
script was a bare npx eslint . with nothing declared, so npx fetched a version
the pinned Node could not run.
One line of unreachable code concealed a three-week production regression, and the tool that would have caught it on day one had been silently broken for months.
Watch after deploy
Database load should fall as reads start hitting Redis. Worth a look in both directions: cached values written during the uncached window are as fresh as their last write, and frequently-read keys were being rewritten constantly, but a rarely-touched key with a long TTL could be stale.