Skip to content

fix(router): deduplicate concurrent loadProjectConfig fetches to prevent cache stampede#913

Merged
zbigniewsobiecki merged 1 commit intodevfrom
fix/router-config-cache-stampede
Mar 16, 2026
Merged

fix(router): deduplicate concurrent loadProjectConfig fetches to prevent cache stampede#913
zbigniewsobiecki merged 1 commit intodevfrom
fix/router-config-cache-stampede

Conversation

@zbigniewsobiecki
Copy link
Copy Markdown
Member

Summary

  • Root cause: When the cache is cold and multiple concurrent webhook requests arrive simultaneously, each one checks _projectConfigCache === null and independently calls loadConfig(), producing N×3 redundant DB queries (3 parallel queries per call). Sentry's N+1 detector flags these as issues 98589064, 98586219, 103501033, 98901392.
  • Fix: Add an in-flight promise deduplicator (_pendingConfigFetch) to loadProjectConfig() — concurrent callers with a cold cache share a single DB fetch rather than each issuing their own.
  • Test: New deduplication test fires two concurrent calls before the DB responds and asserts loadConfig is called exactly once and both callers receive the identical result.

Changed files

  • src/router/config.ts — add _pendingConfigFetch variable; wrap fetch in deduplicating IIFE with .finally() cleanup; clear in _resetProjectConfigCache()
  • tests/unit/router/config.test.ts — add concurrent deduplication test

Test plan

  • npm test — 289/289 test files, 5428/5428 tests passing
  • npm run lint — no issues
  • npm run typecheck — no issues
  • New stampede test: two concurrent loadProjectConfig() calls before DB responds → only 1 loadConfig() call, both callers get the same result object

🤖 Generated with Claude Code

…ent cache stampede

Add an in-flight promise deduplicator (_pendingConfigFetch) to loadProjectConfig() so
that concurrent webhook requests arriving while the cache is cold all share a single
DB fetch instead of each firing their own loadConfig() call. Fixes N+1 query / cache
stampede reported in Sentry issues 98589064, 98586219, 103501033, 98901392.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@zbigniewsobiecki zbigniewsobiecki merged commit 4c91c72 into dev Mar 16, 2026
11 of 12 checks passed
@zbigniewsobiecki zbigniewsobiecki deleted the fix/router-config-cache-stampede branch March 16, 2026 17:02
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