Skip to content

Memory & Disk Eviction

Redlite supports automatic eviction of keys when memory or disk limits are exceeded. This allows you to use Redlite as a cache with bounded resource usage.

FeatureMemory (maxmemory)Disk (maxdisk)
LimitRAM usage estimateSQLite file size
PolicyConfigurable (LRU, LFU, random, etc.)Fixed: oldest-first
ScopeCurrent database onlyAll databases (0-15)
Config--eviction-policyN/A

Both use vacuum-first strategy: expired keys are deleted before evicting valid keys.

Terminal window
# Limit to 100MB memory with LRU eviction
./redlite --max-memory 104857600 --eviction-policy allkeys-lru
# Limit to 500MB disk
./redlite --max-disk 524288000
# Both limits
./redlite --max-memory 104857600 --max-disk 524288000 --eviction-policy allkeys-lfu

Memory eviction removes keys when the estimated memory usage exceeds maxmemory. This is useful for caching scenarios where you want to limit RAM usage.

Key behavior:

  • Uses configurable policies (LRU, LFU, random, TTL-based)
  • Only evicts from the current selected database (set via SELECT)

Command line:

Terminal window
./redlite --max-memory 104857600 --eviction-policy allkeys-lru

Runtime (via CONFIG):

Terminal window
CONFIG SET maxmemory 104857600 # 100MB limit
CONFIG SET maxmemory-policy allkeys-lru
CONFIG GET maxmemory
CONFIG GET maxmemory-policy

Embedded API:

use redlite::{Db, EvictionPolicy};
let db = Db::open_memory()?;
db.set_max_memory(100 * 1024 * 1024); // 100MB
db.set_eviction_policy(EvictionPolicy::AllKeysLRU);
PolicyDescription
noevictionNever evict keys. Returns error when memory limit exceeded. (Default)
allkeys-lruEvict least recently used keys from all keys
allkeys-lfuEvict least frequently used keys from all keys
allkeys-randomEvict random keys from all keys
volatile-lruEvict least recently used keys among keys with TTL
volatile-lfuEvict least frequently used keys among keys with TTL
volatile-ttlEvict keys with shortest remaining TTL
volatile-randomEvict random keys among keys with TTL

Redlite tracks access patterns for LRU and LFU eviction:

  • LRU (Least Recently Used): Tracks when each key was last accessed. Keys that haven’t been read or written recently are evicted first.
  • LFU (Least Frequently Used): Tracks how often each key is accessed. Keys with fewer accesses are evicted first.

Access tracking uses an in-memory HashMap for fast updates, with periodic persistence to SQLite columns for durability.

Like Redis, Redlite uses sampling to find eviction candidates rather than scanning all keys. When eviction is needed:

  1. Sample 5 random keys
  2. Pick the “worst” key among the samples (oldest access for LRU, lowest count for LFU)
  3. Evict that key

This provides O(1) eviction performance even with millions of keys, at the cost of approximate rather than perfect LRU/LFU behavior.

Volatile policies only consider keys that have a TTL set:

Terminal window
# Only evict keys with expiration
CONFIG SET maxmemory-policy volatile-lru

If no keys have TTL and the volatile policy can’t find candidates, Redlite will return an error on writes when memory is full.

Disk eviction removes keys when the SQLite database file exceeds maxdisk. Unlike memory eviction, disk eviction:

  • Uses oldest-first ordering (by creation time) - no configurable policy
  • Operates across all databases (0-15), not just the current one

Command line:

Terminal window
./redlite --max-disk 524288000 # 500MB limit

Runtime:

Terminal window
CONFIG SET maxdisk 524288000
CONFIG GET maxdisk

Embedded API:

let db = Db::open("data.db")?;
db.set_max_disk(500 * 1024 * 1024); // 500MB
  • Eviction checks run on write operations (SET, HSET, LPUSH, etc.)
  • Checks are throttled to once per second to minimize overhead
  • Oldest keys (by creation time) are evicted first
  • Disk size is calculated from SQLite page count

When eviction is triggered, Redlite first attempts to reclaim space by deleting expired keys:

  1. Phase 1: Vacuum - Delete all expired keys (keys with past TTL)
  2. Phase 2: Evict - If still over limit, evict valid keys based on policy

This ensures expired keys (which would be deleted on access anyway) are cleaned up before evicting valid user data.

For LRU/LFU policies, you can tune access tracking behavior:

Terminal window
# Enable/disable access tracking persistence to disk
CONFIG SET persist-access-tracking on # Persist to SQLite (default for :memory:)
CONFIG SET persist-access-tracking off # In-memory only (default for file DBs)
CONFIG GET persist-access-tracking

When disabled, access tracking still works in-memory but isn’t persisted across restarts.

Terminal window
# How often to flush access tracking to disk (milliseconds)
CONFIG SET access-flush-interval 5000 # 5 seconds (default for :memory:)
CONFIG SET access-flush-interval 300000 # 5 minutes (default for file DBs)
CONFIG GET access-flush-interval

Trade-offs:

  • Shorter intervals: More accurate LRU/LFU but more disk I/O
  • Longer intervals: Less disk I/O but LRU/LFU is approximate within the window
Database Typepersist-access-trackingaccess-flush-interval
:memory:on5 seconds
File-basedoff5 minutes

File-based databases default to off to avoid WAL bloat and S3 replication costs when using tools like Litestream.

Redlite estimates memory usage per key:

key_memory = key_name_length + value_size + overhead (~150 bytes)

Value size varies by type:

  • String: Length of the value bytes
  • Hash: Sum of all field names + values
  • List: Sum of all element sizes
  • Set: Sum of all member sizes
  • ZSet: Sum of all member sizes + 8 bytes per score
  • Stream: Sum of all entry data

Check memory usage:

Terminal window
MEMORY USAGE mykey # Memory used by a specific key
MEMORY STATS # Overall memory statistics
  • Eviction checks run on write operations only
  • Checks are throttled to once per second
  • Sampling approach is O(1) regardless of key count
  • Access tracking adds ~1 microsecond per read operation

High-performance cache:

Terminal window
./redlite --storage memory \
--max-memory 1073741824 \
--eviction-policy allkeys-lru \
--cache 1024

Persistent with bounded disk:

Terminal window
./redlite --db /data/cache.db \
--max-disk 10737418240 \
--max-memory 1073741824 \
--eviction-policy allkeys-lfu

Minimal overhead (no LRU/LFU tracking):

Terminal window
./redlite --db /data/cache.db \
--max-disk 5368709120 \
--eviction-policy allkeys-random
Terminal window
# Check current limits
CONFIG GET maxmemory
CONFIG GET maxdisk
CONFIG GET maxmemory-policy
# Check usage
MEMORY STATS
DBSIZE
INFO
FeatureRedliteRedis
Memory evictionYesYes
Disk evictionYesNo
LRU/LFU policiesYes (approximate)Yes (approximate)
Volatile policiesYesYes
Sampling size5 keys5 keys (configurable)
Access trackingHashMap + SQLiteIn-memory only
Vacuum-firstYesNo