Installing and Configuring Redis

July 23, 2026

Redis is an in-memory key-value store used for caching, session storage, and message queuing. On a self-hosted server stack, Redis most commonly backs spam filtering (Rspamd uses it heavily for Bayes classification, rate limiting, and greylisting) and provides caching for web applications like Nextcloud. This post covers installing Redis with the right compile-time flags, writing a production configuration, and verifying the service.

Installing Redis

On Gentoo

Redis benefits from jemalloc as its memory allocator — it reduces fragmentation and improves performance for long-running processes. Set the USE flags before installing:

Create /etc/portage/package.use/redis:

mkdir -p /etc/portage/package.use
cat > /etc/portage/package.use/redis << 'EOF'
dev-db/redis jemalloc ssl -tcmalloc
dev-libs/jemalloc stats
EOF

Install Redis:

emerge -av dev-db/redis

The jemalloc flag links Redis against jemalloc instead of glibc's malloc. The ssl flag enables TLS support if you need encrypted connections later. The -tcmalloc flag explicitly excludes Google's tcmalloc to avoid conflicts with jemalloc.

On Debian

apt install -y redis-server

Debian's Redis package links against jemalloc by default.

On Alpine

apk add redis

Configuring Redis

The default Redis configuration works for development but needs tuning for production use. The main configuration file is at /etc/redis/redis.conf on Debian, /etc/redis.conf on Gentoo, or /etc/redis.conf on Alpine.

Back up the original and replace it:

On Gentoo

cp /etc/redis.conf /etc/redis.conf.orig

On Debian

cp /etc/redis/redis.conf /etc/redis/redis.conf.orig

Write the production configuration. On Gentoo, write to /etc/redis.conf. On Debian, write to /etc/redis/redis.conf:

# Network
bind 127.0.0.1
port 6379
protected-mode yes
tcp-backlog 511
timeout 0
tcp-keepalive 300

# General
daemonize no
supervised auto
pidfile /var/run/redis/redis.pid
loglevel notice
logfile /var/log/redis/redis.log
databases 16

# Snapshotting (persistence)
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir /var/lib/redis

# Memory management
maxmemory 256mb
maxmemory-policy volatile-lru

# Append only mode (disabled - RDB persistence is sufficient)
appendonly no

# Slow log
slowlog-log-slower-than 10000
slowlog-max-len 128

# Security
# No password required for localhost-only access

Configuration Decisions

bind 127.0.0.1 — Redis only listens on localhost. This is the most important security setting. Redis has no authentication by default, and binding to all interfaces would expose your data to the network. Even with a password set, Redis shouldn't be exposed to untrusted networks.

protected-mode yes — a safety net that rejects connections from external IPs if no password is set and Redis is bound to all interfaces. With bind 127.0.0.1 this is redundant, but it's a useful failsafe.

maxmemory 256mb — caps Redis memory usage at 256MB. Without a limit, Redis will consume all available memory and trigger the OOM killer. 256MB is sufficient for Rspamd's statistical data and most caching workloads. Adjust based on your server's RAM and workload.

maxmemory-policy volatile-lru — when Redis hits the memory limit, it evicts keys with an expiration set, starting with the least recently used. This is the right policy for caching and Rspamd: cached data has TTLs and can be regenerated, so evicting stale entries is safe. Other options:

Policy Behavior
volatile-lru Evict keys with TTL, least recently used first
allkeys-lru Evict any key, least recently used first
volatile-ttl Evict keys with TTL, shortest TTL first
noeviction Return errors when memory is full

Snapshotting (save directives) — Redis periodically writes its dataset to disk as an RDB file. The three save lines mean:

  • Save if at least 1 key changed in the last 900 seconds (15 minutes)
  • Save if at least 10 keys changed in the last 300 seconds (5 minutes)
  • Save if at least 10000 keys changed in the last 60 seconds

This provides persistence without the overhead of append-only mode. If Redis crashes, you lose at most the last few minutes of writes — acceptable for caching and spam filtering data.

appendonly no — the append-only file (AOF) logs every write operation for point-in-time recovery. For a caching use case, RDB snapshotting is sufficient and has lower I/O overhead. Enable AOF if you're using Redis as a primary data store.

daemonize no and supervised auto — with OpenRC or systemd managing the process, Redis should not daemonize itself. The supervised auto setting lets Redis detect whether it's running under systemd or another init system and signals readiness appropriately.

Setting Up the Data Directory

Ensure the data directory exists with the correct ownership:

mkdir -p /var/lib/redis
chown redis:redis /var/lib/redis
chmod 750 /var/lib/redis

On Gentoo, also ensure the log directory exists:

mkdir -p /var/log/redis
chown redis:redis /var/log/redis

And the PID directory:

mkdir -p /var/run/redis
chown redis:redis /var/run/redis

Starting and Enabling the Service

On Gentoo

rc-update add redis default
rc-service redis start

On Debian

systemctl enable redis-server
systemctl start redis-server

Note: Debian names the service redis-server, not redis.

On Alpine

rc-update add redis default
rc-service redis start

Verifying the Installation

Check the Service Is Running

ss -lnt sport = :6379

Expected output:

State    Recv-Q   Send-Q   Local Address:Port   Peer Address:Port
LISTEN   0        511      127.0.0.1:6379        0.0.0.0:*

Test with redis-cli

The PING command is the standard Redis health check:

redis-cli PING

Expected response:

PONG

Check Memory Configuration

redis-cli INFO memory | grep -E "maxmemory|used_memory_human|mem_allocator"

You should see:

used_memory_human:1.00M
maxmemory:268435456
maxmemory_human:256.00M
mem_allocator:jemalloc-5.3.0

The mem_allocator line confirms Redis is using jemalloc. If it shows libc instead, the jemalloc USE flag wasn't applied correctly on Gentoo.

Check Persistence Configuration

redis-cli CONFIG GET save

Expected output:

1) "save"
2) "900 1 300 10 60 10000"

Monitor Redis in Real Time

For debugging, redis-cli MONITOR streams every command Redis receives:

redis-cli MONITOR

Press Ctrl+C to exit. This is useful for verifying that Rspamd or other applications are actually writing to Redis.

Tuning for Specific Workloads

Rspamd (Spam Filtering)

Rspamd uses Redis for Bayes spam classification, rate limiting, greylisting data, and fuzzy hash storage. The default 256MB is adequate for a single-domain mail server. For high-volume servers processing thousands of messages per day, increase to 512MB or 1GB:

maxmemory 512mb

Rspamd sets TTLs on most of its Redis keys, so volatile-lru is the correct eviction policy. Bayes tokens that haven't been seen recently are the first to be evicted, which is the desired behavior.

Nextcloud (Session Cache)

Nextcloud can use Redis for file locking and session storage. The memory footprint is small — typically under 50MB even with many active users. The default configuration works without changes.

PHP Session Storage

Redis can replace file-based PHP sessions for applications behind a load balancer. Add to your PHP configuration:

session.save_handler = redis
session.save_path = "tcp://127.0.0.1:6379"

Sessions are automatically expired by PHP's session.gc_maxlifetime setting. Redis's volatile-lru eviction handles cleanup if sessions accumulate faster than they expire.

Monitoring Redis

Built-in Statistics

Redis tracks detailed statistics about memory, clients, and operations:

redis-cli INFO

Key sections to review:

# Memory
redis-cli INFO memory

# Connected clients
redis-cli INFO clients

# Operations per second
redis-cli INFO stats | grep instantaneous_ops_per_sec

# Keyspace (database sizes)
redis-cli INFO keyspace

Slow Query Log

The slowlog captures queries that exceed the configured threshold (10ms by default):

redis-cli SLOWLOG GET 10

This shows the 10 most recent slow queries with execution time. If you see frequent slow queries, the server may need more memory or the workload may need optimization.

Optional: Password Authentication

If Redis needs to accept connections from other hosts (e.g., a separate application server), add a password and adjust the bind address:

bind 127.0.0.1 192.168.1.10
requirepass your-redis-password-here

Clients then authenticate with:

redis-cli -h 192.168.1.10 -a your-redis-password-here PING

For localhost-only setups, a password is unnecessary — the network binding is the access control mechanism.

Summary

After completing these steps:

  • Redis is installed with jemalloc for efficient memory management
  • The server listens only on localhost (127.0.0.1:6379)
  • Memory is capped at 256MB with LRU eviction for expired keys
  • RDB snapshotting provides persistence without AOF overhead
  • The service starts at boot and is verified with PING

Redis is now ready to back Rspamd's spam filtering and serve as a cache for web applications.