Databases

Tune Redis maxmemory and Eviction Policies on a Linux VPS

Set a Redis memory ceiling, pick the right eviction policy and understand how key expiry behaves so your cache stops growing until the server runs out of RAM.

IntermediateLinux server7 min read

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-cli binary 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:

Bash
redis-cli INFO server | grep redis_version
redis-cli CONFIG GET maxmemory
redis-cli CONFIG GET maxmemory-policy

A 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:

Bash
redis-cli INFO memory

The fields that matter:

  • used_memory_human — total data plus overhead, the number you compare against maxmemory.
  • used_memory_rss_human — what the OS has actually given the process. This is usually higher than used_memory because of allocator fragmentation.
  • mem_fragmentation_ratio — rss divided by used_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:

Bash
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:

Bash
redis-cli CONFIG SET maxmemory 2gb
redis-cli CONFIG SET maxmemory-policy allkeys-lru

CONFIG SET applies immediately and survives until the next restart. To make it permanent, edit the config file:

Bash
sudo nano /etc/redis/redis.conf

Find and change these lines:

INI
maxmemory 2gb
maxmemory-policy allkeys-lru

If the lines are commented out with #, remove the #. Then restart:

Bash
sudo systemctl restart redis-server

On 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 handle OOM 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.

Bash
redis-cli CONFIG SET maxmemory-policy volatile-lru

Two tuning knobs affect accuracy:

INI
maxmemory-samples 5
lfu-log-factor 10
lfu-decay-time 1

maxmemory-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:

Bash
redis-cli INFO keyspace

The 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:

Bash
redis-cli SET session:abc123 "data" EX 3600
redis-cli EXPIRE cache:homepage 300
redis-cli TTL cache:homepage

Tip: 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:

Bash
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:

Bash
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:

Bash
redis-cli CONFIG SET maxmemory 20mb
redis-cli INFO stats | grep evicted_keys

Restore your real value afterwards.

Troubleshooting

  • OOM command not allowed when used memory > 'maxmemory' — the policy is noeviction, or a volatile-* policy with no keys carrying a TTL. Switch to allkeys-lru for 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 run redis-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 SET only. Add the lines to /etc/redis/redis.conf and restart the service.
  • maxmemory set but used_memory exceeds it — replication buffers, client output buffers and AOF buffers sit outside the limit. Check INFO clients and INFO memory for mem_clients_normal and replication backlog sizes.

Next steps

Was this guide helpful?

Still stuck?

Ask MdmHost AI for a quick answer, or open a ticket and our team will take a look. We are here 24/7.