Back to Blog
guideJanuary 20, 20267 min read

Session Management Best Practices with Redis

Sessions seem simple until they're not. One day you're storing a user ID, the next you're debugging why users are randomly getting logged out, or why someone's session persists after they changed their password.

Redis is perfect for sessions—it's fast, it handles expiration natively, and it scales horizontally. But there are patterns you should follow.

The Basics Done Right

Here's a solid foundation for session management:

import { nanoid } from 'nanoid'

async function createSession(userId) {
  const sessionId = nanoid(32)
  
  await redis.setex(
    `session:${sessionId}`,
    86400, // 24 hours
    JSON.stringify({ userId, createdAt: Date.now() })
  )
  
  return sessionId
}

Sliding Expiration

Active users shouldn't get logged out. Extend the session on each request:

async function touchSession(sessionId) {
  const data = await redis.get(`session:${sessionId}`)
  if (!data) return null
  
  // Extend expiration
  await redis.expire(`session:${sessionId}`, 86400)
  
  return JSON.parse(data)
}

Security tip

Don't extend sessions indefinitely. Set a maximum lifetime (e.g., 30 days) regardless of activity to limit the damage from stolen session tokens.

Limiting Concurrent Sessions

Sometimes you want to limit how many devices a user can be logged in on:

async function createSessionWithLimit(userId, limit = 3) {
  const key = `sessions:${userId}`
  const sessions = await redis.smembers(key)
  
  // Remove oldest if at limit
  if (sessions.length >= limit) {
    const oldest = sessions[0]
    await redis.del(`session:${oldest}`)
    await redis.srem(key, oldest)
  }
  
  const sessionId = await createSession(userId)
  await redis.sadd(key, sessionId)
  
  return sessionId
}

Logout Everywhere

When a user changes their password, invalidate all sessions:

async function logoutEverywhere(userId) {
  const key = `sessions:${userId}`
  const sessions = await redis.smembers(key)
  
  for (const sid of sessions) {
    await redis.del(`session:${sid}`)
  }
  await redis.del(key)
}

Security Checklist

  • ✓ Use secure, httpOnly, sameSite cookies
  • ✓ Regenerate session ID after login
  • ✓ Store minimal data in sessions
  • ✓ Implement "logout everywhere" for password changes
  • ✓ Set absolute maximum session lifetime

Good session management is invisible to users but critical for security. Take the time to get it right.

Ready to build something amazing?

Get your Redis database running in 30 seconds. No credit card required.

Start Free →