Valkey on a VPS: The Open-Source Redis Alternative for Caching, Queues, and Session Storage

Valkey on a VPS: The Open-Source Redis Alternative for Caching, Queues, and Session Storage

Valkey is a fully open-source, Redis-compatible in-memory data store forked from Redis 7.2 after Redis changed to a proprietary SSPL license in 2024. Valkey is maintained by the Linux Foundation with major contributors from AWS, Google, Oracle, and Ericsson. It is API-compatible with Redis — the same commands, same clients, same configuration — with a BSD open-source license that will remain free to use and deploy indefinitely.

Why Valkey Instead of Redis

  • License: Redis is now SSPL (non-OSI-approved, commercial restrictions). Valkey is BSD licensed — use freely in any context.
  • API compatibility: Valkey is a drop-in replacement — same commands, same clients (ioredis, redis-py, jedis), same config format.
  • Active development: Linux Foundation backing, rapid release cadence, I/O threading improvements
  • Zero migration cost: Change the hostname in your Redis connection string — nothing else changes

Step 1: Docker Compose Setup

<code">mkdir -p /opt/valkey && cd /opt/valkey
nano docker-compose.yml
<code">version: '3.8'

services:
  valkey:
    image: valkey/valkey:8-alpine
    container_name: valkey
    restart: always
    ports:
      - "127.0.0.1:6379:6379"
    command: valkey-server /usr/local/etc/valkey/valkey.conf
    volumes:
      - ./valkey.conf:/usr/local/etc/valkey/valkey.conf:ro
      - valkey_data:/data

volumes:
  valkey_data:
<code">nano valkey.conf
<code"># Authentication
requirepass YourStrongValkeyPassword!

# Persistence — choose based on use case:
# Option A: RDB snapshots (good for cache + occasional persistence)
save 900 1        # Save if at least 1 key changed in 900 seconds
save 300 10       # Save if at least 10 keys changed in 300 seconds
save 60 10000     # Save if at least 10000 keys changed in 60 seconds

# Option B: AOF (append-only file — better durability for queues/sessions)
# appendonly yes
# appendfsync everysec   # Flush to disk every second

# Option C: No persistence (pure cache — data lost on restart)
# save ""
# appendonly no

# Memory limit and eviction (for caching use case)
maxmemory 512mb
maxmemory-policy allkeys-lru   # Evict least recently used keys when full

# Bind to localhost only (Nginx/app handles external access)
bind 127.0.0.1

# Performance
tcp-keepalive 300
tcp-backlog 511

# Logging
loglevel notice
logfile /data/valkey.log
<code">docker compose up -d
docker compose logs -f valkey

# Test connection
docker exec valkey valkey-cli -a YourStrongValkeyPassword! PING
# Expected: PONG

Step 2: Bare-Metal Install (Alternative)

<code"># Install from package manager
sudo apt install -y valkey-server

# Or compile from source:
git clone https://github.com/valkey-io/valkey.git /tmp/valkey
cd /tmp/valkey && make -j$(nproc)
sudo make install   # Installs valkey-server and valkey-cli

sudo systemctl enable valkey-server
sudo systemctl start valkey-server

Step 3: Common Use Cases

Application Caching (Python/Flask)

<code">pip install valkey redis   # Valkey uses the redis client
<code">import redis
import json
from functools import wraps

# Connect — identical to Redis connection
r = redis.Redis(
    host='localhost',
    port=6379,
    password='YourStrongValkeyPassword!',
    decode_responses=True,
)

def cache(ttl: int = 300):
    """Cache decorator — caches function result in Valkey for TTL seconds."""
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            key = f"cache:{func.__name__}:{args}:{kwargs}"
            cached = r.get(key)
            if cached:
                return json.loads(cached)
            result = func(*args, **kwargs)
            r.setex(key, ttl, json.dumps(result))
            return result
        return wrapper
    return decorator

@cache(ttl=300)
def get_user_profile(user_id: int) -> dict:
    """Expensive database query — cached for 5 minutes."""
    # ... database query here
    return {"id": user_id, "name": "Alice"}

Session Storage (Node.js/Express)

<code">npm install ioredis connect-redis express-session
<code">import session from 'express-session';
import { createClient } from 'redis';   // ioredis also works
import RedisStore from 'connect-redis';

// Connect to Valkey — same API as Redis
const client = createClient({
    socket: { host: 'localhost', port: 6379 },
    password: 'YourStrongValkeyPassword!',
});
await client.connect();

app.use(session({
    store: new RedisStore({ client }),   // Uses Valkey transparently
    secret: process.env.SESSION_SECRET,
    resave: false,
    saveUninitialized: false,
    cookie: {
        secure: true,   // HTTPS only
        httpOnly: true,
        maxAge: 7 * 24 * 60 * 60 * 1000,  // 7 days
    },
}));

Job Queue (BullMQ)

<code">npm install bullmq ioredis
<code">import { Queue, Worker } from 'bullmq';
import IORedis from 'ioredis';

const connection = new IORedis({
    host: 'localhost',
    port: 6379,
    password: 'YourStrongValkeyPassword!',
    maxRetriesPerRequest: null,  // Required for BullMQ
});

// Producer: add jobs
const emailQueue = new Queue('email', { connection });
await emailQueue.add('send-welcome', {
    to: 'user@example.com',
    template: 'welcome',
});

// Consumer: process jobs
const worker = new Worker('email', async (job) => {
    const { to, template } = job.data;
    await sendEmail(to, template);
    console.log(`Sent ${template} email to ${to}`);
}, { connection, concurrency: 5 });

Step 4: Monitor Valkey

<code"># Real-time stats
docker exec valkey valkey-cli -a YourStrongValkeyPassword! INFO

# Key metrics from INFO:
# connected_clients: active connections
# used_memory_human: RAM in use
# hit_rate: cache hit percentage (keyspace_hits / (hits + misses))
# evicted_keys: keys evicted due to maxmemory policy

# Monitor commands in real-time (debug use)
docker exec valkey valkey-cli -a YourStrongValkeyPassword! MONITOR

# Slow query log (queries over 10ms)
docker exec valkey valkey-cli -a YourStrongValkeyPassword! SLOWLOG GET 10

# Key count by pattern
docker exec valkey valkey-cli -a YourStrongValkeyPassword! INFO keyspace

Step 5: Migrate from Redis to Valkey

<code"># For Docker users — just change the image:
# FROM: image: redis:7-alpine
# TO:   image: valkey/valkey:8-alpine

# For bare-metal:
sudo systemctl stop redis-server
sudo apt remove redis-server
sudo apt install valkey-server

# Copy existing redis.conf settings to valkey.conf
# Valkey reads the same configuration format

# Dump Redis data and restore to Valkey:
redis-cli -a OLD_PASS --rdb /tmp/dump.rdb BGSAVE
# Copy dump.rdb to new Valkey data directory
# Valkey reads Redis RDB dump format natively

Getting Started

Valkey is a drop-in Redis replacement — same resource footprint (50–200 MB RAM depending on data), same commands, same client libraries. Deploy on any Ubuntu VPS at VPS.DO via Docker or apt package. For new projects, use Valkey from the start; for existing Redis deployments, migration is as simple as changing the Docker image and potentially the package name.

Conclusion

Valkey provides Redis-compatible in-memory data storage under a perpetual BSD license — eliminating concerns about Redis’s SSPL licensing for commercial and self-hosted deployments. The API is identical, client libraries work without changes, and data formats are compatible. For caching, session storage, pub/sub messaging, and job queues, Valkey is the recommended open-source choice for new VPS deployments and the natural migration path for existing Redis users.

Fast • Reliable • Affordable VPS - DO It Now!

Get top VPS hosting with VPS.DO’s fast, low-cost plans. Try risk-free with our 7-day no-questions-asked refund and start today!