Is Valkey a drop-in for your Redis?
For Redis OSS up to 7.2, yes. Valkey began as a fork of Redis OSS 7.2.4, and its migration guide calls moving from any open-source Redis release, 2.x through 7.2.x, effectively an upgrade. In practice:
- Your client libraries keep working: Valkey speaks the same RESP2 and RESP3 protocol.
- Valkey reads the
dump.rdband AOF files Redis OSS 7.2 writes, and accepts its configuration directives. redis-clican talk to Valkey, andvalkey-clito an OSS Redis.redis.*Lua scripts andRedisModule_modules still run.
Data from Redis Community Edition 7.4 or newer is the exception: Valkey cannot read its files, and the guide offers no route. Also, INFO keeps answering redis_version:7.2.4 for compatibility, so point your monitoring at valkey_version to see the real release.
What the BSD licence lets you do
The project's COPYING file holds the BSD 3-Clause License text, copyright "Valkey contributors" from 2024 and Redis Ltd. for 2006-2020. Its README says the fork came just before Redis switched to source-available licences, and valkey.io says the Linux Foundation backs the project.
How we read it (not legal advice): a permissive licence. You may use Valkey commercially, change it and hand it on. Whoever distributes copies, as source or compiled, passes on the copyright line, the list of conditions and the warranty disclaimer, and needs written permission before naming the contributors to promote a product. Publishing source code, theirs or yours, is never required. Staying on Redis? Our Redis server guide walks through its licences and setup.
How much memory will you need?
Valkey keeps everything in RAM, so start from your data size. Two rules from the administration page (still flagged as under review) decide the rest: keep maxmemory under the free memory (aim for 8-9 GB if 10 GB are free), and expect a write-heavy instance to need up to double its usual memory while it saves to disk, because pages that change during the save get copied.
| What you keep in it | When memory fills up (our suggestion) | What goes to disk |
|---|---|---|
| A cache of database results | allkeys-lru drops the least recently used keys | Nothing needed |
| Logins, sessions, counters | volatile-lru, or noeviction to refuse writes | Snapshots |
| Job queues, data you cannot lose | noeviction | Snapshots plus the append-only log |
The processor matters less. The sample valkey.conf describes the server as mostly single threaded and suggests I/O threads only when it is truly busy on three or more cores, keeping one free: two or three threads on four cores, six on eight.
The server that fits
Our dedicated servers give you the whole machine with root access and an unmetered port, so a big save never competes with another customer for memory. Choose by RAM:
- Up to 64 GB: an E3-1585L v5 cartridge at 3 GHz with NVMe storage; a fast clock suits a server doing most work on one thread. Compare drives on our NVMe servers.
- Up to 128 GB: one Xeon D-1587 cartridge: sixteen cores and 1.92 TB of NVMe, comfortable for an append-only log that writes all day.
- Up to 1 TB or 2 TB: the two- and four-processor Xeon servers, for one dataset that really is that large.
A console you can open yourself, with the screen and the power button, is included on rack servers and blades and on two cartridge models, m510 and m710x; other cartridges can only be powered on and off remotely. Leave the ARM X-Gene cartridge aside, since Ubuntu 16.04 and 18.04 are all it installs. Ready servers are handed over within 30 minutes of approval; custom builds take hours, not minutes. You manage the server; we keep the hardware and the network running.
Install it and keep it private
On Ubuntu 24.04 the package sits in the universe archive and brings the 7.2 series; Ubuntu 26.04 ships the 9.0 series. Paste this as root. It installs Valkey, checks the stock config still listens only on 127.0.0.1 and ::1 with protected mode on, applies the docs' two kernel settings, and turns the firewall on for IPv4 and IPv6 with only SSH allowed. Ubuntu comes ready to install on our Linux servers.
apt-get update && apt-get install -y valkey-server valkey-tools ufw \
&& systemctl is-active --quiet valkey-server \
&& [ "$(valkey-cli ping)" = PONG ] \
&& grep -qx 'bind 127.0.0.1 -::1' /etc/valkey/valkey.conf \
&& grep -qx 'protected-mode yes' /etc/valkey/valkey.conf \
&& printf 'vm.overcommit_memory = 1\n' > /etc/sysctl.d/60-valkey.conf \
&& sysctl -q -p /etc/sysctl.d/60-valkey.conf \
&& printf 'w /sys/kernel/mm/transparent_hugepage/enabled - - - - never\n' > /etc/tmpfiles.d/valkey-thp.conf \
&& systemd-tmpfiles --create /etc/tmpfiles.d/valkey-thp.conf \
&& grep -q '\[never\]' /sys/kernel/mm/transparent_hugepage/enabled \
&& sed -i 's/^IPV6=.*/IPV6=yes/' /etc/default/ufw \
&& ufw allow OpenSSH && ufw --force enable \
&& echo "STEP 1 OK" || echo "STOP - step 1 did not finish, read the output above"
Go on only after STEP 1 OK. The package runs Valkey as its own valkey user, reads /etc/valkey/valkey.conf and keeps data in /var/lib/valkey. We added the tmpfiles entry so huge pages stay off after a reboot; the docs only show echo never. Re-pasting changes nothing.
Give each app its own login
Out of the box, the default user needs no password. Protected mode blocks other machines only while default is passwordless, and does nothing about programs on the server itself. valkey.io recommends ACL users over one shared requirepass, so this block switches default off and creates admin for you and app for your software. Their random passwords are stored only as SHA-256 hashes (an ACL rule starting with #). It turns on the append-only log and caps memory at 12 GB with noeviction, our pick for a 32 GB server so a save has headroom. On another size, change the 12gb in the block to about three-eighths of the machine's RAM before you paste it (6gb on 16 GB, 24gb on 64 GB; that fraction is our own rule of thumb), and change maxmemory-policy in /etc/valkey/local.conf if the table above suggests another policy.
V=/etc/valkey
if [ -e $V/users.acl ] || [ -e /root/valkey-passwords ]; then echo "STOP - already ran"
elif [ "$(valkey-cli dbsize)" != 0 ]; then echo "STOP - instance holds keys or is not answering, see below"
else
a=$(openssl rand -hex 32); b=$(openssl rand -hex 32)
ha=$(printf %s "$a" | sha256sum | cut -d' ' -f1); hb=$(printf %s "$b" | sha256sum | cut -d' ' -f1)
if [ ${#a}${#b}${#ha}${#hb} = 64646464 ]; then
install -m 600 /dev/null /root/valkey-passwords \
&& printf 'admin %s\napp %s\n' "$a" "$b" > /root/valkey-passwords \
&& install -m 600 -o valkey -g valkey /dev/null $V/users.acl \
&& printf 'user default off\nuser admin on #%s ~* &* +@all\nuser app on #%s ~* &* +@all -@dangerous\n' "$ha" "$hb" > $V/users.acl \
&& install -m 640 -o valkey -g valkey /dev/null $V/local.conf \
&& printf '%s\n' "aclfile $V/users.acl" 'maxmemory 12gb' 'maxmemory-policy noeviction' 'appendonly yes' > $V/local.conf \
&& echo "include $V/local.conf" >> $V/valkey.conf \
&& systemctl restart valkey-server \
&& valkey-cli ping 2>&1 | grep -q NOAUTH \
&& REDISCLI_AUTH=$a valkey-cli --user admin ping | grep -qx PONG \
&& echo "LOCKDOWN OK" || echo "STOP - check journalctl -u valkey-server"
else echo "STOP - password generation did not work, nothing written"; fi
unset a b ha hb
fi
Look for LOCKDOWN OK. It never runs twice, so passwords cannot be overwritten, and it refuses a server that already holds keys: the persistence page warns that switching the append-only log on in the config and restarting a server with data in it can lose that data. Bring data in afterwards with the restore steps below. The passwords live in /root/valkey-passwords, readable by root only. The app login cannot run the @dangerous group, such as FLUSHALL or CONFIG; allow one back with +commandname if your library needs it. Stuck halfway? Remove what it made (the ACL file, local.conf, the password file and the last line of valkey.conf), restart, and paste again. If an Ubuntu update asks about valkey.conf, keep your version.
Keep a copy somewhere else
Valkey writes each snapshot under a temporary name and renames it when finished, which is why the persistence page says dump.rdb can be copied while the server runs. This job does that every hour, tests each copy with valkey-check-rdb, saves your configuration and password file beside it, and clears copies older than two days only after a new one has passed.
install -d -m 700 /srv/valkey-backups && cat > /usr/local/bin/valkey-snapshot <<'EOF'
d=/srv/valkey-backups; t=$(date +%F-%H%M%S); umask 077
cp /var/lib/valkey/dump.rdb "$d/dump-$t.part" \
&& valkey-check-rdb "$d/dump-$t.part" >/dev/null \
&& mv "$d/dump-$t.part" "$d/dump-$t.rdb" \
&& tar -czf "$d/etc-$t.tar.gz" -C / etc/valkey root/valkey-passwords \
&& tar -tzf "$d/etc-$t.tar.gz" >/dev/null \
|| { echo "STOP - valkey snapshot copy FAILED, see $d"; exit 1; }
find "$d" \( -name 'dump-*.rdb' -o -name 'etc-*.tar.gz' \) -mmin +2880 -delete
EOF
printf '%s\n' '41 * * * * root /bin/bash /usr/local/bin/valkey-snapshot >> /var/log/valkey-snapshot.log 2>&1' > /etc/cron.d/valkey-snapshot \
&& bash /usr/local/bin/valkey-snapshot && ls -l /srv/valkey-backups
A copy is only as recent as Valkey's last snapshot: by default an hour after a single change, five minutes after 100, or a minute after 10,000. No dump.rdb yet? Run BGSAVE as admin, then retry. Once a day, fetch one copy from a second machine with rsync -a (leave out --delete) and compare checksums, which the docs advise.
Put a saved file back, or load a Redis dump
Restoring your own snapshot and importing a dump.rdb from Redis OSS 7.2 or an earlier release work alike. The catch: while the append-only log is on, Valkey loads it and ignores the file you copied, so you switch it off for one start. Place the file at /root/import.rdb, then as root set up the helper with C=/etc/valkey/local.conf; adm() { REDISCLI_AUTH="$(grep '^admin ' /root/valkey-passwords | cut -d' ' -f2)" valkey-cli --user admin "$@"; }
- Test the file with
if valkey-check-rdb /root/import.rdb; then echo ok; fi; no ok, no further. - Take a fresh copy of what is there now with
/bin/bash /usr/local/bin/valkey-snapshot || echo STOP, and stop if it prints STOP. - Run
systemctl stop valkey-server, then switch the log off withsed -i '/^appendonly/s/yes/no/' $C && grep -x 'appendonly no' $C. - Move the current data out of the way with
cd /var/lib && [ ! -e valkey-old ] && mv valkey valkey-old && install -d -o valkey -g valkey -m 750 valkey && echo ok. Rename an oldvalkey-oldfirst if one exists. - Place the file with
install -o valkey -g valkey -m 640 /root/import.rdb /var/lib/valkey/dump.rdb, start the service withsystemctl start valkey-server, and checkadm INFO keyspaceshows the key count the source had. - Switch the log back on while it runs with
adm CONFIG SET appendonly yes; whenadm INFO persistenceshowsaof_last_bgrewrite_status:okwith bothaof_rewrite_in_progressandaof_rewrite_scheduledat 0, runsed -i '/^appendonly/s/no/yes/' $C. - Count wrong? Roll back with `systemctl stop valkey-server && cd /var/lib && [ ! -e valkey-bad ] && mv valkey valkey-bad && mv valkey-old valkey && sed -i '/^appendonly/s/no/yes/' $C && grep -x 'appendonly yes' $C && systemctl start valkey-server && echo ok
(it uses theCset above; rename an oldvalkey-bad` first if one exists).
When all is well, delete /var/lib/valkey-old. To get the file from Redis, the migration guide says to disconnect every client and run SAVE. Same server? After SAVE, cp /var/lib/redis/dump.rdb /root/import.rdb, then systemctl disable --now redis-server, since the two cannot share port 6379, and only then do the install, the logins and these steps.
Bring Redis across with only a short pause
If your app cannot stop for a file copy, let Valkey follow Redis as a replica and switch at a quiet moment. Check first that the old machine's redis_version (from INFO server) is 7.2.x or earlier, and that its used_memory fits under your maxmemory. The two talk through an SSH tunnel on your own login, so port 6379 stays closed at both ends.
- On the Valkey server, open the tunnel with
ssh -o ExitOnForwardFailure=yes -fN -L 6380:localhost:6379 you@redis-box. - Redis has a password? Write
masterauth(plusmasteruserfor an ACL login; newer Valkey releases call themprimaryauthandprimaryuser) intolocal.confand restart Valkey, which keeps it out of your shell history. - With the
admhelper above, runadm REPLICAOF localhost 6380. Anything Valkey held before is thrown away. - Repeat
adm INFO replicationuntilmaster_sync_in_progress:0appears next tomaster_link_status:up. - Pause your app's writes, check both sides give the same
INFO keyspace, runadm REPLICAOF NO ONEand point the app at Valkey with theapplogin. Then take themasterauthlines out, close the tunnel and shut Redis down.
Ubuntu's valkey-redis-compat package can take Redis's place on one machine (it copies redis.conf and the Redis data across and waits for you to delete /etc/valkey/REDIS_MIGRATION, per README.Debian), but it skips the logins above, so we prefer loading the dump.
Questions people ask
- Can I run Valkey in Docker on this server?
- You can, with care. The official
valkey/valkeyimage (tags such as9.0.7) is built with protected mode disabled, per the valkey-io/valkey-container build files, so-p 6379:6379would put a password-free server on every address of the machine. Docker-published ports get past ufw for IPv4 traffic, and for IPv6 too once IPv6 is switched on inside Docker. Use-p 127.0.0.1:6379:6379, which stays local from Docker Engine 28 on, and mount a config defining ACL users. - Ubuntu 24.04 has Valkey 7.2. How do I get 9.0?
- valkey.io publishes ready-built tarballs for Ubuntu 22.04 and 24.04 on x86_64 and arm64, with SHA-256 sums to check, and the repository includes
utils/systemd-valkey_server.serviceto base a service on. Updates are then yours to apply. Or install Ubuntu 26.04, whose archive already carries the 9.0 series. - Isn't protected mode enough on its own?
- No. It applies only while
defaulthas no password, ignores programs on the same machine, and anyone administering the server is free to disable it. The listening address, the firewall and long ACL passwords are what keep data private; valkey.io's security page wants all three. - What if my apps run on other servers?
- Valkey sends everything, the login too, unencrypted unless TLS is configured, and there is no private network between our servers, so traffic between two of them crosses the public port. Keep the app on the Valkey machine, or link the machines with WireGuard or an SSH tunnel. Open port 6379 only together with a specific listening address, a firewall rule for each client address and TLS.