Skip to content

Fix domain cache never expiring under steady traffic - #836

Open
Kash597 wants to merge 1 commit into
codelitdev:mainfrom
Kash597:fix/domain-cache-sliding-ttl
Open

Kash597 wants to merge 1 commit into
codelitdev:mainfrom
Kash597:fix/domain-cache-sliding-ttl

Conversation

@Kash597

@Kash597 Kash597 commented Oct 23, 2026

Copy link
Copy Markdown
Contributor

Problem

The in-memory domain cache (apps/web/lib/domain-cache.ts) has a 60-second TTL, but under steady traffic the entry never reloads from MongoDB.

/verify-domain calls cacheDomainByName(domain) on every request (apps/web/app/verify-domain/route.ts). In single-tenant mode resolveDomainFromHost returns getCachedDomain(...), so the domain passed back in is the cached copy, and cacheDomainByName gives it a fresh expiresAt. As long as requests keep arriving within 60 seconds, the TTL keeps sliding and the cached domain never refreshes.

Admin saves are fine because they call invalidateDomainCache. A change made directly in the database (a migration or a mongosh fix) stays invisible until the app restarts. We hit this on a self-hosted instance: a migration rewrote footer links in domains.sharedWidgets, and the site kept serving the old links for minutes, until a restart.

Fix

cacheDomainByName keeps the expiry of an existing unexpired entry and sets a fresh one only when the entry is missing or expired. invalidateDomainCache is unchanged, so an invalidated entry gets a full TTL on its next cache.

Tests

apps/web/lib/__tests__/domain-cache.test.ts gains a fake-timer test: an entry that is read and re-cached repeatedly still reloads from the database once the TTL has passed. The existing tests still pass.

🤖 Generated with Claude Code

The verify-domain route calls cacheDomainByName on every request. In
single-tenant mode resolveDomainFromHost returns the cached copy, so each
call reset expiresAt and, under steady traffic, the entry never reloaded
from MongoDB. Direct database changes stayed invisible until the app
restarted.

cacheDomainByName now keeps the expiry of an unexpired entry and only
sets a fresh one when the entry is missing or expired.
invalidateDomainCache is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant