PATTERN Cited by 1 source
JWKS cache with thundering-herd protection¶
Intent¶
Cache the identity provider's JSON Web Key Set (JWKS) to avoid per-request network calls for JWT signature verification, while protecting the JWKS endpoint from a thundering herd when the cache expires or a key rotation triggers a cache miss.
Problem¶
Every JWT validation requires the signing key. Fetching the key from the
identity provider's /.well-known/jwks.json endpoint on every request adds
latency and creates a runtime dependency. Caching the key set eliminates this —
but when the cache TTL expires, many concurrent requests simultaneously discover
the cache is stale and all attempt to refresh. Under high concurrency, this
thundering herd can overwhelm the JWKS endpoint or cause mass request failures
during the refresh window.
Solution¶
A mutex-guarded refresh with a time-based re-fetch guard: if another goroutine/thread already refreshed within the last N seconds, the current goroutine uses the already-refreshed cache instead of making another fetch.
func (c *JWKSCache) refresh() error {
c.mu.Lock()
defer c.mu.Unlock()
// If another goroutine already refreshed within guard window, skip
if time.Since(c.fetched) < 30*time.Second {
return nil
}
// Fetch from JWKS endpoint...
c.fetched = time.Now()
return nil
}
This is a simplified singleflight pattern: exactly one goroutine performs the expensive operation; all others observe the result.
Canonical parameters¶
| Parameter | Value | Rationale |
|---|---|---|
| Cache TTL | 1 hour | Cognito rotates keys infrequently; hourly refresh balances freshness vs load |
| Re-fetch guard | 30 seconds | Prevents stampede; 30s is long enough that a JWKS fetch completes |
(Source: sources/2026-06-29-aws-dual-token-authentication-for-nakama-game-servers)
Key properties¶
- Correctness on rotation: if a JWT arrives signed with a
kidnot in the cache, the cache can be proactively refreshed (still protected by the guard). This handles key rotation without waiting for TTL expiry. - Bounded load: at most one JWKS fetch per 30-second window, regardless of request concurrency.
- No external dependency after cache warm: once cached, JWT validation is CPU-only (RSA signature verification). The identity provider can be temporarily unreachable without affecting request processing.
Relationship to other patterns¶
- concepts/thundering-herd — the failure mode this pattern prevents.
- concepts/request-collapsing — the general technique of coalescing duplicate in-flight requests; JWKS cache guard is a specialised instance.
Seen in¶
- sources/2026-06-29-aws-dual-token-authentication-for-nakama-game-servers — Nakama Go hook with 1hr TTL + 30s guard