redis/redis
Modules
Active contributors: antirez, Itamar Haber, Yossi Gottlieb, Meir Shpilraien, Oran Agra, debing.sun.
Purpose
The Module API lets shared libraries register new commands, data types, ACL categories, configuration options, blocking commands, event hooks, cluster messages, key-space functions, and more — without modifying the Redis core. A module is a .so (or .dylib) file loaded with loadmodule <path> (in redis.conf) or MODULE LOAD <path> at runtime.
Source layout
| File | Role |
|---|---|
src/module.c |
The implementation. 15,743 lines — the largest file in the repo. Every RedisModule_* exported symbol lives here. |
src/redismodule.h |
The public C header that modules #include to call into the API. |
src/modules/ |
In-tree sample modules (helloworld.c, hellotype.c, helloblock.c, hellocluster.c, hellodict.c, hellohook.c, hellotimer.c, helloacl.c). |
modules/ |
Top-level optional bundle of upstream modules (redisbloom, redisearch, redisjson, redistimeseries, vector-sets). Built with BUILD_WITH_MODULES=yes. |
The header uses a clever pattern: RedisModule_* symbols are function pointers that redismodule.h declares as extern. The module's RedisModule_OnLoad calls RedisModule_Init first, which fills those pointers from the running server. After Init, the rest of the API is callable.
This indirection means:
- Module compile dependencies are minimal — only
redismodule.hneeds to be present. - Multiple Redis versions can host the same module if the API surface is forward-compatible.
- Modules don't link against
redis-server; they receive the function pointers at runtime.
Loading and lifetime
sequenceDiagram
participant Server
participant Module as module.so
Server->>Module: dlopen(path)
Server->>Module: dlsym("RedisModule_OnLoad")
Server->>Module: RedisModule_OnLoad(ctx, argv, argc)
Module->>Server: RedisModule_Init(ctx, name, ver, REDISMODULE_APIVER_1)
Module->>Server: RedisModule_CreateCommand(...)
Module->>Server: RedisModule_CreateDataType(...)
Module->>Server: RedisModule_RegisterInfoFunc / SubscribeToServerEvent / ...
Note over Server,Module: Module is now live
Server->>Module: command callbacks
Server->>Module: RedisModule_OnUnload(ctx) (when MODULE UNLOAD)MODULE LIST shows loaded modules, their versions, and arguments. MODULE UNLOAD <name> is supported only if the module declared itself unloadable (some types don't support unload because data of that type would be orphaned).
What modules can register
| API family | Description |
|---|---|
| Commands | RedisModule_CreateCommand, RedisModule_CommandFilter*. |
| Data types | RedisModule_CreateDataType with RDB save/load, AOF rewrite, digest, free, copy callbacks. |
| ACL categories | RedisModule_AddACLCategory lets a module declare a new permission group. |
| Configuration | RedisModule_RegisterStringConfig, RegisterBoolConfig, etc. Module configs appear in CONFIG GET/SET. |
| Blocking commands | RedisModule_BlockClient, UnblockClient, IsBlockedReplyRequest. |
| Threading | ThreadSafeContext* — start a thread, lock the GIL, mutate the dataset, unlock. |
| Event hooks | RedisModule_SubscribeToServerEvent for replication, persistence, client connect/disconnect, eviction, etc. |
| Cluster messages | RedisModule_RegisterClusterMessageReceiver for arbitrary inter-node messaging. |
| Key-space notifications | RedisModule_SubscribeToKeyspaceEvents. |
| Module timers | RedisModule_CreateTimer with millisecond resolution. |
| Pub/Sub | RedisModule_PublishMessage, RedisModule_SubscribeToChannel. |
| Streams | RedisModule_StreamAdd, StreamRead, etc. — first-class stream APIs that mirror XADD/XREAD. |
| Replication | RedisModule_Replicate to propagate commands. |
| Lua/script integration | RedisModule_AddScriptableLuaCommand (limited). |
| Auth | RedisModule_RegisterAuthCallback for custom authentication providers. |
| Info | RedisModule_RegisterInfoFunc adds a section to INFO. |
The full list is the table of contents at the top of src/redismodule.h.
Data types
A module type is registered with a type id — a 9-character ASCII string broken into "name" (8 bytes) + "version" (1 byte). The type id is written into RDB so the loader knows which module to delegate to. If a module is unloaded but its data is still in memory or on disk, the loader refuses to start until the module is reloaded.
Each type provides callbacks:
rdb_saveandrdb_loadfor persistence.aof_rewritefor AOF rewriting.digestsoDEBUG DIGESTreturns a deterministic hash.freefor value destruction.copyforCOPY,MOVE, etc.mem_usageforMEMORY USAGE.defragfor active defragmentation.unlinkfor asynchronous deletion.
This is how redisbloom, redisearch, redisjson, redistimeseries, and the in-tree vector-sets integrate with persistence and replication.
Threading
A module can run code on its own threads with RedisModule_GetThreadSafeContext + RedisModule_ThreadSafeContextLock / Unlock. The lock is the global Redis GIL — only one thread (main or module) executes against the dataset at a time.
Common pattern:
RedisModuleCtx *ctx = RedisModule_GetThreadSafeContext(NULL);
pthread_t tid;
pthread_create(&tid, NULL, my_worker, ctx);
RedisModule_FreeThreadSafeContext(ctx); /* freed in worker */
void *my_worker(void *arg) {
RedisModuleCtx *ctx = arg;
/* do non-Redis work */
RedisModule_ThreadSafeContextLock(ctx);
/* mutate dataset via RedisModule_Call etc */
RedisModule_ThreadSafeContextUnlock(ctx);
RedisModule_FreeThreadSafeContext(ctx);
return NULL;
}The blocking-command pattern is similar but inverted: the command handler returns immediately after calling RedisModule_BlockClient, then a background thread completes the work and calls RedisModule_UnblockClient to deliver the reply.
Sample modules in src/modules/
| File | Demonstrates |
|---|---|
helloworld.c |
Basic command registration, replies, integer/string arguments. |
hellotype.c |
A custom data type with RDB/AOF/digest callbacks. |
helloblock.c |
Blocking commands using a background thread. |
hellocluster.c |
Cluster-bus messaging. |
hellodict.c |
A non-trivial value type built on the dict primitive. |
hellohook.c |
Event hooks. |
hellotimer.c |
Module timers. |
helloacl.c |
Custom ACL categories. |
Bundled modules in modules/
Built only with BUILD_WITH_MODULES=yes:
modules/vector-sets/— HNSW-backed vector index. Compiled directly intoredis-server(not as a separate.so) when SVE/atomics are available.modules/redisbloom/,modules/redisearch/,modules/redisjson/,modules/redistimeseries/— stub directories whose Makefiles fetch the upstream source and build it. The result is a.sonext toredis-server.
Where to start modifying
- Add an API symbol — declare it in
src/redismodule.h, implement it insrc/module.c(find the appropriate section), bump the API version macro if the change is breaking. - Add an event — extend
RedisModuleEventinredismodule.h, fire it from the right place in core (e.g.replicationFeedReplicasfor a replication event). - Improve a module's debugging —
MODULEINFO,MODULE LIST, and the per-moduleINFOsection all dispatch intomodule.ccallbacks.
Related pages
- redis-server — module load order is in
main(). - Persistence — module data appears in RDB.
- Cluster — module messages travel on the cluster bus.
- Module API reference — a higher-level walkthrough.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.