JusDB
Free DB Audit
NoSQL Databases

Valkey Security Hardening: ACLs, TLS, LDAP, and Building Without Lua

Harden a Valkey 9.1 server for production: network exposure, least-privilege ACL users with db= rules, TLS rotation, valkey-ldap, Lua-free builds, and NOPERM debugging.

JusDB Team
Published November 5, 2026
Updated November 10, 2026
20 min read

A fresh Valkey 9.1 server trusts whoever can reach it. The default user is on nopass ~* &* +@all, so only the listening address and protected mode stand between a stranger and FLUSHALL, and the official Docker image compiles protected mode off. Hardening closes that gap, and it usually announces itself with errors such as NOPERM No permissions to access a key, which do not say which rule denied the call. This guide covers Valkey 9.1.3, the current patch as of November 2026: network exposure, least-privilege ACL users with the 9.1 per-database rules, TLS and certificate rotation, what an expired certificate does on 9.1.x, LDAP through valkey-ldap, building without Lua, and debugging denials with ACL LOG and ACL DRYRUN.

TL;DR
  • Check what is listening first: a server started without a config file binds every interface, and the official valkey/valkey image compiles protected mode off.
  • Turn the default user off and give every application, replica, Sentinel, and monitoring agent its own user with a key prefix, a db= list, and no @admin or @dangerous commands, on 9.1.2 or later.
  • Valkey 9.1.x loads expired certificates without complaint, although the TLS page says otherwise (the check was reverted in #3572). Alert on INFO tls and set tls-auto-reload-interval.
  • Lua has no runtime switch in 9.1. Remove it with make BUILD_LUA=no, after an inventory shows no script traffic.
  • A NOPERM message often hides the key or database. ACL LOG and ACL DRYRUN name them.

Scope and review date: November 2026. This post covers self-managed Valkey 9.1 (9.1.3, released 26 October 2026), with notes where 9.0, 8.x, or the 9.2 release candidates differ. Defaults and behavior were checked on 10 November 2026 against the Valkey documentation, the 9.1.3 valkey.conf and source, the release notes, the official container build files, and the valkey-ldap repository. The commands were not run in a lab, so rehearse them on staging. Managed services are out of scope.


How exposed is a default Valkey 9.1 server?

It depends on how the server was started:

  • With the shipped valkey.conf: bind 127.0.0.1 -::1 and protected-mode yes, so only local clients connect.
  • With no config file: the compiled-in default is bind * -::*, every interface. Protected mode is still on.
  • With the official Docker image: the valkey/valkey build patches config.c so protected-mode defaults to no, because Docker publishes no ports unless asked. valkey-bundle is built on it. In Kubernetes or with host networking, such a container accepts every client that can route to it.

The Valkey administration page still says the server "listens to all the network interfaces" with no authentication by default, which describes only the no-config case. Check the running server instead:

bash
valkey-cli -h 127.0.0.1 CONFIG GET bind
valkey-cli -h 127.0.0.1 CONFIG GET protected-mode
valkey-cli -h 127.0.0.1 ACL GETUSER default
ss -ltnp | grep valkey

Interpretation: * -::* means every interface. If the default user has the nopass flag and protected mode is no, every client that reaches a listening address is fully authenticated without sending AUTH.

Protected mode is a safety net, not a control: it applies only while the default user has nopass. Once a password is set, the server takes AUTH attempts from any address it listens on. Bind to loopback plus the one private interface clients use, for example bind 127.0.0.1 -::1 10.0.4.15, and filter the port with security groups or a NetworkPolicy. Pre-authentication reachability has had its own bug: CVE-2025-21605, fixed in 8.1.1, 8.0.3, and 7.2.9, let unauthenticated clients grow output buffers without a limit.

A default Valkey 9.1 server next to a hardened one

Switch tabs to see which settings this guide changes

Default 9.1

SettingDefault 9.1
Listening addressesLoopback with valkey.conf; all interfaces without one
Protected modeOn; off in the official Docker image
Default useron nopass ~* &* +@all
Application usersNone
Client connectionsPlain TCP on 6379
Replication and cluster busPlain TCP
Certificate reloadOff (tls-auto-reload-interval 0)
Scripting engineLua linked in and loaded at startup
DEBUG and MODULE commandsBlocked

Hardened 9.1

SettingHardened 9.1
Listening addressesLoopback plus one private interface, firewalled
Protected modeOn, kept as a safety net
Default useroff, no password, no commands
Application usersOne per service: key prefix, db=, no @dangerous
Client connectionsTLS only: port 0, tls-port 6379
Replication and cluster bustls-replication yes, tls-cluster yes
Certificate reloadInterval set, plus an INFO tls alert
Scripting engineBUILD_LUA=no when no client uses scripts
DEBUG and MODULE commandsBlocked

Already safe: enable-debug-command, enable-module-command, and enable-protected-configs default to no and can only change at startup. The open default user is the setting that matters most.

How should you design ACL users for applications?

One user per service, built up from nothing. Start with -@all, add the categories the service needs, and remove @dangerous last; rules apply left to right. Add the service's key prefix, resetchannels unless it uses Pub/Sub, and on 9.1 a db= list. Keep users in an external ACL file:

ini
# /etc/valkey/users.acl (Valkey 9.1; earlier versions do not know db=)
user default off resetpass resetkeys resetchannels -@all
user admin on #REPLACE_WITH_SHA256 ~* &* +@all
user orders on #REPLACE_WITH_SHA256 resetchannels ~orders:* ~cart:* db=0 -@all +@read +@write +@connection +@transaction -@dangerous
user reports on #REPLACE_WITH_SHA256 resetchannels %R~orders:* db=0 -@all +@read +@connection -@dangerous

Interpretation: the trailing -@dangerous strips FLUSHALL, FLUSHDB, KEYS, SORT, and the rest of that category from what +@write added. %R~ makes reports read-only on the order keys. The # form stores a SHA-256 hash, so the file holds no plain passwords.

bash
PASS=$(valkey-cli ACL GENPASS)      # 64 hex characters from the system CSPRNG
printf '%s' "$PASS" | sha256sum     # value for the #REPLACE_WITH_SHA256 rule
valkey-cli ACL LOAD                 # reload users.acl; one bad line rejects the file
valkey-cli ACL SAVE                 # write runtime ACL SETUSER changes back

Interpretation: per the Valkey ACL documentation, a failed ACL LOAD keeps the old users, and CONFIG REWRITE does not call ACL SAVE. aclfile is immutable, so moving users out of valkey.conf needs one restart.

Three behaviors catch teams. New connections land in database 0 even when the user cannot use it, so set the database in the client's connection options. FLUSHALL, CLUSTER MIGRATESLOTS, and CLUSTER CANCELSLOTMIGRATIONS need alldbs. And a user or selector without a db= rule starts with alldbs.

Patch before you lock the default user

Before 9.1.2, 9.0.6, 8.1.10, 8.0.11, and 7.2.15, AOF loading ran ACL checks on replayed commands, and the release notes describe silent data loss when the default user is disabled (#3984). Database ACL bypasses through COPY, MOVE, and CLUSTER FLUSHSLOT were closed in 9.1.1 and 9.1.2.

Which commands should no application run?

@admin holds CONFIG, DEBUG, MONITOR, ACL, SHUTDOWN, and REPLICAOF. @dangerous adds FLUSHALL, KEYS, MIGRATE, RESTORE, CLIENT, and INFO. MONITOR streams every command with its arguments. The 9.1.3 valkey.conf marks rename-command as deprecated in favor of ACLs. Run ACL CAT dangerous after each minor upgrade, because new commands join categories.

How Valkey evaluates a command against these rules

A user has root permissions and optional selectors in parentheses. A command runs if any one permission set allows the command and every key, channel, and database it touches. Valkey 9.2, still a release candidate as of November 2026, adds named roles, checked the same way after the selectors.

ACL evaluation for one command in Valkey 9.1

Each permission set is checked in turn; the first full match runs the command

How Valkey decides whether a command is allowed A command arrives with a user, a selected database, and arguments. Valkey checks the user's root permissions for the command, its keys, channels, and databases. If they allow it, the command runs. If not, Valkey checks each selector in the order added, and in the 9.2 release candidates each role in the order assigned. If any allows the whole command, it runs. If none does, the client gets a NOPERM error and ACL LOG records an entry. Command user, db, args Root rules command, keys, db Selectors in order added Roles 9.2 RC only Run command one set matched NOPERM plus ACL LOG entry no match match match match nothing matched

OR, not AND: selectors and roles only add rights. In the 9.2 release candidates a new role starts with alldbs, so giving it to a db=0 user grants every database unless the role has its own db= rule.

What permissions do replicas, Sentinel, and monitoring agents need?

Each needs a small, fixed command set. The ACL documentation lists the replication commands, and the 9.1.3 sentinel.conf carries a more current Sentinel rule than the ACL page.

ini
# On every node (rule from the ACL docs)
user replica-user on >REPLACE_ME +@write ~* -@dangerous +ping +select +sync +psync +replconf +cluster|syncslots -flushall -flushdb -restore -restore-asking
# Also on every node, because any node can become a replica after a failover
primaryuser replica-user
primaryauth REPLACE_ME

Interpretation: plain replication needs only PING, SYNC, PSYNC, and REPLCONF; the @write, SELECT, and CLUSTER SYNCSLOTS part serves atomic slot migration in 9.0 cluster mode. A replica always treats its primary as the root user, so replicas need no user for the primary.

ini
# On every monitored node (rule from the 9.1.3 sentinel.conf)
user sentinel-user on >REPLACE_ME +subscribe +publish +failover +script|kill +ping +info +multi +slaveof +config +client +exec &__sentinel__:hello
# In sentinel.conf
sentinel auth-user mymaster sentinel-user
sentinel auth-pass mymaster REPLACE_ME

Interpretation: since Sentinel 9.0 the user needs +failover, which the ACL page example omits. Sentinel holds all of CONFIG and CLIENT, so treat its password like an admin password.

ini
# Monitoring: no keys, no CONFIG
user monitor on >REPLACE_ME resetchannels -@all +ping +info +client|list +slowlog|get +latency|latest +cluster|info

Interpretation: grant what your exporter calls, then read ACL LOG after the first scrape. Keep CONFIG GET away from monitoring: in 9.1.3 the sensitive flag only redacts CONFIG SET arguments in logs, so CONFIG GET primaryauth returns the replication password in plain text.

How do you enable TLS and rotate certificates without a restart?

TLS is a build option (make BUILD_TLS=yes, or module, which Sentinel does not support). The official Docker image is built with BUILD_TLS=yes; check distribution packages yourself. A TLS-only node:

ini
port 0
tls-port 6379
tls-cert-file /etc/valkey/tls/server.crt
tls-key-file /etc/valkey/tls/server.key
tls-ca-cert-file /etc/valkey/tls/ca.crt
tls-auth-clients yes
tls-replication yes
tls-cluster yes
tls-protocols "TLSv1.2 TLSv1.3"
tls-auto-reload-interval 3600

Interpretation: port 0 closes the plaintext listener. tls-auth-clients yes, the default, requires a client certificate; optional accepts one without requiring it. Valkey never uses the system CA store, so a CA file or directory is required. tls-replication covers replicas and Sentinel, and tls-cluster covers the cluster bus. TLSv1.2 and TLSv1.3 are already the defaults; stating them helps an audit.

tls-auto-reload-interval is new in 9.1 and defaults to 0 (off). Above zero, a background thread checks the files on that interval and swaps in new material without blocking the main thread. Pull request #3020 says it detects certificate changes by SHA-256 fingerprint, and key file and CA directory changes by inode and modification time. A reload through CONFIG SET still runs synchronously.

bash
# Option A: atomic renames, then wait one interval
mv /etc/valkey/tls/server.key.new /etc/valkey/tls/server.key
mv /etc/valkey/tls/server.crt.new /etc/valkey/tls/server.crt

# Option B: versioned files switched in one CONFIG SET, then persisted
valkey-cli --tls --cacert /etc/valkey/tls/ca.crt --user admin --askpass \
  CONFIG SET tls-cert-file /etc/valkey/tls/server-2026-11.crt \
             tls-key-file /etc/valkey/tls/server-2026-11.key
valkey-cli --tls --cacert /etc/valkey/tls/ca.crt --user admin --askpass CONFIG REWRITE

Interpretation: renames switch each file at once, so a check never reads a half-written file. Option B returns any error to you, and setting certificate and key in one command avoids a mismatched pair.

Using the client certificate as the user

tls-auth-clients-user logs a client in as the ACL user named in its certificate: CN since 9.0, or the first SAN URI that matches an enabled user since 9.1. If no user matches, the client stays the default user and ACL LOG records a tls-cert entry. With a nopass default user, that client has full access.

ini
tls-auth-clients-user URI
# resetpass: this user can log in only with a certificate
user urn:valkey:user:orders on resetpass resetchannels ~orders:* db=0 -@all +@read +@write +@connection -@dangerous

Interpretation: a client with URI:urn:valkey:user:orders in its SAN is authenticated during the handshake. Run 9.1.2 or later, which compares the whole CN so an embedded NUL byte cannot impersonate a shorter username (#4577).

TLS bugs have their own patch floor

CVE-2026-56684, a use-after-free in TLS connection handling reachable through CLIENT KILL, was fixed in 9.1.1, 9.0.5, 8.1.9, 8.0.10, and 7.2.14.

What happens when a certificate expires on Valkey 9.1.x?

Valkey 9.1.x loads it anyway. The TLS documentation says loading fails "immediately" for a certificate outside its validity period. That is pull request #2999, which pull request #3572 reverted from 9.1 in 9.1.0-rc2 "as it's a breaking change", deferring it to the next major version. The 9.1.3 tls.c has no validity check.

So an expired certificate does not stop startup, CONFIG SET, or an automatic reload. The failure moves to the peers: clients that verify the server certificate refuse the handshake, and with tls-replication and tls-cluster, replicas and cluster nodes verify each other too, so links drop as connections are re-established. The 9.2.0-rc2 source does contain the check and logs Server TLS certificate is invalid. Aborting TLS configuration., so expect startup failures there.

bash
valkey-cli --tls --cacert /etc/valkey/tls/ca.crt --user monitor --askpass INFO tls

Interpretation: the section, added in 9.1 (#2913), is not part of plain INFO. It reports a serial and an expires_in_seconds value for the server, client, and CA certificates, such as tls_server_cert_expires_in_seconds. Each counter stops at 0, so a serial with 0 seconds left means expired. Alert at 14 days (1,209,600 seconds) on all three.

How do you authenticate Valkey users against LDAP?

With valkey-ldap, an official Valkey module written in Rust, compatible with Valkey 7.2 and later. As of November 2026 the latest release is 1.1.1 (29 June 2026). The repository publishes RPM and DEB build artifacts, and the valkey-bundle 9.1 image ships 1.1.1; its entrypoint loads every module in /usr/lib/valkey, used or not.

The module only checks passwords. Each LDAP user must also exist as a Valkey ACL user that holds its permissions, created without a password so LDAP is the only way in. MODULE LOAD is blocked by default, so load it from the config file:

ini
loadmodule /usr/lib/valkey/libvalkey_ldap.so
ldap.servers "ldaps://ldap1.example.internal:636 ldaps://ldap2.example.internal:636"
ldap.auth_mode search+bind
ldap.search_bind_dn "cn=valkey-svc,ou=service,dc=example,dc=internal"
ldap.search_bind_passwd REPLACE_ME
ldap.search_base "ou=people,dc=example,dc=internal"
ldap.tls_ca_cert_path /etc/valkey/tls/ldap-ca.crt

Interpretation: search+bind finds the user's DN by the uid attribute (the default), then binds as that DN with the AUTH password. Use ldaps:// or ldap.use_starttls yes, or passwords reach the directory unencrypted. The docs' prose says ldap.search_base_dn, but the option table and README say ldap.search_base.

bash
valkey-cli ACL SETUSER alice on resetpass resetchannels -@all +@read +info '~*'
valkey-cli INFO ldap_status    # per server: healthy with ping_time_ms, or unhealthy with error

Interpretation: alice has no local password, so her AUTH succeeds only if the directory accepts it. Keep one local admin with a vaulted password for when the directory is unreachable.

Use LDAP for people, not services. According to the project README, every AUTH goes to the module first, so a service account with a local password costs an LDAP lookup and a failure log line; an ldap.exclude_users option is on the main branch but in no release yet. The default pool is 2 connections per server. If you run 1.0.0, upgrade: 1.0.1 fixed CONFIG REWRITE writing an obfuscated ldap.search_bind_passwd.

Can you turn Lua off in Valkey 9.1?

Not at runtime. 9.1.0-rc1 moved the Lua engine into a module (#2858), and 9.1.0-rc2 made static linking the default (#3392). The 9.1 announcement speaks of "the option to disable Lua entirely", but there is no valkey.conf directive, and server.c loads the static engine at startup. make BUILD_LUA=no builds without the engine; BUILD_LUA=module builds libvalkeylua.so, loaded only through loadmodule. The official Docker image uses the default, so it has Lua. Since 9.1.2, Sentinel does not load Lua.

Of the 24 CVE and GHSA identifiers in Valkey release notes since October 2024, nine involve Lua:

AdvisoryIssue (release note wording)Fixed in
CVE-2024-31449Lua library commands may lead to stack overflow and potential RCE8.0.1, 7.2.7
CVE-2024-46981Lua script commands may lead to remote code execution8.0.2, 7.2.8
CVE-2025-49844, -46817, -46818, -46819RCE, integer overflow, execution as another user, out-of-bound read8.1.4, 8.0.6, 7.2.11
CVE-2025-67733RESP protocol injection via Lua error_reply9.0.3, 8.1.6, 8.0.7, 7.2.12
CVE-2026-23631Use-after-free when full sync occurs during a yielding Lua or function execution9.1.0, 9.0.4, 8.1.7, 8.0.9, 7.2.13
GHSA-fq2f-crmw-q97rUnauthenticated use-after-free of the Lua interpreter state9.1.2

Inventory scripts first. Job queues such as BullMQ, lock libraries, and rate limiters often call EVALSHA under the hood:

bash
valkey-cli INFO commandstats | grep -E 'cmdstat_(eval|evalsha|eval_ro|evalsha_ro|fcall|fcall_ro|script.load|function.load):'
valkey-cli FUNCTION LIST
valkey-cli INFO scriptingengines

Interpretation: command stats count since the last restart or CONFIG RESETSTAT, so sample across a full business cycle. Any non-zero calls, or any library in FUNCTION LIST, means a client depends on Lua. INFO scriptingengines shows engines_count, which is 0 on a Lua-less build.

bash
git clone --depth 1 --branch 9.1.3 https://github.com/valkey-io/valkey.git
cd valkey && make BUILD_TLS=yes BUILD_LUA=no

Interpretation: without an engine, EVAL and FUNCTION LOAD return an error that the scripting engine cannot be found. Build every node in a shard the same way, because a promoted Lua-less replica breaks every script. If you keep Lua, remove @scripting from users that do not need it.

In what order should you roll out these changes?

Each step can lock out a client the previous step missed, so this order keeps the default user working until every service has moved.

Valkey 9.1 hardening runbook

Eight steps; step 6 can lock out any client you did not inventory

  1. Patch to the current release

    9.1.3 carries the ACL, AOF, and TLS fixes above. Read valkey_version, not redis_version.

    valkey-cli INFO server | grep valkey_version
  2. Find who connects as the default user

    The addr and lib-name fields name the host and client library.

    valkey-cli CLIENT LIST USER default
  3. Write users to an ACL file

    Services plus replica, Sentinel, monitor, and admin users. Switching to aclfile needs one restart.

    valkey-cli ACL LOAD
  4. Prove each user with DRYRUN

    Test every command the service sends, including what its library sends on connect.

    valkey-cli ACL DRYRUN orders \ HSET orders:1 status paid
  5. Move services one at a time

    Deploy new credentials per service and read ACL LOG after each.

    valkey-cli ACL LOG 10
  6. Turn off the default user

    Only when CLIENT LIST USER default is empty. Save the change.

    valkey-cli ACL SETUSER default off resetpass valkey-cli ACL SAVE
  7. Add TLS beside TCP, then close TCP

    Both ports change at runtime. Move clients to the TLS port first.

    valkey-cli CONFIG SET tls-port 6380 valkey-cli CONFIG SET port 0
  8. Alert on certificates and denials

    Watch expiry seconds and the acl_access_denied counters.

    valkey-cli INFO tls valkey-cli INFO stats | grep acl_access_denied

Rollback point: until step 6, unmigrated clients still work as the default user. After it, an admin session can turn the default user back on with a password while you fix the missed client.

How do you debug NOPERM errors after hardening?

In the 9.1.3 source, a client receives one of four NOPERM messages, and only the first names anything: User orders has no permissions to run the 'flushall' command, No permissions to access a key, No permissions to access a channel, or No permissions to access database.

ACL LOG fills the gap. Each entry has a reason (command, key, channel, database, auth, or tls-cert), a context (toplevel, multi, lua, script, or module), the denied object, the username, and the client's details. Repeats within 60 seconds fold into one entry with a count. The log keeps 128 entries by default, and ACL LOG shows the 10 newest.

From a vague NOPERM to the exact key

Illustrative output, trimmed to the first seven fields of one ACL LOG entry

valkey-cli: admin session on vk-01
vk-01:6379> ACL LOG 1 1) 1) "count" 2) (integer) 37 3) "reason" 4) "key" 5) "context" 6) "toplevel" 7) "object" 8) "billing:8812" 9) "username" 10) "orders" 11) "age-seconds" 12) "4.2" 13) "client-info" 14) "id=912 addr=10.0.4.17:51122 ... db=0 ... user=orders"vk-01:6379> ACL DRYRUN orders GET billing:8812"User orders has no permissions to access the 'billing:8812' key"

Read the object field: the client only saw "No permissions to access a key". The log names the key and user, and count shows 37 denials folded into one entry.

bash
valkey-cli INFO stats | grep acl_access_denied      # auth, cmd, key, channel, tls_cert, db
valkey-cli ACL DRYRUN orders GET billing:8812       # full denial text, no side effects
valkey-cli ACL DRYRUN orders SELECT 3               # database access check
valkey-cli ACL LOG RESET                            # clear after the fix, then watch again

Interpretation: ACL DRYRUN returns OK or the full message. In 9.1.3 it checks key commands against the database your own session has selected, so SELECT the service's database first, or test SELECT directly.

The usual causes are few. Client libraries send HELLO, CLIENT SETINFO, SELECT, or INFO on connect, and -@dangerous removes INFO. Pub/Sub clients need channel patterns, because acl-pubsub-default is resetchannels. Scripts run with the caller's permissions, so a denial inside one shows context lua.

Frequently asked questions

Does Valkey 9.1 reject expired TLS certificates?

No. Valkey 9.1.x loads expired or not-yet-valid certificates at startup, on CONFIG SET, and on automatic reload, although the TLS documentation says loading fails. The check was reverted from 9.1 in pull request #3572. Clients and peers that verify the certificate still refuse the handshake, so alert on the expiry fields in INFO tls. The 9.2 release candidate source rejects them at load.

How do I disable Lua scripting in Valkey 9.1?

Build Valkey with make BUILD_LUA=no. Valkey 9.1 links Lua statically by default and loads it at startup, and no configuration directive turns it off. Before switching builds, check INFO commandstats for EVAL, EVALSHA, and FCALL calls and run FUNCTION LIST, because job queues and lock libraries often use scripts. Build every node in a shard the same way.

How do I restrict a Valkey user to one database?

On Valkey 9.1 or later, add a db= rule, for example ACL SETUSER orders db=0. A later db= rule replaces the list rather than adding to it. New connections still start in database 0, so set the database in the client's connection options. Run 9.1.2 or later, which closed MOVE and COPY bypasses of database rules.

Why does Valkey return NOPERM No permissions to access a key?

The user's key patterns do not cover a key the command touches, and the client message leaves the key name out. Run ACL LOG as an admin to see the key, the username, and the client address, or ACL DRYRUN with the same user and command to get the full message. Then widen the pattern or fix the key name.

Key takeaways

  • Check the running server, not the docs: without a config file it binds every interface, and the official Docker image compiles protected mode off.
  • Disable the default user and give each application, replica, Sentinel, and monitoring agent a minimal user on 9.1.3, with db= for database scoping.
  • Enable TLS for clients, replication, and the cluster bus, set tls-auto-reload-interval, and alert on INFO tls, because 9.1.x loads expired certificates.
  • Use valkey-ldap 1.1.1 for people, over LDAPS with a local break-glass admin.
  • Remove Lua with make BUILD_LUA=no only after an inventory, and debug denials with ACL LOG and ACL DRYRUN.

Harden your Valkey deployment with JusDB

JusDB's Valkey support team can review your configuration, ACL users, and TLS setup against this checklist, inventory the clients and scripts that depend on the default user or Lua, and plan the rollout order with you.

Bring your Valkey versions, topology (standalone, Sentinel, or cluster), current ACL LIST output with passwords removed, and how certificates are issued today. Your team approves every production change.

Share this article

Database engineering notes

Articles like this one, in your inbox. No spam, unsubscribe anytime.

JusDB Team

Official JusDB content team

Keep reading

Moving a Multi-Database Valkey Instance into a 9.x Cluster

Move a Valkey instance that uses SELECT 1 to 15 into a 9.x cluster: keep or remap databases, copy each one, verify counts per database, and keep a way back.

Redis18 minNov 10, 2026
Read

Valkey Keyspace Notifications in Production: Expired Events, hexpired and Cluster Mode

Run Valkey keyspace notifications in production: why expired and hexpired events lag the TTL, how to subscribe on every cluster node, and when a stream is safer.

Redis20 minNov 10, 2026
Read

Valkey GLIDE in Production: AZ-Affinity Reads and Migrating from Legacy Clients

Configure Valkey GLIDE AZ-affinity reads on servers and clients, learn what GLIDE 2.5.3 does not support, and migrate from redis-py, Jedis, ioredis, or go-redis one service at a time.

Redis20 minNov 10, 2026
Read