How to Run Valkey on a $6 VPS With Persistence

by David Park
How to Run Valkey on a $6 VPS With Persistence

Valkey is the Linux Foundation fork of Redis that emerged after the Redis license change in 2024. By the end of this guide you will have Valkey 7.2 running on Ubuntu 24.04, writing append-only logs to disk so restarts don't wipe your data, capped to a safe memory ceiling, locked behind a password, and managed by systemd so it survives reboots. Prerequisites: a fresh Ubuntu 24.04 VPS (Hetzner CAX11 or equivalent, 2 GB RAM minimum), a non-root sudo user, and SSH access.

Prerequisites

  • Ubuntu 24.04 LTS (fresh install)
  • 2 GB RAM, 20 GB disk minimum
  • A non-root user with sudo privileges
  • Ports 6379 closed to the public (firewall in place — covered in Step 2)
  • Basic familiarity with systemctl and editing files with nano or vim

Step 1 — Update the System and Install Build Dependencies

Valkey is not yet in Ubuntu 24.04's default apt repositories, so you will build it from source. First, update the package index and install the required tools.

sudo apt update && sudo apt upgrade -y
sudo apt install -y build-essential tcl libssl-dev pkg-config

This installs GCC, Make, the TCL interpreter (needed for Valkey's test suite), and OpenSSL headers.

Step 2 — Lock Down the Firewall Before Anything Else

Before you open a cache port, close everything you don't need. If you have ufw active, run:

sudo ufw default deny incoming
sudo ufw allow OpenSSH
sudo ufw enable
sudo ufw status

Expected output:

Status: active

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere

Valkey will bind only to 127.0.0.1, so port 6379 never needs to be open to the internet. If your app runs on the same host, that's all you need. If it runs on a separate private network node, add a rule for that private IP only — never 0.0.0.0.

Step 3 — Download and Build Valkey

Fetch the 7.2.x release tarball from the official Valkey GitHub releases page.

cd /usr/local/src
sudo wget https://github.com/valkey-io/valkey/archive/refs/tags/7.2.5.tar.gz
sudo tar xzf 7.2.5.tar.gz
cd valkey-7.2.5

Build with TLS support disabled (saves compile time; enable it if your app talks to Valkey over a network):

sudo make -j$(nproc)

On a 2-vCPU Hetzner CAX11 this takes roughly 90 seconds. Run the test suite to confirm the build is clean:

sudo make test 2>&1 | tail -5

Expected last line:

\o/ All tests passed without errors!

Install the binaries to /usr/local/bin:

sudo make install

Verify the binary is in place:

valkey-server --version

Expected output:

Valkey server v=7.2.5 sha=00000000:0 malloc=libc bits=64 build=...

Step 4 — Create a Dedicated System User and Directories

Never run Valkey as root. Create a locked system account:

sudo useradd --system --no-create-home --shell /bin/false valkey

Create the data and log directories and assign ownership:

sudo mkdir -p /var/lib/valkey /var/log/valkey /etc/valkey
sudo chown valkey:valkey /var/lib/valkey /var/log/valkey
sudo chmod 750 /var/lib/valkey /var/log/valkey

Step 5 — Write the Configuration File

Copy the default config as a starting point, then override the values that matter for a small VPS.

sudo cp /usr/local/src/valkey-7.2.5/valkey.conf /etc/valkey/valkey.conf

Open the file:

sudo nano /etc/valkey/valkey.conf

Locate and change the following directives (search with Ctrl+W in nano):

# Bind to localhost only
bind 127.0.0.1

# Require a password — replace with a strong random string
requirepass YOUR_STRONG_PASSWORD_HERE

# Cap memory to 256 MB on a 2 GB VPS
maxmemory 256mb

# Evict least-recently-used keys when the cap is hit
maxmemory-policy allkeys-lru

# Enable append-only persistence
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec

# Disable RDB snapshots (AOF is enough for this setup)
save ""

# Write data to the dedicated directory
dir /var/lib/valkey

# Write logs to file
logfile /var/log/valkey/valkey.log
loglevel notice

# Run as the valkey user (systemd will also enforce this)
daemonize no

Save and close the file (Ctrl+X, then Y, then Enter).

Set restrictive permissions on the config so the password isn't world-readable:

sudo chown root:valkey /etc/valkey/valkey.conf
sudo chmod 640 /etc/valkey/valkey.conf

Step 6 — Create the systemd Service Unit

Create the unit file:

sudo nano /etc/systemd/system/valkey.service

Paste the following content exactly:

[Unit]
Description=Valkey In-Memory Data Store
After=network.target

[Service]
Type=simple
User=valkey
Group=valkey
ExecStart=/usr/local/bin/valkey-server /etc/valkey/valkey.conf
ExecStop=/usr/local/bin/valkey-cli -a YOUR_STRONG_PASSWORD_HERE shutdown nosave
Restart=on-failure
RestartSec=5s
LimitNOFILE=65535
NoNewPrivileges=yes
PrivateTmp=yes
ProtectSystem=full
ReadWritePaths=/var/lib/valkey /var/log/valkey

[Install]
WantedBy=multi-user.target

Replace YOUR_STRONG_PASSWORD_HERE with the same password you set in valkey.conf.

Reload systemd, enable the service, and start it:

sudo systemctl daemon-reload
sudo systemctl enable valkey
sudo systemctl start valkey

Check the service status:

sudo systemctl status valkey

Expected output (truncated):

● valkey.service - Valkey In-Memory Data Store
     Loaded: loaded (/etc/systemd/system/valkey.service; enabled)
     Active: active (running) since ...

Verify It Works

Connect with the CLI and authenticate:

valkey-cli -a YOUR_STRONG_PASSWORD_HERE ping

Expected output:

PONG

Write a key, restart the service, and confirm the key survives:

valkey-cli -a YOUR_STRONG_PASSWORD_HERE set testkey "hello-persistence"
sudo systemctl restart valkey
valkey-cli -a YOUR_STRONG_PASSWORD_HERE get testkey

Expected output:

"hello-persistence"

If you see "hello-persistence" after the restart, AOF persistence is working correctly.

Check memory usage:

valkey-cli -a YOUR_STRONG_PASSWORD_HERE info memory | grep used_memory_human

Expected output on a fresh instance:

used_memory_human:896.50K

Confirm the AOF file is being written:

ls -lh /var/lib/valkey/

Expected output:

-rw-r--r-- 1 valkey valkey 57 Jan  1 00:00 appendonly.aof

Troubleshooting

Service fails to start — "Permission denied" on /var/lib/valkey Run sudo chown -R valkey:valkey /var/lib/valkey and restart the service.

valkey-cli returns NOAUTH Authentication required You connected without -a YOUR_STRONG_PASSWORD_HERE. Always pass the flag or use AUTH inside the CLI session.

make test fails with "You need tcl 8.5 or newer" Run sudo apt install -y tcl and retry.

used_memory keeps climbing toward maxmemory This is expected if you're storing a lot of data. Check which keys are largest with valkey-cli -a PASSWORD --bigkeys. Consider increasing maxmemory or switching to volatile-lru if only some keys have TTLs.

AOF file grows unboundedly Valkey rewrites the AOF automatically when it doubles in size, but you can trigger it manually: valkey-cli -a PASSWORD bgrewriteaof. Monitor the file size with ls -lh /var/lib/valkey/appendonly.aof.

Port 6379 shows as open in nmap from outside The bind 127.0.0.1 directive should prevent this. Double-check the running config: valkey-cli -a PASSWORD config get bind. If it still shows 0.0.0.0, the config file change wasn't picked up — verify the path in the systemd unit matches /etc/valkey/valkey.conf.

Next Steps

With Valkey running and persisting data, you have a production-grade caching layer for under $0.01/hour of additional server cost. From here:

  • Connect your app: use any Redis-compatible client (ioredis, redis-py, go-redis) — point it at 127.0.0.1:6379 with your password. No code changes required beyond the connection string.
  • Set up log rotation: add /var/log/valkey/valkey.log to /etc/logrotate.d/ so the log file doesn't eat your disk over months.
  • Monitor with Prometheus: the comparison on techjournaler.com exposes Valkey metrics in Prometheus format — bolt it onto your existing Grafana stack if you have one.
  • Tune appendfsync: everysec is the right default for most workloads (at most one second of data loss on a crash). Switch to always only if you're using Valkey as a primary store and can't tolerate any loss — it will cut write throughput significantly on a shared VPS disk.