Open-Source Wikis

/

Redis

/

API

/

Module API

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.c

Load:

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 — for MEMORY USAGE.
  • digest — for DEBUG DIGEST.
  • free — destructor.
  • copy — for COPY.
  • 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.

  • Modules — load order, threading, sample modules.
  • redis-servermain() calls moduleInitModulesSystem() 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.

Module API – Redis wiki | Factory