Redis keeps everything in RAM, so an unbounded instance will happily grow until the kernel OOM killer or the allocator ends the process. Setting maxmemory and an eviction policy gives Redis a defined ceiling and a rule for what to throw away when it reaches that ceiling. This guide walks through measuring current usage, choosing a policy, applying it in redis.conf, and confirming that evictions happen the way you expect.
The two settings work as a pair: maxmemory says how much data Redis may hold, and maxmemory-policy says what happens at the limit. Get them wrong and you either lose keys you needed or crash the server.
Before you start
You need:
- A Linux VPS with Redis installed and running. If you have not set it up yet, follow how to install and secure Redis on a Linux VPS.
- Root or sudo access, and the
redis-clibinary on the same host. - A rough idea of how much RAM the VPS has and what else runs on it. Check with
free -m. - Knowledge of whether the data is a cache (safe to evict) or a store (must not be evicted). This decides everything below.
Warning: Changing maxmemory to a value lower than current usage can trigger immediate mass eviction or write errors. Note the current usage before you change anything.
Confirm the server version and current settings:
redis-cli INFO server | grep redis_version
redis-cli CONFIG GET maxmemory
redis-cli CONFIG GET maxmemory-policyA fresh install usually reports maxmemory as 0, which means no limit at all.
Measure what Redis is actually using
Start with the memory section of INFO:
redis-cli INFO memoryThe fields that matter:
used_memory_human— total data plus overhead, the number you compare againstmaxmemory.used_memory_rss_human— what the OS has actually given the process. This is usually higher thanused_memorybecause of allocator fragmentation.mem_fragmentation_ratio—rssdivided byused_memory. Slightly above 1 is normal. Above 1.5 means wasted RAM you could reclaim with a restart.maxmemory_policy— the policy currently in force.
Then find out what is taking the space:
redis-cli --bigkeys
redis-cli INFO keyspace--bigkeys scans the keyspace and reports the largest key per type. It is a sampling scan, so it is safe on a live server, but it does add load — avoid running it during peak traffic.
Tip: MEMORY USAGE <key> gives the exact byte cost of one key including overhead. Use it when you need to size a specific structure.
Set maxmemory to a safe ceiling
Leave headroom for the OS, the Redis process overhead, replication buffers and any other service on the box. A common starting point is 60–75% of total RAM on a dedicated Redis VPS. If Redis shares the machine with a web app or database, budget accordingly.
Say the VPS has 4 GB and Redis is the main workload — 2 GB is a reasonable ceiling:
redis-cli CONFIG SET maxmemory 2gb
redis-cli CONFIG SET maxmemory-policy allkeys-lruCONFIG SET applies immediately and survives until the next restart. To make it permanent, edit the config file:
sudo nano /etc/redis/redis.confFind and change these lines:
maxmemory 2gb
maxmemory-policy allkeys-lruIf the lines are commented out with #, remove the #. Then restart:
sudo systemctl restart redis-serverOn some distributions the unit is named redis instead of redis-server; check with systemctl list-units | grep redis.
Warning: Restarting Redis drops the in-memory dataset unless persistence is configured and working. Verify with redis-cli INFO persistence that rdb_last_bgsave_status is ok before you restart a store-type instance.
Choose the right eviction policy
Redis offers eight policies. The ones you will actually pick:
noeviction— returns an error on writes once the limit is reached. Correct for a dataset you cannot lose, but the application must handleOOM command not allowed when used memory > 'maxmemory'.allkeys-lru— evicts the least recently used key across the whole keyspace. The default choice for a pure cache.allkeys-lfu— evicts the least frequently used key. Better when popularity matters more than recency, for example a product catalogue where a few items get most of the traffic.allkeys-random— evicts a random key. Rarely the best choice, but cheap on CPU.volatile-lru,volatile-lfu,volatile-random,volatile-ttl— evict only keys that have an expiry set. Use these when the instance holds both cache keys and permanent keys.
The volatile-* family is the safe middle ground: mark cache entries with EXPIRE and leave durable keys without one. If every volatile key is gone and memory is still full, Redis behaves like noeviction and starts rejecting writes.
redis-cli CONFIG SET maxmemory-policy volatile-lruTwo tuning knobs affect accuracy:
maxmemory-samples 5
lfu-log-factor 10
lfu-decay-time 1maxmemory-samples controls how many keys Redis inspects when approximating LRU or LFU. Higher values are more accurate and slightly more expensive. The LFU settings only apply to allkeys-lfu and volatile-lfu; check the current Redis documentation for the exact semantics before changing them, since behaviour has been refined across versions.
Understand key expiry
Expiry and eviction are different mechanisms. Eviction happens because memory is full; expiry happens because a TTL ran out. Expired keys are removed lazily on access and by a background cycle that samples volatile keys.
Check how many keys are volatile:
redis-cli INFO keyspaceThe expires column shows how many keys in each database have a TTL. If it is 0 while you use a volatile-* policy, nothing can be evicted and writes will fail.
Set TTLs on cache writes:
redis-cli SET session:abc123 "data" EX 3600
redis-cli EXPIRE cache:homepage 300
redis-cli TTL cache:homepageTip: Always set a TTL on cache keys. It bounds staleness and gives volatile-* policies something to work with.
Check it works
Confirm the settings took effect:
redis-cli CONFIG GET maxmemory
redis-cli CONFIG GET maxmemory-policy
redis-cli INFO memory | grep -E "used_memory_human|maxmemory_human|maxmemory_policy"Then watch eviction counters under real traffic:
redis-cli INFO stats | grep -E "evicted_keys|expired_keys"evicted_keys rising steadily means the ceiling is being hit and the policy is doing its job. If it climbs fast and hit rate drops, the instance is undersized — either raise maxmemory or reduce what you store.
To test deliberately, set a small limit, write keys until it is reached, and watch the counter move:
redis-cli CONFIG SET maxmemory 20mb
redis-cli INFO stats | grep evicted_keysRestore your real value afterwards.
Troubleshooting
OOM command not allowed when used memory > 'maxmemory'— the policy isnoeviction, or avolatile-*policy with no keys carrying a TTL. Switch toallkeys-lrufor a cache, or add expiries to cache keys.- Memory stays high after deleting keys — the allocator has not returned pages to the OS. Check
mem_fragmentation_ratio; a restart reclaims it. Persistent growth with a flat key count usually means large values, so runredis-cli --bigkeys. - Evictions happen but hit rate still falls — the working set is larger than
maxmemory. Raise the limit, or split hot and cold data across two instances. - Settings revert after a reboot — you used
CONFIG SETonly. Add the lines to/etc/redis/redis.confand restart the service. maxmemoryset butused_memoryexceeds it — replication buffers, client output buffers and AOF buffers sit outside the limit. CheckINFO clientsandINFO memoryformem_clients_normaland replication backlog sizes.
Next steps
- Optimizing Redis for high-read, low-latency applications covers pipelining, connection handling and latency checks.
- Configure Redis remote access with bind and protected-mode if clients connect from another host.
- How to install and secure Redis on a Linux VPS for a clean baseline install.
