Inside Redis: How Its Single‑Threaded Event Loop Works

This article walks through Redis’s annotated source code to explain how its single‑threaded architecture initializes the server, loads configuration and data, and continuously processes file and time events within a while‑loop, revealing why Redis achieves high performance without spawning additional worker threads.

IT Architects Alliance
IT Architects Alliance
IT Architects Alliance
Inside Redis: How Its Single‑Threaded Event Loop Works

Overview

Redis is a single‑threaded in‑memory database. This article examines its single‑threaded model by walking through the annotated source of Redis 3.0 (the repository https://github.com/huangz1990/redis-3.0-annotated).

Main Function (main)

In redis.c the main function performs several initialization steps before entering the event loop:

Detect whether Redis is started in Sentinel mode.

Initialize server configuration (LRU time, RDB conditions, commands, client output buffers, slow‑log, etc.).

Load configuration files and startup commands.

Initialize server data structures, create time events, open TCP listening socket, set up the I/O multiplexer, initialise Lua, slow‑log and the only background thread used for persistence.

Load data from AOF or RDB.

Validate the maxmemory setting.

Enter the event‑processing loop (the core of Redis work).

When the loop ends, stop the server and return 0.

Event Loop Core (aeMain)

The loop is implemented in aeMain:

/*
 * Event loop main function
 */
void aeMain(aeEventLoop *eventLoop) {
    eventLoop->stop = 0;
    while (!eventLoop->stop) {
        if (eventLoop->beforesleep != NULL)
            eventLoop->beforesleep(eventLoop);
        aeProcessEvents(eventLoop, AE_ALL_EVENTS);
    }
}

The loop runs until eventLoop->stop becomes true, optionally invoking a pre‑sleep callback, then delegating all work to aeProcessEvents.

Processing Events (aeProcessEvents)

aeProcessEvents

handles two kinds of events: time events and file (socket) events. Its main steps are:

Determine the nearest time event and compute the timeout for select() (or the platform‑specific poller).

If no time events are pending, decide whether to block based on the AE_DONT_WAIT flag.

Call the underlying poller ( aeApiPoll) with the calculated timeout to obtain ready file descriptors.

Iterate over the ready descriptors, dispatch read and/or write callbacks while ensuring a descriptor is processed only once.

After file events, process any due time events via processTimeEvents.

Return the total number of processed events.

int aeProcessEvents(aeEventLoop *eventLoop, int flags) {
    int processed = 0, numevents;
    /* Nothing to do? return ASAP */
    if (!(flags & AE_TIME_EVENTS) && !(flags & AE_FILE_EVENTS))
        return 0;
    /* ... compute timeout ... */
    numevents = aeApiPoll(eventLoop, tvp);
    for (int j = 0; j < numevents; j++) {
        aeFileEvent *fe = &eventLoop->events[eventLoop->fired[j].fd];
        int mask = eventLoop->fired[j].mask;
        int fd = eventLoop->fired[j].fd;
        int rfired = 0;
        if (fe->mask & mask & AE_READABLE) {
            rfired = 1;
            fe->rfileProc(eventLoop, fd, fe->clientData, mask);
        }
        if (fe->mask & mask & AE_WRITABLE) {
            if (!rfired || fe->wfileProc != fe->rfileProc)
                fe->wfileProc(eventLoop, fd, fe->clientData, mask);
        }
        processed++;
    }
    if (flags & AE_TIME_EVENTS)
        processed += processTimeEvents(eventLoop);
    return processed;
}

Conclusion

From the source perspective, Redis never creates additional worker threads after the main function; all client I/O is handled by a single thread using an event‑driven loop based on select() / epoll() (the aeApiPoll abstraction). Time events are integrated into the same loop, making Redis’s single‑threaded model both simple and highly performant.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Backend DevelopmentredisCevent loopSingle Thread
IT Architects Alliance
Written by

IT Architects Alliance

Discussion and exchange on system, internet, large‑scale distributed, high‑availability, and high‑performance architectures, as well as big data, machine learning, AI, and architecture adjustments with internet technologies. Includes real‑world large‑scale architecture case studies. Open to architects who have ideas and enjoy sharing.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.