Tutorial: Set Up Redis Session Storage
In this tutorial, you will install Redis, configure the Redis session storage backend, and verify that sessions work across server restarts.
Prerequisites
- A Remix V3 project with session middleware (see the session-middleware tutorial)
- Redis installed locally or access to a managed Redis service
Step 1: Install Redis
macOS (Homebrew):
bash
brew install redis
brew services start redisLinux (apt):
bash
sudo apt update && sudo apt install redis-server
sudo systemctl start redisDocker:
bash
docker run -d --name redis -p 6379:6379 redis:latestVerify Redis is running:
bash
redis-cli ping
# PONGStep 2: Add Environment Variables
Add the Redis URL to your .env file:
bash
REDIS_URL=redis://localhost:6379
SESSION_SECRET=your-random-secret-hereStep 3: Configure Redis Session Storage
Replace your current session storage with the Redis backend:
ts
// app/session.ts
import { createCookie } from 'remix/cookie'
import { createRedisSessionStorage } from 'remix/session-storage-redis'
export let sessionCookie = createCookie('__session', {
httpOnly: true,
secure: process.env.NODE_ENV === 'production',
sameSite: 'Lax',
secrets: [process.env.SESSION_SECRET!],
maxAge: 60 * 60 * 24 * 7, // 1 week
})
export let sessionStorage = createRedisSessionStorage({
url: process.env.REDIS_URL!,
ttl: 60 * 60 * 24 * 7, // 7 days, matches cookie maxAge
prefix: 'myapp:session:', // Namespaced key prefix
})Your router setup and handlers do not change:
ts
// app/server.ts
import { createRouter } from 'remix/fetch-router'
import { session } from 'remix/session-middleware'
import { Session } from 'remix/session'
import { sessionCookie, sessionStorage } from './session.ts'
let router = createRouter({
middleware: [
session(sessionCookie, sessionStorage),
],
})
router.get(homeRoute, async ({ context }) => {
let s = context.get(Session)
let visits = (s.get('visits') ?? 0) + 1
s.set('visits', visits)
return new Response(`Visit #${visits}`)
})Step 4: Use an Existing Redis Client
If your application already uses Redis for caching or other purposes, share the client:
ts
import { createClient } from 'redis'
import { createRedisSessionStorage } from 'remix/session-storage-redis'
let redisClient = createClient({ url: process.env.REDIS_URL! })
await redisClient.connect()
export let sessionStorage = createRedisSessionStorage({
client: redisClient,
ttl: 60 * 60 * 24 * 7,
prefix: 'myapp:session:',
})Step 5: Test It
- Start your server and visit
http://localhost:3000 - The visit count should increment on each page load
- Restart your server (Ctrl+C and start again)
- Visit the page again -- the count continues from where it left off (because the session is in Redis, not in process memory)
Inspect the session in Redis:
bash
redis-cli keys "myapp:session:*"
# 1) "myapp:session:a1b2c3d4..."
redis-cli get "myapp:session:a1b2c3d4..."
# {"visits":5}
redis-cli ttl "myapp:session:a1b2c3d4..."
# (integer) 604793Summary
| Step | What You Did |
|---|---|
| Install Redis | brew install redis or Docker |
| Configure storage | createRedisSessionStorage({ url, ttl, prefix }) |
| Wire up middleware | session(sessionCookie, sessionStorage) -- same as any backend |
| Test | Sessions persist across server restarts |
Next Steps
- Session Overview -- Compare all storage backends.
- API Reference -- Full documentation of
createRedisSessionStorageoptions.