Installing Redis
Installing Redis means getting two things onto your machine: the redis-server daemon that stores your data in memory and serves commands, and redis-cli, the command-line client you use to talk to it. Redis ships as a package for every major Linux distribution and macOS, as an official Docker image, and as source code you can compile yourself. This lesson walks through each installation path, shows you how to verify the server is actually running and responding, and covers the mistakes people make when setting Redis up for the first time.
Overview: How Redis Gets Installed and Started
A Redis installation is really two binaries plus a config file. redis-server is the daemon: a single-threaded process that listens on a TCP port (6379 by default), keeps your entire dataset in memory, and processes one command at a time from a queue of connected clients. redis-cli is a thin client that opens a connection to redis-server and sends it commands typed at a prompt — it does no work itself, so a working redis-cli binary tells you nothing about whether a server is actually running. The third piece, redis.conf, is a plain-text configuration file that controls the port, the bind address, persistence settings, memory limits, and more; most package managers install a sensible default copy of it.
Because Redis is single-threaded, startup is a simple, predictable sequence rather than a pool of workers spinning up independently — there is exactly one process to start, and once it logs that it’s ready, every connected client is served by that same thread. This matters for installation because it means “is Redis running” has a single, unambiguous answer: either the one redis-server process is up and listening on its port, or it isn’t.
Redis is not a drop-in replacement for a relational database — it has no query language for ad-hoc joins or filtering — so most installs exist purely to support caching, counters, session storage, queues, or leaderboards for another application. Keep that in mind if you’re deciding whether to install it at all: Redis installation is the easy part, but it commits you to that narrower usage pattern.
Installation Methods
You have four realistic options. Pick the one that matches your environment; all of them get you the same redis-server and redis-cli binaries.
| Method | Best for | Command |
|---|---|---|
| APT (Debian/Ubuntu) | Linux servers and dev machines | sudo apt install redis-server |
| DNF (Fedora/RHEL) | Red Hat-family Linux | sudo dnf install redis |
| Homebrew (macOS) | Local development on a Mac | brew install redis |
| Docker | Disposable/reproducible environments, CI | docker run -d -p 6379:6379 redis:7 |
On Ubuntu or Debian, the package manager installs both binaries, a systemd service, and a default redis.conf, and starts the service immediately:
sudo apt update
sudo apt install redis-server
Output:
Reading package lists... Done
Building dependency tree... Done
...
Setting up redis-server (5:7.0.15-1) ...
Created symlink /etc/systemd/system/redis.service -> /lib/systemd/system/redis-server.service.
redis-server.service is enabled and active (running)
The Docker route skips package management entirely — you pull an image with Redis already built and run it as a container, which is convenient for local testing or CI because it leaves nothing on the host to clean up:
docker run -d --name my-redis -p 6379:6379 redis:7
docker ps --filter name=my-redis
Output:
a1b2c3d4e5f67890123456789abcdef0123456789abcdef0123456789abcdef
CONTAINER ID IMAGE COMMAND STATUS PORTS NAMES
a1b2c3d4e5f6 redis:7 "docker-entrypoint.s..." Up 2 seconds 0.0.0.0:6379->6379/tcp my-redis
Whichever method you use, the port mapping matters: -p 6379:6379 exposes the container’s Redis port to your host so a local redis-cli can reach it at 127.0.0.1:6379.
Examples
Installing Redis is only half the job — you should always confirm the server is actually accepting commands before building anything on top of it. These examples use redis-cli to connect and run a few commands against a fresh install.
Example 1: Confirming the server responds
The simplest possible check is PING, which the server answers immediately with no arguments needed:
PING
SET install:test "hello from apt install"
GET install:test
Output:
PONG
OK
"hello from apt install"
PING is O(1) and exists purely as a liveness check — if it replies PONG, the TCP connection, the port, and the single command-processing thread are all working. SET (O(1)) and GET (O(1)) then confirm the server can actually store and retrieve data, not just answer a heartbeat.
Example 2: Checking that TTL behavior works as expected
A slightly deeper check exercises expiration, since a lot of real Redis usage depends on it:
PING
SET install:check "docker works"
TTL install:check
EXPIRE install:check 60
TTL install:check
Output:
PONG
OK
(integer) -1
(integer) 1
(integer) 60
The first TTL returns -1 because a plain SET creates a key with no expiration. EXPIRE (O(1)) attaches a 60-second TTL and returns 1 to confirm the key existed, and the second TTL call shows the countdown has started. If your install can’t reproduce this sequence, something is wrong with the server, not with your command syntax.
Example 3: A short read/write/delete cycle
DBSIZE
SET greeting "Hello, Redis!"
EXISTS greeting
DEL greeting
DBSIZE
Output:
(integer) 0
OK
(integer) 1
(integer) 1
(integer) 0
DBSIZE (O(1)) reports the number of keys in the current database, EXISTS (O(1)) checks presence without transferring the value, and DEL (O(1) for a single key, O(N) for N keys) removes it. Running this cycle right after installing confirms writes, reads, existence checks, and deletes all round-trip correctly.
How Redis Starts Up, Step by Step
When you launch redis-server, either directly or via the systemd service the package manager installed, it goes through the same sequence every time:
- It reads
redis.conf(or its built-in defaults if no config file is given) to determine the port, bind address, memory limits, and persistence settings. - It allocates the in-memory data structures it needs to track keys — hash tables for the main keyspace and for expiration tracking.
- It binds a TCP socket on the configured port (6379 by default) and starts listening for connections.
- If an RDB snapshot (
dump.rdb) or an AOF log (appendonly.aof) exists from a previous run, it loads that file back into memory before accepting traffic, so restarts don’t lose persisted data. - It logs a line ending in “Ready to accept connections” and enters its single-threaded event loop, using the OS’s I/O multiplexing (epoll on Linux, kqueue on macOS/BSD) to service many client sockets from that one thread.
That single event loop is why every individual command Redis executes is atomic: nothing can interleave in the middle of a command, because there’s only one thread running commands at all. It’s also why a slow command (a huge KEYS *, for instance) blocks every other client until it finishes — there’s no second thread to pick up the slack.
Common Mistakes
Forgetting which port the server is actually on. If you start Redis on a non-default port, plain redis-cli still tries to connect to 6379 and fails — this is a client-side connection error, not something Redis itself returns:
redis-server --port 6380 --daemonize yes
redis-cli -p 6380 PING
redis-cli PING
Output:
PONG
Could not connect to Redis at 127.0.0.1:6379: Connection refused
The fix is always to pass -p <port> (and -h <host> for a remote server) to redis-cli so it matches how the server was actually started.
Assuming a working redis-cli means the server is running. Some distributions split the client and server into separate packages (for example, redis-tools vs. redis-server on Debian). It’s entirely possible to have a functioning redis-cli binary on a machine with no redis-server process running anywhere — the command simply hangs or refuses to connect. Always confirm with PING after installing, not just by checking that the CLI exists.
Installing an old version from a distro’s default repository and expecting new commands. Ubuntu LTS releases in particular often ship a Redis version that’s a year or more behind current. If a command from a recent Redis release comes back as an unknown command, check redis-cli --version before assuming you mistyped it — you may need the official Redis APT repository or the Docker image to get a current release.
Never enabling the service, so Redis doesn’t survive a reboot. A package-manager install typically enables and starts the systemd service automatically, but a manual redis-server invocation or a source build does not persist across restarts unless you explicitly set it up as a service. Don’t discover this the first time your host reboots in production.
Best Practices
- Prefer your OS package manager or the official Docker image over compiling from source — reserve source builds for cases where you need a patch or feature not yet packaged.
- Always verify a fresh install with
PINGbefore writing any application code against it. - Check the version with
redis-cli --versionso you know which command set and behaviors you actually have available. - Let the package manager’s systemd service manage startup/restart rather than running
redis-serverby hand, so Redis survives reboots and crashes. - For Docker, mount a volume for the data directory if you need persistence to survive container recreation — the container filesystem alone is not durable.
- Before exposing a Redis instance beyond localhost, set
requirepassin the config and restrict access with a firewall — a default install has no authentication and binds openly.
Practice Exercises
Exercise 1: Install Redis using whichever method fits your machine (APT, Homebrew, or Docker), then use redis-cli to run PING and confirm you get back PONG.
Exercise 2: Start a second Redis instance on port 6380 alongside your first one on 6379 (using redis-server --port 6380 --daemonize yes or a second Docker container with a different port mapping), and confirm with redis-cli -p 6380 PING that both respond independently.
Exercise 3: Run redis-cli --version and redis-cli PING against your installation, then use SET and GET to store and retrieve one key. Note the version number — you’ll need it later when a lesson mentions a command introduced in a specific Redis release.
Summary
- Installing Redis means getting both
redis-server(the daemon) andredis-cli(the client) onto your machine, via APT, DNF, Homebrew, Docker, or source. - A working
redis-clibinary does not prove a server is running — always confirm withPING. - Redis starts by reading its config, binding a port, optionally loading a persisted RDB/AOF file, then entering a single-threaded event loop.
- Because Redis is single-threaded, exactly one
redis-serverprocess answers “is Redis running” for a given port. - Use
redis-cli‘s-hand-pflags to match the host and port your server actually started on — a plainredis-clicall always assumes127.0.0.1:6379. - Prefer the package manager or official Docker image over building from source, and always set a password before exposing Redis beyond localhost.
