Redis on FreeBSD: In-Memory Data Store Review
Redis is an in-memory data structure store that operates as a database, cache, message broker, and streaming engine. It stores all data in RAM, which makes it orders of magnitude faster than disk-based databases for the operations it supports. Redis processes over a million simple operations per second on commodity hardware, and its data structure primitives -- strings, hashes, lists, sets, sorted sets, streams, and bitmaps -- make it far more versatile than a simple key-value cache. On FreeBSD, Redis runs as a single-threaded event loop using kqueue for I/O multiplexing, and it integrates well with the system's process supervision, memory management, and ZFS-based storage for persistence snapshots. This review covers Redis's architecture, FreeBSD-specific installation and tuning, persistence strategies, Sentinel for high availability, Cluster mode for horizontal scaling, and how it compares with Memcached and the Valkey fork.
What Redis Does
Redis operates entirely in memory. Every read and write touches RAM, not disk. Persistence to disk is handled asynchronously through snapshots or append-only logs, but the working dataset always lives in memory. This design gives Redis sub-millisecond latency for most operations.
Core capabilities:
- Data structures -- not just key-value. Redis supports strings, hashes (field-value maps), lists (linked lists), sets (unordered unique collections), sorted sets (scored members with range queries), streams (append-only log with consumer groups), bitmaps, HyperLogLog, and geospatial indexes.
- Atomic operations -- all Redis commands are atomic.
INCR,LPUSH,SADD, and others execute without race conditions, even under high concurrency. - Pub/Sub -- publish/subscribe messaging for real-time notifications and event distribution.
- Lua scripting -- execute Lua scripts atomically on the server side, reducing round trips for complex operations.
- Transactions --
MULTI/EXECblocks execute a sequence of commands atomically (though not with rollback like SQL transactions). - TTL and expiration -- keys can have time-to-live values. Expired keys are automatically removed, making Redis a natural fit for caching and session storage.
- Streams -- an append-only data structure with consumer groups, suitable for event sourcing, message queues, and log aggregation.
Redis is not a replacement for a relational database. It does not support SQL, joins, or complex queries. It complements a primary database by handling the workloads where speed matters most: caching, session management, rate limiting, leaderboards, real-time analytics, and message passing.
Installation on FreeBSD
Redis is available as a binary package and through the ports tree.
Binary Package Installation
shpkg install redis
This installs Redis server, CLI, and related tools. The binary is at /usr/local/bin/redis-server, and the configuration file is at /usr/local/etc/redis.conf.
Enable Redis at boot:
shsysrc redis_enable="YES"
Start Redis:
shservice redis start
Verify Installation
shredis-cli ping
If Redis is running, this returns PONG.
shredis-cli info server
This shows the Redis version, build information, and server uptime.
Ports Installation
For custom build options:
shcd /usr/ports/databases/redis make config make install clean
Configuration on FreeBSD
The default configuration file at /usr/local/etc/redis.conf is extensively commented and works for development. Production deployments need specific adjustments.
Production Configuration
sh# Bind to localhost only (default). For remote access, bind to specific IPs. bind 127.0.0.1 ::1 # Require authentication requirepass your_strong_password_here # Memory limit -- Redis will evict keys when this is reached maxmemory 2gb maxmemory-policy allkeys-lru # Persistence save 900 1 save 300 10 save 60 10000 appendonly yes appendfsync everysec # Logging logfile /var/log/redis/redis.log loglevel notice # Connections maxclients 10000 tcp-backlog 511 timeout 300 # Disable dangerous commands in production rename-command FLUSHDB "" rename-command FLUSHALL "" rename-command DEBUG "" rename-command CONFIG "CONFIG_b4d8f7a2"
Create the log directory:
shmkdir -p /var/log/redis chown redis:redis /var/log/redis
Memory Policy
The maxmemory-policy setting determines what happens when Redis reaches its memory limit:
allkeys-lru-- evict least recently used keys from all keys. Best for caching workloads.volatile-lru-- evict LRU keys only from keys with an expiration set. Persistent keys are never evicted.allkeys-lfu-- evict least frequently used keys. Better than LRU when access patterns vary.noeviction-- return errors on writes when memory is full. Use this when Redis is a primary data store, not a cache.
For caching, allkeys-lru or allkeys-lfu are the standard choices. For session storage where data loss is unacceptable, use noeviction and size your memory limit to accommodate peak session counts.
Persistence
Redis offers two persistence mechanisms that can be used independently or together.
RDB Snapshots
RDB creates point-in-time snapshots of the dataset at configured intervals:
shsave 900 1 # Snapshot if at least 1 key changed in 900 seconds save 300 10 # Snapshot if at least 10 keys changed in 300 seconds save 60 10000 # Snapshot if at least 10000 keys changed in 60 seconds
Redis forks a child process to write the snapshot, using copy-on-write to avoid blocking the main process. On FreeBSD with ZFS, this fork is efficient because ZFS's copy-on-write semantics align well with Redis's forking model.
RDB files are compact and fast to load on restart. The downside is potential data loss -- if Redis crashes between snapshots, changes since the last snapshot are lost.
AOF (Append Only File)
AOF logs every write operation to a file:
shappendonly yes appendfsync everysec
The appendfsync options are:
always-- fsync after every write. Safest but slowest. Expect 10x throughput reduction.everysec-- fsync once per second. At most one second of data loss on crash. Recommended for most deployments.no-- let the OS decide when to flush. Fastest but riskiest.
AOF files grow over time. Redis rewrites them periodically to compact the log:
shauto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb
Recommended Strategy
Use both RDB and AOF together. AOF provides durability (at most one second of data loss with everysec), and RDB provides fast full backups that are easy to ship offsite:
shredis-cli BGSAVE cp /var/db/redis/dump.rdb /backup/redis/dump-$(date +%Y%m%d).rdb
Redis Sentinel
Sentinel provides automatic failover for Redis replication setups. It monitors master and replica nodes, detects failures, and promotes a replica to master when the current master is unreachable.
Architecture
A Sentinel deployment requires:
- One Redis master
- One or more Redis replicas
- At least three Sentinel processes (for quorum-based leader election)
Sentinel Configuration on FreeBSD
Install Sentinel (included with the Redis package):
shcat > /usr/local/etc/redis-sentinel.conf << 'EOF' port 26379 daemonize yes logfile /var/log/redis/sentinel.log pidfile /var/run/redis/sentinel.pid sentinel monitor mymaster 192.168.1.10 6379 2 sentinel auth-pass mymaster your_strong_password_here sentinel down-after-milliseconds mymaster 5000 sentinel failover-timeout mymaster 60000 sentinel parallel-syncs mymaster 1 EOF
Enable and start Sentinel:
shsysrc redis_sentinel_enable="YES" service redis-sentinel start
The sentinel monitor line tells Sentinel to watch the master at 192.168.1.10:6379, and the quorum of 2 means two Sentinel instances must agree that the master is down before failover begins.
Verifying Sentinel
shredis-cli -p 26379 sentinel master mymaster redis-cli -p 26379 sentinel replicas mymaster
Redis Cluster
Redis Cluster provides horizontal scaling by sharding data across multiple Redis nodes. Each node owns a subset of the 16,384 hash slots that Redis uses to partition keys.
Cluster Setup
A minimum Redis Cluster requires six nodes: three masters and three replicas. On FreeBSD, you can run multiple instances on different ports for testing:
shfor port in 7000 7001 7002 7003 7004 7005; do mkdir -p /var/db/redis-cluster/${port} cat > /usr/local/etc/redis-cluster-${port}.conf << EOF port ${port} cluster-enabled yes cluster-config-file /var/db/redis-cluster/${port}/nodes.conf cluster-node-timeout 5000 appendonly yes dir /var/db/redis-cluster/${port} EOF redis-server /usr/local/etc/redis-cluster-${port}.conf --daemonize yes done
Create the cluster:
shredis-cli --cluster create 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 \ 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 --cluster-replicas 1
Cluster Limitations
- Keys in different hash slots cannot be used in multi-key operations unless they share the same hash tag (e.g.,
{user:1000}:profileand{user:1000}:sessions). - Lua scripts must use keys that map to the same slot.
- The cluster protocol adds complexity to client libraries. Not all Redis clients support Cluster mode.
Use Cases on FreeBSD
Session Storage
shredis-cli SET session:abc123 '{"user_id":42,"role":"admin"}' EX 3600 redis-cli GET session:abc123
Sessions with a one-hour TTL. Expired sessions are automatically removed.
Rate Limiting
shredis-cli MULTI redis-cli INCR "ratelimit:192.168.1.50:$(date +%s)" redis-cli EXPIRE "ratelimit:192.168.1.50:$(date +%s)" 60 redis-cli EXEC
Caching Database Queries
Store expensive query results with a TTL:
shredis-cli SETEX "query:users:active:count" 300 "4821"
The value expires after 300 seconds, forcing a fresh query on the next cache miss.
Message Queue with Streams
shredis-cli XADD jobs '*' type email to user@example.com subject "Welcome" redis-cli XREAD COUNT 1 BLOCK 5000 STREAMS jobs 0
Streams provide persistent, replayable message queues with consumer group support, similar to Kafka for smaller-scale deployments.
FreeBSD-Specific Tuning
Memory Overcommit
Redis uses fork() for background persistence. On FreeBSD, ensure sufficient swap or memory is available for the fork. Unlike Linux, FreeBSD does not have vm.overcommit_memory. Instead, ensure your system has enough swap:
shswapinfo
A general rule: swap should be at least equal to the Redis maxmemory setting to guarantee successful forking.
Transparent Huge Pages
FreeBSD does not use transparent huge pages by default, so this common Linux tuning issue does not apply. One less thing to worry about.
Network Tuning
For high-connection-count deployments:
shsysctl kern.ipc.somaxconn=4096 sysctl net.inet.tcp.msl=3000
File Descriptor Limits
Redis with many concurrent connections needs high file descriptor limits:
shsysctl kern.maxfiles=100000 sysctl kern.maxfilesperproc=50000
Redis vs Memcached
Memcached is the original in-memory caching system. The comparison with Redis is straightforward:
Choose Redis when:
- You need data structures beyond simple key-value (hashes, lists, sets, sorted sets, streams).
- You need persistence. Memcached has no built-in persistence.
- You need pub/sub or message queue functionality.
- You need atomic operations on complex data types.
- You need replication and high availability (Sentinel or Cluster).
Choose Memcached when:
- You need a simple, volatile cache with no persistence requirements.
- You want multi-threaded performance on a single node. Memcached uses threads; Redis is primarily single-threaded (I/O threading was added in Redis 6 but the command processing remains single-threaded).
- Your caching needs are limited to
SET/GETwith TTL and nothing more. - You want lower memory overhead per key for simple string caching.
In practice, Redis has largely supplanted Memcached. The additional capabilities come with minimal performance overhead for simple operations, and the persistence and replication features provide operational safety that Memcached lacks.
Redis vs Valkey
Valkey is a Redis fork created in 2024 after Redis Ltd changed the Redis license from BSD to a dual license (RSALv2/SSPLv1). Valkey is maintained by the Linux Foundation and preserves the BSD-like open-source license.
On FreeBSD, both Redis and Valkey are available:
shpkg search valkey pkg search redis
The technical differences are minimal as of 2026 -- Valkey tracks Redis's feature set closely. The choice is primarily about licensing philosophy. If you want guaranteed open-source licensing, Valkey is the safer long-term bet. If you are using Redis for a self-hosted deployment (not offering it as a service), the Redis license does not restrict you.
Performance on FreeBSD
Benchmark Redis on your FreeBSD system:
shredis-benchmark -q -n 100000 -c 50
Typical results on a 4-core FreeBSD 14.2 system with DDR4 memory:
SET: 150,000+ operations/secondGET: 170,000+ operations/secondINCR: 160,000+ operations/secondLPUSH: 140,000+ operations/secondSADD: 150,000+ operations/second
These numbers are for a single Redis instance. Redis Cluster scales horizontally by adding more nodes.
Monitoring
Built-in Monitoring
shredis-cli INFO memory redis-cli INFO stats redis-cli INFO replication redis-cli INFO clients
Key Metrics to Watch
used_memoryvsmaxmemory-- how close you are to the eviction threshold.evicted_keys-- keys removed due to memory pressure. High numbers mean your dataset exceeds memory.connected_clients-- current client connections.instantaneous_ops_per_sec-- current throughput.rdb_last_bgsave_status-- whether the last background save succeeded.aof_last_bgrewrite_status-- whether the last AOF rewrite succeeded.
Prometheus Integration
shpkg install redis_exporter sysrc redis_exporter_enable="YES" service redis_exporter start
The exporter exposes metrics at http://localhost:9121/metrics for Prometheus scraping.
Verdict
Redis is the standard in-memory data store for FreeBSD deployments that need sub-millisecond latency, rich data structures, and operational flexibility. Its persistence options make it more than a cache -- it can serve as a primary data store for appropriate workloads. Sentinel provides automatic failover for high availability, and Cluster mode enables horizontal scaling when a single node's memory is insufficient.
On FreeBSD, Redis benefits from kqueue-based I/O, the absence of transparent huge pages issues, and ZFS integration for snapshot-based backups of RDB files. It is stable, well-packaged, and runs efficiently in jails.
For simple volatile caching with no persistence needs, Memcached is lighter. For everything else in the in-memory data store category, Redis is the default choice.
Frequently Asked Questions
Does Redis work in FreeBSD jails?
Yes. Redis runs in jails without modification. Bind it to the jail's IP address in redis.conf and ensure the jail has sufficient memory allocated.
How much memory does Redis need?
Redis uses approximately 1.5x the raw data size due to internal overhead (pointers, metadata, allocator fragmentation). A dataset with 1 GB of raw data typically consumes 1.5-2 GB of Redis memory. Use redis-cli INFO memory to check actual usage.
Can Redis replace my database?
For specific workloads (session storage, caching, leaderboards, real-time counters), yes. For general-purpose relational data with complex queries, no. Redis complements a primary database -- it does not replace one.
Should I use Redis Sentinel or Redis Cluster?
Sentinel provides high availability for a single dataset that fits in one node's memory. Cluster provides high availability plus horizontal scaling across multiple nodes. If your dataset fits in a single node (up to the server's RAM), use Sentinel. If you need to shard across nodes, use Cluster.
How do I secure Redis on FreeBSD?
Bind to 127.0.0.1 or a private network address. Set requirepass with a strong password. Rename or disable dangerous commands (FLUSHALL, CONFIG, DEBUG). Use TLS if connections traverse untrusted networks (Redis 6+ supports native TLS). Run Redis in a jail for additional isolation.
What is the maximum dataset size?
Redis is limited by available RAM. A single instance can handle datasets up to the server's physical memory minus OS overhead. For larger datasets, use Redis Cluster to shard across multiple nodes, or consider a disk-based database.