redis/redis
Module API
The C ABI exposed to shared libraries that extend Redis. Modules can register new commands, new data types, new ACL categories, configuration options, blocking commands, event hooks, and more.
This page is a developer-oriented overview. The implementation is documented in Modules. The full per-symbol reference is auto-generated by utils/generate-module-api-doc.rb from src/redismodule.h and published on redis.io.
A minimal module
#include "redismodule.h"
#include <string.h>
int helloCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
if (argc != 1) return RedisModule_WrongArity(ctx);
RedisModule_ReplyWithSimpleString(ctx, "world");
return REDISMODULE_OK;
}
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
if (RedisModule_Init(ctx, "hello", 1, REDISMODULE_APIVER_1) == REDISMODULE_ERR)
return REDISMODULE_ERR;
if (RedisModule_CreateCommand(ctx, "hello.world", helloCommand, "fast", 0, 0, 0)
== REDISMODULE_ERR) return REDISMODULE_ERR;
return REDISMODULE_OK;
}Build:
gcc -fPIC -shared -o hello.so hello.cLoad:
loadmodule /path/to/hello.so> HELLO.WORLD
"world"RedisModule_Init populates the function-pointer table inside redismodule.h. After it returns, every RedisModule_* symbol is callable.
Major API families
Commands and replies
int RedisModule_CreateCommand(RedisModuleCtx *ctx, const char *name,
RedisModuleCmdFunc cmdfunc,
const char *strflags,
int firstkey, int lastkey, int keystep);
void RedisModule_ReplyWithSimpleString(RedisModuleCtx *ctx, const char *msg);
void RedisModule_ReplyWithError(RedisModuleCtx *ctx, const char *err);
void RedisModule_ReplyWithLongLong(RedisModuleCtx *ctx, long long ll);
void RedisModule_ReplyWithDouble(RedisModuleCtx *ctx, double d);
void RedisModule_ReplyWithStringBuffer(RedisModuleCtx *ctx, const char *buf, size_t len);
void RedisModule_ReplyWithArray(RedisModuleCtx *ctx, long len);
void RedisModule_ReplyWithMap(RedisModuleCtx *ctx, long len); /* RESP3 */
void RedisModule_ReplyWithSet(RedisModuleCtx *ctx, long len); /* RESP3 */
void RedisModule_ReplyWithBool(RedisModuleCtx *ctx, int b); /* RESP3 */The strflags argument to CreateCommand is a space-separated list of flags such as write, readonly, denyoom, admin, pubsub, noscript, random, fast, loading, stale, no-cluster, no-monitor, no-slowlog, may-replicate, no-mandatory-keys. They map to the same CMD_* flags the core uses.
Strings and arguments
RedisModuleString *RedisModule_CreateString(RedisModuleCtx *ctx, const char *ptr, size_t len);
RedisModuleString *RedisModule_CreateStringFromLongLong(RedisModuleCtx *ctx, long long ll);
const char *RedisModule_StringPtrLen(const RedisModuleString *s, size_t *len);
int RedisModule_StringToLongLong(const RedisModuleString *s, long long *ll);
int RedisModule_StringToDouble(const RedisModuleString *s, double *d);
void RedisModule_FreeString(RedisModuleCtx *ctx, RedisModuleString *str);RedisModuleString is a typed alias for robj* — strings, integers, or doubles wrapped in the standard value object. The opaque type is meant to keep modules forward-compatible if internals change.
Keys and values
RedisModuleKey *RedisModule_OpenKey(RedisModuleCtx *ctx, RedisModuleString *keyname, int mode);
void RedisModule_CloseKey(RedisModuleKey *kp);
int RedisModule_KeyType(RedisModuleKey *key);
int RedisModule_DeleteKey(RedisModuleKey *key);
int RedisModule_ValueLength(RedisModuleKey *key);
/* Type-specific */
int RedisModule_StringSet(RedisModuleKey *key, RedisModuleString *str);
int RedisModule_ListPush(RedisModuleKey *key, int where, RedisModuleString *ele);
int RedisModule_ZsetAdd(RedisModuleKey *key, double score, RedisModuleString *ele, int *flagsptr);
int RedisModule_HashSet(RedisModuleKey *key, int flags, ...);
int RedisModule_StreamAdd(RedisModuleKey *key, int flags, RedisModuleStreamID *id,
RedisModuleString **field_values, int64_t numfields);Modes are REDISMODULE_READ, REDISMODULE_WRITE, REDISMODULE_OPEN_KEY_NOEFFECTS (don't update LRU/freq), and REDISMODULE_OPEN_KEY_NONOTIFY (don't fire keyspace notifications).
Custom data types
RedisModuleType *RedisModule_CreateDataType(RedisModuleCtx *ctx, const char *name,
int encver, RedisModuleTypeMethods *typemethods);name must be a 9-character ASCII string; encver is the type's data-format version. typemethods provides:
rdb_load,rdb_save— RDB serialisation.aof_rewrite— AOF rewrite.mem_usage— forMEMORY USAGE.digest— forDEBUG DIGEST.free— destructor.copy— forCOPY.defrag— for active defragmentation.unlink— async-delete callback.aux_save/aux_load— non-key data (e.g. global indices).
Calling other commands
RedisModuleCallReply *RedisModule_Call(RedisModuleCtx *ctx, const char *cmdname,
const char *fmt, ...);The fmt is a tiny format string: s for RedisModuleString*, c for const char*, b for binary buffer, l for long long, v for vector of strings, ! for replicate.
RedisModuleCallReply *r = RedisModule_Call(ctx, "INCR", "s!", key);
long long n = RedisModule_CallReplyInteger(r);
RedisModule_FreeCallReply(r);The trailing ! flag tells the server to also propagate the call (write to AOF / replicate to replicas).
Blocking commands
RedisModuleBlockedClient *RedisModule_BlockClient(RedisModuleCtx *ctx,
RedisModuleCmdFunc reply_callback,
RedisModuleCmdFunc timeout_callback,
void (*free_privdata)(RedisModuleCtx*, void*),
long long timeout_ms);
int RedisModule_UnblockClient(RedisModuleBlockedClient *bc, void *privdata);
int RedisModule_AbortBlock(RedisModuleBlockedClient *bc);The blocking command returns from its handler immediately after BlockClient. Some other code path (a thread, a timer, an event hook) calls UnblockClient later, which schedules the reply_callback on the main thread to deliver the reply.
Threads
RedisModuleCtx *RedisModule_GetThreadSafeContext(RedisModuleBlockedClient *bc);
void RedisModule_FreeThreadSafeContext(RedisModuleCtx *ctx);
void RedisModule_ThreadSafeContextLock(RedisModuleCtx *ctx);
void RedisModule_ThreadSafeContextUnlock(RedisModuleCtx *ctx);A thread-safe context is the entry token a worker thread uses to mutate the dataset. Acquiring the lock acquires the global GIL — only one thread (main or module) executes against the dataset at a time.
Events
int RedisModule_SubscribeToServerEvent(RedisModuleCtx *ctx,
RedisModuleEvent event, RedisModuleEventCallback callback);Events include RedisModuleEvent_ReplicationRoleChanged, RedisModuleEvent_Persistence, RedisModuleEvent_FlushDB, RedisModuleEvent_Loading, RedisModuleEvent_ClientChange, RedisModuleEvent_Shutdown, RedisModuleEvent_ReplicaChange, RedisModuleEvent_CronLoop, RedisModuleEvent_ModuleChange, RedisModuleEvent_LoadingProgress, RedisModuleEvent_SwapDB, RedisModuleEvent_ReplBackup, RedisModuleEvent_ForkChild, RedisModuleEvent_Eviction, RedisModuleEvent_Key, …
ACL
int RedisModule_AddACLCategory(RedisModuleCtx *ctx, const char *name);
int RedisModule_SetCommandACLCategories(RedisModuleCommand *cmd, const char *categories);
int RedisModule_RegisterAuthCallback(RedisModuleCtx *ctx, RedisModuleAuthCallback cb);Configuration
int RedisModule_RegisterStringConfig(RedisModuleCtx *ctx, const char *name,
const char *default_val, unsigned int flags,
RedisModuleConfigGetStringFunc getfn, RedisModuleConfigSetStringFunc setfn,
RedisModuleConfigApplyFunc applyfn, void *privdata);
/* plus Bool / Numeric / Enum variants */Module configs surface in CONFIG GET/CONFIG SET as <modulename>.<name>. They persist in redis.conf automatically when CONFIG REWRITE is called.
Cluster messaging
int RedisModule_RegisterClusterMessageReceiver(RedisModuleCtx *ctx,
uint8_t type, RedisModuleClusterMessageReceiver callback);
int RedisModule_SendClusterMessage(RedisModuleCtx *ctx, const char *target_id,
uint8_t type, const char *msg, uint32_t len);Lets a module piggyback on the cluster bus to talk to peer instances of itself.
Notifications
int RedisModule_NotifyKeyspaceEvent(RedisModuleCtx *ctx, int type,
const char *event, RedisModuleString *key);
int RedisModule_SubscribeToKeyspaceEvents(RedisModuleCtx *ctx, int types,
RedisModuleNotificationFunc callback);API versioning
The header defines REDISMODULE_APIVER_1. New API symbols are added at the end of the function-pointer table, so older modules built against APIVER_1 continue to work — they simply don't see the newer symbols. Removing or renaming a symbol is a breaking change and would require a new APIVER.
Where to look in the implementation
Every API symbol is a wrapper in src/module.c. The file is organised by API family — search for Hash API, Stream API, Cluster API, Auth API, etc. for a coherent view of one area. The function-pointer table that gets filled by RedisModule_Init is RedisModule_GetApi / moduleRegisterCoreAPI.
Related pages
- Modules — load order, threading, sample modules.
- redis-server —
main()callsmoduleInitModulesSystem()at startup. - Persistence — module data types appear in RDB.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.