Administration, Monitoring & Troubleshooting
|
This content was generated with the assistance of AI and should be verified against the official Redis documentation before being relied on in production. This section’s bibliography lists the reference material consulted while preparing these pages. |
Examples on this page target Redis Open Source 8.10 (8.10.2) with the Jedis 8 and Lettuce 7.7 client
libraries, and cover the day-to-day administration surface: configuring a running server, reading its
built-in diagnostics (INFO, SLOWLOG, LATENCY, MEMORY, HOTKEYS, CLIENT), benchmarking it,
tuning memory usage, and exporting its metrics to an external monitoring stack.
Configuration: redis.conf and CONFIG
Redis 8.0 through 8.8.x ship two sample configuration files: redis.conf for the core server only, and
redis-full.conf — which starts with include redis.conf — for the server plus the bundled search,
time series, and probabilistic-data-structure components. Redis 8.10 (the version these examples target)
folds everything back into a single redis.conf, so redis-full.conf no longer exists on 8.10+; only
older 8.x installs need to choose between the two files. See
Redis configuration.
# redis.conf -- one directive per line, "keyword argument1 [argument2 ...]"
maxmemory 2gb
maxmemory-policy allkeys-lru
appendonly yes
A running server can be reconfigured live, without editing that file or restarting, using CONFIG GET
parameter [parameter …] and CONFIG SET parameter value [parameter value …] — both accept glob
patterns on CONFIG GET and multiple parameter/value pairs on CONFIG SET in one call, though most
(not all) directives support being changed this way. Live changes never touch redis.conf itself, so a
restart reverts to whatever the file still says unless CONFIG REWRITE is run afterward, which scans the
config file(s) the server was started with and updates only the fields that drifted from the live value,
leaving comments and everything else untouched. See
CONFIG GET,
CONFIG SET, and
CONFIG REWRITE.
127.0.0.1:6379> CONFIG GET maxmemory*
127.0.0.1:6379> CONFIG SET maxmemory 4gb maxmemory-policy allkeys-lru
OK
127.0.0.1:6379> CONFIG REWRITE
OK
INFO: the built-in health snapshot
INFO [section [section …]] returns a text block of field:value pairs grouped into sections; calling
it with no argument returns the default sections, INFO all returns every section including the more
expensive ones, and naming a section (or several) narrows the reply to just that data instead of parsing
the whole block. The sections worth checking first when something looks wrong:
| Section | What to look at |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
One |
See INFO.
127.0.0.1:6379> INFO memory
127.0.0.1:6379> INFO replication
SLOWLOG: the slow-command log
Redis keeps an in-memory ring buffer of commands that took longer than slowlog-log-slower-than
microseconds to execute (default 10000, i.e. 10ms; 0 logs every command, a negative value disables
logging), up to slowlog-max-len entries. SLOWLOG GET [count] returns the most recent entries (each
with an ID, Unix timestamp, execution time in microseconds, and the command’s argument vector),
SLOWLOG LEN returns how many entries are currently stored, and SLOWLOG RESET clears the log — typically the first place to look once INFO stats or an application trace has already pointed at a
period of elevated latency. See SLOWLOG GET and
Diagnosing latency
issues.
127.0.0.1:6379> CONFIG SET slowlog-log-slower-than 5000
OK
127.0.0.1:6379> SLOWLOG GET 10
127.0.0.1:6379> SLOWLOG LEN
(integer) 3
127.0.0.1:6379> SLOWLOG RESET
OK
LATENCY DOCTOR and LATENCY HISTORY
Beyond SLOWLOG, Redis’s latency-monitoring subsystem tracks latency spikes per named event (e.g.
command, fork, expire-cycle) once latency-monitor-threshold (milliseconds) is set above zero.
LATENCY HISTORY event-name returns that event’s raw time series of recorded spikes, each a
timestamp/duration pair — useful for graphing or correlating against an external incident timeline.
LATENCY DOCTOR goes further and returns a free-form, human-readable report that analyzes every recorded
event and suggests likely causes (page faults during a fork, slow commands, expire-cycle pressure, and so
on), which is usually the faster starting point when the root cause isn’t already suspected. See
LATENCY HISTORY and
LATENCY DOCTOR.
127.0.0.1:6379> CONFIG SET latency-monitor-threshold 100
OK
127.0.0.1:6379> LATENCY HISTORY command
127.0.0.1:6379> LATENCY DOCTOR
MEMORY DOCTOR, MEMORY USAGE, and MEMORY STATS
MEMORY USAGE key [SAMPLES count] reports the number of bytes a single key (its value plus its own
overhead) currently occupies — for a large aggregate type, SAMPLES controls how many elements are
sampled to estimate the total rather than walking every element, trading accuracy for speed. MEMORY
STATS returns a structured breakdown of the whole keyspace’s memory (per-database overhead, the
allocator’s own bookkeeping, replication backlog size, and more) as RESP field/value pairs, the same
underlying numbers INFO memory summarizes but broken out further. MEMORY DOCTOR mirrors LATENCY
DOCTOR for memory: it inspects the current allocation pattern and returns a plain-language report
flagging things like high fragmentation or a large number of small keys, without requiring the reader to
already know which MEMORY STATS field to look at. See
MEMORY USAGE,
MEMORY STATS, and
MEMORY DOCTOR.
127.0.0.1:6379> MEMORY USAGE bookshop:book:9780000000001 SAMPLES 0
(integer) 512
127.0.0.1:6379> MEMORY STATS
127.0.0.1:6379> MEMORY DOCTOR
HOTKEYS: finding disproportionately busy keys
HOTKEYS (added in Redis 8.6.0, so available on the 8.10 target of this page) is a container command
for a short tracking session that identifies keys responsible for a disproportionate share of CPU time
and/or network bytes — the same job redis-cli --hotkeys and the older sampling-based approach did far
less precisely. HOTKEYS START METRICS count [CPU] [NET] [COUNT k] [DURATION seconds] [SAMPLE ratio]
begins a session: METRICS is required and names at least one of CPU/NET to track, COUNT
sets how many top keys (k) to keep, DURATION auto-stops the session after that many seconds, and
SAMPLE trades accuracy for overhead by only sampling one key in every ratio commands. HOTKEYS GET
returns the current or most recent session’s results (including by-cpu-time-us and by-net-bytes
key/value arrays), HOTKEYS STOP ends tracking early while keeping the collected data available to
HOTKEYS GET, and HOTKEYS RESET discards it. Because tracking adds per-command overhead, a DURATION
and a conservative SAMPLE ratio keep a production session’s cost bounded. See
HOTKEYS,
HOTKEYS START, and
HOTKEYS GET.
127.0.0.1:6379> HOTKEYS START METRICS 2 CPU NET COUNT 10 DURATION 60 SAMPLE 10
OK
127.0.0.1:6379> HOTKEYS GET
1) "tracking-active"
2) (integer) 1
3) "by-cpu-time-us"
4) 1) "bookshop:book:9780000000001"
2) (integer) 842
127.0.0.1:6379> HOTKEYS STOP
OK
CLIENT LIST and CLIENT KILL
CLIENT LIST [TYPE normal|master|replica|pubsub] returns one line per connected client with its address,
age, idle time, last command, and more, optionally filtered to one connection class — the starting point
for "who is connected right now and what are they doing." CLIENT KILL supports several selector forms:
the legacy CLIENT KILL ip:port, and the newer filter form CLIENT KILL ID client-id | ADDR ip:port |
TYPE type | USER username | SKIPME yes\|no […], which can combine filters and closes every matching
connection instead of exactly one. SKIPME defaults to yes so a filtered kill never closes the very
connection issuing the command; because Redis is single-threaded, a client cannot be killed mid-command,
only once it yields back to the event loop. See
CLIENT LIST and
CLIENT KILL.
127.0.0.1:6379> CLIENT LIST TYPE normal
id=7 addr=127.0.0.1:52344 ... cmd=get age=12 idle=0
127.0.0.1:6379> CLIENT KILL ID 7
(integer) 1
MONITOR
MONITOR streams every command processed by the server, in real time, as it happens — invaluable for a
quick "what is actually being sent right now" trace against a misbehaving application. It comes with a
real performance cost: because Redis is single-threaded, streaming every command to a MONITOR client
competes directly with normal command processing, and the throughput hit grows with the server’s own
command rate, so running it against a busy production instance for anything beyond a short, targeted
trace measurably slows every other client. Ctrl-C (or closing the connection) is the only way to stop it
once started. See MONITOR.
127.0.0.1:6379> MONITOR
OK
1758802531.128374 [0 127.0.0.1:52344] "JSON.GET" "bookshop:book:9780000000001"
redis-benchmark
redis-benchmark is the bundled load-testing tool: it simulates a number of concurrent clients (-c,
default 50) each issuing a total number of requests (-n, default 100000) against a set of commands, and
reports requests per second and latency percentiles per command. -t restricts the run to a comma-separated
command list instead of the default full suite, -d sets the payload size in bytes for SET/LPUSH-style
commands, -P pipelines that many requests per round trip, and --csv switches the summary to CSV for
feeding into another tool. See
Redis benchmark.
redis-benchmark -h 127.0.0.1 -p 6379 -c 50 -n 100000 -t GET,SET -d 128 -P 16 --csv
Memory optimization: small-collection encodings and active defragmentation
Redis automatically picks a compact, cache-friendly encoding for a collection while it stays small, and transparently upgrades it to the general-purpose encoding once a configured size or count threshold is crossed:
| Type | Compact encoding | Threshold config |
|---|---|---|
Hash |
|
|
List |
|
|
Set of small integers |
|
|
Set of short strings |
|
|
Sorted set |
|
|
Keeping collections under these thresholds (splitting an oversized hash across several keys, for example)
is one of the cheapest ways to shrink overall memory use, since a listpack/intset-encoded collection
uses a fraction of the per-element overhead of its general-purpose counterpart. OBJECT ENCODING key
reports which encoding a given key currently uses. Separately, activedefrag (CONFIG SET activedefrag
yes, requires Redis built with jemalloc) runs an incremental background defragmentation pass that
compacts memory fragmented by the normal churn of writes and deletes, targeted by
active-defrag-ignore-bytes/active-defrag-threshold-lower/active-defrag-threshold-upper so it only
kicks in once fragmentation is actually worth paying the CPU cost to fix. See
Memory
optimization.
127.0.0.1:6379> OBJECT ENCODING bookshop:cart:42
"listpack"
127.0.0.1:6379> CONFIG SET activedefrag yes
OK
Redis Insight’s profiler
Redis Insight (3.8 at the time of writing) is the official GUI, and its Profiler view is a graphical
front end over the same command stream MONITOR exposes — it records and displays commands as they
run against a chosen database, with filtering and search, without requiring a separate terminal session
running MONITOR by hand. It carries the same underlying cost as MONITOR while a profiling session is
active, so the same caution against leaving it running against production traffic applies.
Upgrade paths
Redis Open Source generally supports a rolling, in-place upgrade within the same major version by
replacing the binary and restarting, and a minor/patch upgrade (e.g. 8.8 to 8.10) is typically safe to
apply directly to a replica first, promote it, then upgrade the former primary — avoiding a
full-cluster restart window. A major-version upgrade (e.g. 7.x to 8.x) warrants reading that release’s own
upgrade notes first, since configuration file layout (as with redis-full.conf disappearing at 8.10) and
default behaviors can change between major versions; replicating from the old version to a freshly
started new-version replica, verifying it, then failing traffic over is the safer path over an in-place
binary swap for anything beyond a small development instance. See
Upgrade a standalone Redis
instance to Redis 8.
redis_exporter: Prometheus and Grafana
redis_exporter follows the same shape as any other Prometheus exporter described in
Exporters & the Pushgateway: it runs as its own process, connects to a
Redis instance, and translates the output of INFO (plus, optionally, per-key metrics and LATENCY
HISTORY) into Prometheus’s exposition format on its own /metrics endpoint for Prometheus to scrape on
its normal schedule — no polling loop or custom collector needs to be written by hand.
docker run -d --name redis_exporter -p 9121:9121 \
-e REDIS_ADDR=redis://redis:6379 \
oliver006/redis_exporter
A Grafana dashboard built on the exporter’s metric names (redis_memory_used_bytes,
redis_connected_clients, redis_commands_processed_total, redis_keyspace_hits_total/
redis_keyspace_misses_total, and so on) turns the same INFO fields this page reads by hand into
graphs and alerts over time, without polling INFO from an application or a cron job.
Related pages
-
Exporters & the Pushgateway — the general exporter/Pushgateway model
redis_exporterfollows.
References
-
Redis configuration —
redis.conf/redis-full.confand live reconfiguration.