How to choose a VPS for Redis: memory headroom, persistence and port protection
Redis keeps all its data in RAM, so a plan for it is chosen almost by a single parameter: the price per gigabyte of memory. But "how much the data weighs" and "how much memory the server needs" are different numbers. The difference goes on internal structures, fragmentation and, above all, the copy of the process that Redis makes when saving to disk.
How much memory to take
Don't count the size of a dump; count what INFO memory shows on real data: every key has overhead, and a million short keys take up several times more in memory than their contents in a file. Then add headroom on top:
- fragmentation: the
mem_fragmentation_ratiofield; with active overwriting of keys of different sizes it stays above 1.2–1.5; - replication and AOF buffers: they are not counted towards the
maxmemorylimit, and the documentation explicitly advises leaving free memory for them; - saving to disk: under heavy writes during an RDB snapshot or an AOF rewrite, Redis can use up to twice as much memory as usual.
Hence a practical rule: if you have 3–4 GB of data and the database is actively written to, take a VPS with 8 GB, not 4. For a pure cache without persistence the headroom can be smaller. Redis barely loads the cores, since commands run in a single main thread, so two to four cores are usually enough, and a high clock speed is more useful than their number.
maxmemory and the eviction policy
By default, on a 64-bit system no memory limit is set, and Redis grows until the kernel's OOM killer kills it. Always set maxmemory explicitly, with a margin below physical memory: with 10 GB free, the documentation advises setting 8–9 GB. What happens when the limit is reached is decided by maxmemory-policy:
noeviction(the default): delete nothing and return an error on writes. Right for queues, sessions and anything that must not be lost silently.allkeys-lruorallkeys-lfu: delete keys that were used long ago or rarely. The standard choice for a cache.volatile-*: delete only keys with a TTL. If no key has a TTL, the policy behaves likenoeviction.
A cache and a queue in one Redis instance is a common mistake: under a shared allkeys-lru, jobs from the queue sooner or later get evicted. Split them into two instances with different policies; on one VPS that's simply two services on different ports.
RDB, AOF and the cost of fork
RDB is a compact snapshot every few minutes: it restores quickly and is handy for backups, but after a crash you lose the data since the last snapshot. AOF records every command; with the default appendfsync everysec policy you lose no more than a second of writes. The documentation recommends enabling both mechanisms if the data matters, and RDB alone if losing a few minutes is acceptable. For a pure cache, persistence can be disabled entirely.
Both mechanisms work through fork(): the process is copied, and the child copy writes the data to disk. On a large dataset the fork itself takes noticeable time, and all that time Redis doesn't respond to clients, from milliseconds up to a second on a weak CPU. Hence the server requirements:
- KVM virtualisation with dedicated memory: on containers with burst memory, fork hits the limit more often;
vm.overcommit_memory = 1, otherwise background saving may fail to start because of a fork error;- transparent huge pages disabled (
never): with them, copy-on-write causes latency spikes and extra memory use; - swap enabled: the documentation recommends it so that when memory runs short you see rising latency rather than a sudden process crash.
RDB files can be copied while the server is running: the snapshot is written to a temporary file and swapped in atomically. Once a day, send a copy off the server.
Never expose 6379 to the internet
Redis is designed for a trusted network: without a password, anyone who can reach the port can read and wipe the data, and by writing the configuration can gain access to the server itself. Scanners find open instances within hours. The minimum for a VPS:
bind 127.0.0.1 -::1andprotected-mode yes; if the application is on another server, use a private network or WireGuard, not a public IP;- a password or ACL users with minimal rights, with dangerous commands such as
CONFIGandFLUSHALLreserved for the administrator; - in Docker, don't publish the port as
-p 6379:6379: Docker writes its own iptables rules, and such a port can end up open despite your ufw rules. Use127.0.0.1:6379:6379.
If you need Redis as a cache and queue for a website on the same server, also see the VPS for Laravel and VPS for databases selections.