Back to all posts
🛡️Authentication6 min read

Token Refresh Patterns That Actually Scale

How to implement refresh tokens without creating a thundering herd problem or security vulnerabilities.

The Refresh Token Dilemma

Short-lived access tokens are a security best practice. But they create a UX problem: users get logged out too frequently.

Refresh tokens solve this, but they introduce their own complexity. Let me walk you through the patterns that actually work at scale.

Pattern 1: Sliding Window Expiration

Instead of fixed expiration times, extend the refresh token's lifetime with each use. This keeps active users logged in while naturally expiring inactive sessions.

const refreshConfig = {
  initialTTL: "7d",
  maxTTL: "30d",
  slidingWindow: true
};

Pattern 2: Token Rotation

Issue a new refresh token with every access token refresh. This limits the window of opportunity if a token is compromised.

Critical: You must handle race conditions. If two requests try to refresh simultaneously, one will get an invalid token error.

Pattern 3: Token Families

Group related tokens into families. If a refresh token is reused (indicating potential theft), invalidate the entire family.

This is how Auth0 and other major providers detect token theft.

Avoiding the Thundering Herd

When tokens expire, don't let all clients refresh simultaneously. Add jitter to your token lifetimes:

const jitter = Math.random() * 300; // 0-5 minutes
const expiresIn = baseExpiry + jitter;

The Redis Approach

Store refresh tokens in Redis with automatic expiration. This gives you:

  • Fast lookups
  • Automatic cleanup
  • Easy revocation
  • Cross-service token validation

At scale, this pattern handles millions of active sessions without breaking a sweat.

Written by Rashad Jamara

Continue Reading

Ready to fix your auth?

Let's discuss how to apply these patterns to your specific stack and requirements.

Book a 20-minute call →