How Redis Functions differ from Lua scripts — functions persist across restarts in RDB/AOF. Function libraries, the shebang declaration, registering multiple functions in one library, replication semantics, and migration from EVALSHA.
A-3 — Redis Functions: Persistent Stored Procedures
Who this module is for: You use
EVALSHAto call Lua scripts by SHA digest and manage script lifecycle manually — re-loading scripts after restarts, distributing SHAs across application instances. Redis Functions (introduced in Redis 7.0) solve exactly these pain points. This module covers the Functions model, how it differs from EVAL/EVALSHA, and when to migrate.
The Problem with EVALSHA
SCRIPT LOAD + EVALSHA works, but has operational friction:
-
Scripts do not persist — they live in a volatile in-memory cache. Redis restart = all scripts gone. Your application must re-load scripts on every startup (or handle
NOSCRIPTerrors). -
SHA distribution — every application instance needs to know the SHA digest of every script. If you deploy a new script version, every instance must get the new SHA simultaneously.
-
No introspection — Redis cannot list what scripts are loaded.
SCRIPT EXISTS shatells you if a specific SHA is loaded, but you cannot ask "what scripts are in the cache?" -
No namespace — all scripts share one global namespace (the SHA cache). No way to group related scripts.
Redis Functions solve all four problems.
What Redis Functions Are
Redis Functions (Redis 7.0+) are named, persistent, typed server-side functions. They are stored in Redis like data — persisted to RDB/AOF, replicated to replicas, and survive restarts.
Key differences from EVAL scripts:
| Feature | EVAL / EVALSHA | Redis Functions |
|---|---|---|
| Persistence | Volatile (cache) | Durable (RDB + AOF) |
| Naming | SHA digest only | Named (library + function name) |
| Discovery | SCRIPT EXISTS sha | FUNCTION LIST |
| Engine | Lua only | Lua (+ future engines) |
| Replication | Command replicated | Library replicated |
| Namespace | Global | Per-library |
Function Library Anatomy
Functions are grouped into libraries. A library is a Lua module with a #! shebang declaring the engine and library name, plus one or more redis.register_function() calls:
Loading a Library
FUNCTION LOAD [REPLACE] function-code
In Node.js:
Calling Functions: FCALL
Managing Libraries
Function Flags
Register functions with flags to declare their behaviour:
Available flags:
no-writes— function is read-only; can be called withFCALL_ROand executed on replicasallow-stale— allow calling on replicas even when replica is in stale stateno-cluster— function cannot run in Cluster modeallow-busy— allow calling duringlua-time-limitexceeded state (use with care)
no-writes is the most important: it enables calling the function via FCALL_RO on read replicas, reducing primary load.
Persistence and Replication
Unlike EVAL scripts, Functions are part of the Redis dataset:
- Stored in RDB snapshots (survives restart)
- Logged to AOF (survives restart with AOF persistence)
- Replicated to all replicas automatically when a library is loaded or deleted
When a replica becomes a primary (after Sentinel failover), its function library is already up-to-date — no manual re-loading required.
Deployment Workflow
Initial Deploy
Update Existing Library
FUNCTION LOAD REPLACE atomically replaces the old library with the new one. Inflight calls to old function names complete normally; new calls after the replacement use the new code.
Multi-Region / Multi-Instance
Since Functions are replicated to all replicas, you only need to load to the primary. All replicas receive the library automatically.
For multiple independent Redis instances (not replicas), load to each:
Backup and Restore
EVAL vs Functions: When to Use Which
| Scenario | Recommendation |
|---|---|
| Redis < 7.0 | EVAL / EVALSHA (no choice) |
| Redis >= 7.0, new project | Functions — better operational model |
| Quick one-off script | EVAL — no need to manage a library |
| Production atomic operations | Functions — persistence, naming, discoverability |
| Cross-service shared logic | Functions — load once, call by name |
| Frequent deployments with script changes | Functions with REPLACE — atomic updates |
Summary
- Redis Functions (7.0+) are persistent, named, replicated server-side functions — the production-grade evolution of EVAL
- Libraries group related functions with a
#!lua name=libnameheader +redis.register_function()calls FUNCTION LOADloads a library (survives restart);FCALLcalls a function by nameFUNCTION LOAD REPLACEatomically updates an existing library — zero-downtime function updatesFCALL_RO+no-writesflag allows read-only functions to run on replicas, reducing primary load- Functions are replicated to all replicas automatically — no manual re-loading after failover
FUNCTION LIST,FUNCTION DUMP/RESTOREfor discovery and backup- Use Functions for production atomic operations in Redis 7.0+; use EVAL for quick scripts or older Redis versions
Next: A-4 — Redlock: The Algorithm, Its Guarantees, and Its Critics — the multi-instance distributed lock, what it guarantees under bounded clock drift, Martin Kleppmann's critique, and when to use it versus alternatives.
What is the most significant operational difference between using the older EVALSHA approach and using Redis Functions (introduced in Redis 7.0)?
A developer has written a Redis Function that analyzes a user's recent activity from several sets and lists, and returns a computed "engagement score." The function never writes or modifies any data in Redis. How should the developer register this function to optimize performance in a Redis Cluster with read replicas?
An engineering team needs to update an existing Redis Function library named user_utils with a critical bug fix. They want to ensure zero downtime and avoid any NOSCRIPT style errors during the deployment. Which command should they use?
Test your knowledge with more question sets
Sign in to access a wider variety of questions and get notified when new practice sets are added to this module.
Sign in & RegisterDiscussion
0Join the discussion