How does a Redis 7 server-side function library get onto every node of a deployment — what happens on FUNCTION LOAD with respect to replicas, snapshots and restarts, and which commands would you use to inspect or move the installed libraries?
answer
- FUNCTION LOAD replicates + hits AOF + lives in RDB
- Promoted replica already has libraries (no NOSCRIPT)
- Cluster: load on every primary, seed new nodes
- LIST WITHCODE = drift check; STATS = what's running
- DUMP/RESTORE with APPEND|FLUSH|REPLACE
basics
~20 sFUNCTION LOAD on a primary is replicated to its replicas and written to the AOF, and libraries are serialized into RDB, so they survive restart and failover. In Cluster you must load on every shard's primary. Inspect with FUNCTION LIST/STATS; move with FUNCTION DUMP/RESTORE.
solid answer
~50 s`FUNCTION LOAD` is a write to server state, so it propagates: the primary sends it to its replicas, it is recorded in the AOF, and libraries are serialized into RDB snapshots. Consequences: - a restart from RDB or AOF brings the libraries back — no client action needed; - a promoted replica already has them, so `FCALL` keeps working after failover (unlike EVALSHA, whose script cache is empty on the new primary); - a replica synced by full RDB transfer receives them with the snapshot. In **Cluster** each shard is an independent replication group, so a library must be loaded on **every primary** — a deployment loop, not one command. Nodes joining later need it too. Inspection and movement: `FUNCTION LIST [LIBRARYNAME x] [WITHCODE]` to inventory and detect drift, `FUNCTION STATS` for the running function, `FUNCTION DUMP` → `FUNCTION RESTORE <payload> [FLUSH|APPEND|REPLACE]` to copy the whole set to another server, `FUNCTION DELETE`/`FUNCTION FLUSH` to remove.
code
text · 9 lines# load on each primary
for node in $(redis-cli --cluster call 127.0.0.1:7000 CLUSTER MYID >/dev/null; \
redis-cli -h 127.0.0.1 -p 7000 CLUSTER NODES | awk '/master/{print $2}' | cut -d@ -f1); do
redis-cli -h ${node%:*} -p ${node#*:} -x FUNCTION LOAD REPLACE < inventory.lua
done
# verify no drift
redis-cli -h host1 FUNCTION LIST LIBRARYNAME inventory WITHCODE | shasum
redis-cli -h host2 FUNCTION LIST LIBRARYNAME inventory WITHCODE | shasumgo deeper
Know that loading a library is persistent and replicated, unlike an EVAL script, so clients do not reload it.
Explain replication to replicas, presence in RDB/AOF, survival across restart, and the FUNCTION LIST/DELETE/FLUSH management commands.
Own the deployment: per-shard loading in Cluster, drift detection with LIST WITHCODE, DUMP/RESTORE for seeding, idempotent REPLACE in pipelines, and the failover contrast with NOSCRIPT.
Treat server-side code as a deployable artifact with the same rigor as migrations: versioning strategy, rollback path, audit of deployed vs repository code, and the managed-service constraints you are accepting.
## Loading is a state change, not a connection setting The mental shift from EVAL is this: `SCRIPT LOAD` only touched an in-memory, per-node cache that no one persisted; `FUNCTION LOAD` changes durable server state. Redis treats a library like data. Concretely, when you run `FUNCTION LOAD [REPLACE] <code>` on a primary: 1. The code is parsed, the shebang read, the library instantiated and its functions registered. Any error here aborts the whole load — a library is all-or-nothing. 2. The command is **propagated to replicas** and to the AOF, so the replicas load the same library. 3. From then on, the library is part of what gets serialized into the **RDB** file. ## What that buys you at restart and failover - **Restart**: loading the RDB (or replaying the AOF) restores libraries. Your application does not need a bootstrap step on reconnect. - **Full resync**: when a replica does a full synchronization, it loads the primary's RDB, which contains the libraries. - **Failover**: the promoted replica already has them. This is the sharp contrast with `EVALSHA`, where the new primary's script cache is typically cold and the first `EVALSHA` returns `NOSCRIPT` until some client reloads the source. ## Cluster: one load per shard Redis Cluster is a set of independent replication groups. A library loaded on shard A's primary reaches only shard A's replicas. Deployment therefore means iterating over every primary and loading there (`redis-cli --cluster call` style loops, or a config-management step). Two operational consequences: - **Drift is possible.** One shard can end up on an old library version if a load partially failed. `FUNCTION LIST WITHCODE` on every node, hashed and compared, is the drift check. - **New nodes need seeding.** A node added during a reshard has no libraries; add the load to your node-provisioning procedure, or use `FUNCTION DUMP`/`RESTORE` from a known-good node. ## The management surface - `FUNCTION LIST [LIBRARYNAME <name>] [WITHCODE]` — libraries, engine, registered functions and their flags; `WITHCODE` returns the source, which makes the server self-describing and lets you diff deployed code against your repository. - `FUNCTION STATS` — whether a function is running right now (its name and how long it has been executing) plus per-engine counts of libraries and functions. This is your first stop when clients report `BUSY`. - `FUNCTION DUMP` — a binary payload of **all** libraries on the node. `FUNCTION RESTORE <payload> [APPEND|FLUSH|REPLACE]` loads it elsewhere: `APPEND` (default) fails on name collisions, `FLUSH` clears existing libraries first, `REPLACE` overwrites colliding ones. This is the supported way to clone a node's function set, including into a fresh environment. - `FUNCTION DELETE <libname>` and `FUNCTION FLUSH [ASYNC|SYNC]` — removal; both replicate, so a `FUNCTION FLUSH` on a primary wipes the replicas too. Treat it with the same care as `FLUSHALL` for code. - `FUNCTION KILL` — terminate a currently running function, only if it has performed no write. ## Deployment patterns Because the library is versionless from Redis's point of view, versioning is a naming convention you impose. Two common approaches: 1. **In-place upgrade**: `FUNCTION LOAD REPLACE` the same library name. Simple, but the swap is instantaneous and old and new callers cannot coexist — only safe when the function contract is unchanged. 2. **Side-by-side**: load `orders_v2` alongside `orders_v1` with distinct function names, shift application traffic, then `FUNCTION DELETE orders_v1`. This gives you a rollback that is just a config flip, at the cost of a name-management convention. Note function names are unique **server-wide**, so v2's functions must be named distinctly. Whichever you choose, the load belongs in your deployment pipeline next to schema migrations, with the source in version control. `FUNCTION LIST WITHCODE` then serves as the audit that the fleet matches the repo. ## Things that bite - Loading on a **replica** directly is refused (replicas are read-only); always load on primaries. - `FUNCTION LOAD` without `REPLACE` errors on an existing name — a re-run of a deployment script must use `REPLACE` or tolerate that error. - A `FUNCTION FLUSH` propagates; it is not a local cleanup. - Managed Redis services and proxies may restrict or intercept `FUNCTION` subcommands; verify before designing around them. - RDB files containing libraries are only loadable by a version that understands them, so a downgrade below 7.0 will not read them.
- Your deployment script runs FUNCTION LOAD on every primary but one shard's load failed. How do you detect and repair that?Detect it by running FUNCTION LIST LIBRARYNAME <lib> WITHCODE on every primary and comparing a hash of the output, or by checking the registered function names and flags. Repair by re-running FUNCTION LOAD REPLACE on the lagging node, or FUNCTION DUMP from a known-good node and FUNCTION RESTORE … REPLACE on the target. Make the deployment step idempotent by always using REPLACE.
- Is it safe to run FUNCTION FLUSH on a primary to clean up experiments?Not casually. FUNCTION FLUSH removes every library on the node and, like other state changes, propagates to replicas, so it wipes the whole replication group's server-side code. Use FUNCTION DELETE for a specific library, and keep FLUSH for a controlled reprovision where you will reload from source afterwards.
saying these in an interview costs you the question
- Thinking clients must load libraries on connect the way they warm the EVALSHA script cache
- Loading on one cluster node and assuming the whole cluster has it
- Expecting a promoted replica to lose its libraries the way it loses the script cache
- Believing FUNCTION FLUSH is a node-local cleanup
- Treating FUNCTION LOAD as idempotent without REPLACE