Skip to content

Tutorial: Set Up Memcache Session Storage

In this tutorial, you will install Memcache, configure the Memcache session storage backend, and verify that sessions work.

Prerequisites

  • A Remix V3 project with session middleware (see the session-middleware tutorial)
  • Memcached installed locally or access to a managed Memcache service

Step 1: Install Memcached

macOS (Homebrew):

bash
brew install memcached
brew services start memcached

Linux (apt):

bash
sudo apt update && sudo apt install memcached
sudo systemctl start memcached

Docker:

bash
docker run -d --name memcached -p 11211:11211 memcached:latest

Verify Memcached is running:

bash
echo "stats" | nc localhost 11211
# STAT pid ...

Step 2: Add Environment Variables

bash
MEMCACHE_URL=localhost:11211
SESSION_SECRET=your-random-secret-here

Step 3: Configure Memcache Session Storage

ts
// app/session.ts
import { createCookie } from 'remix/cookie'
import { createMemcacheSessionStorage } from 'remix/session-storage-memcache'

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,
})

export let sessionStorage = createMemcacheSessionStorage({
  servers: [process.env.MEMCACHE_URL!],
  ttl: 60 * 60 * 24 * 7,    // 7 days, matches cookie maxAge
  prefix: 'myapp:sess:',     // Namespaced key prefix
})

Your router and handlers remain unchanged:

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: Multiple Memcache Servers

For high availability, point to multiple servers. Keys are distributed via consistent hashing:

ts
let sessionStorage = createMemcacheSessionStorage({
  servers: [
    'memcache-1.example.com:11211',
    'memcache-2.example.com:11211',
    'memcache-3.example.com:11211',
  ],
  ttl: 60 * 60 * 24 * 7,
  prefix: 'myapp:sess:',
})

Step 5: Use an Existing Memcache Client

If your application already has a Memcache client, share it:

ts
import Memcached from 'memcached'
import { createMemcacheSessionStorage } from 'remix/session-storage-memcache'

let memcacheClient = new Memcached('localhost:11211')

export let sessionStorage = createMemcacheSessionStorage({
  client: memcacheClient,
  ttl: 60 * 60 * 24 * 7,
  prefix: 'myapp:sess:',
})

Step 6: Test It

  1. Start your server and visit http://localhost:3000
  2. The visit count increments on each page load
  3. Restart your server -- the count continues from where it left off

Summary

StepWhat You Did
Install Memcachedbrew install memcached or Docker
Configure storagecreateMemcacheSessionStorage({ servers, ttl, prefix })
Wire up middlewareSame session() call as any backend

Next Steps

Released under the MIT License.