Connection Multiplexing with redisx (Experimental)

Note: The redisx package contains experimental features. Its API may change or be removed in future versions.

The redisx.ConnMux provides a way to multiplex commands from multiple logical connections (goroutines) onto a single underlying network connection to Redis. This can reduce the overhead of creating and managing a large number of TCP connections in highly concurrent applications.

When to Consider ConnMux

ConnMux is designed for scenarios where many goroutines are executing simple, stateless Redis commands (like GET, SET, INCR). In such cases, the overhead of a large connection pool (redis.Pool) might be undesirable. ConnMux allows these goroutines to share a single connection, potentially improving resource utilization.

Usage

First, import the redisx package:

import "github.com/gomodule/redigo/redisx"

Next, create a ConnMux by wrapping an existing redis.Conn:

// Create a standard Redis connection
c, err := redis.Dial("tcp", ":6379")
if err != nil {
    // handle error
}

// Create a new connection multiplexer
mux := redisx.NewConnMux(c)
defer mux.Close() // This closes the underlying connection

Then, in your goroutines, get a logical connection from the multiplexer:

func worker(mux *redisx.ConnMux, wg *sync.WaitGroup) {
    defer wg.Done()

    // Get a multiplexed connection
    conn := mux.Get()
    defer conn.Close()

    // Use the connection as usual
    reply, err := conn.Do("INCR", "counter")
    // ...
}

// In main:
var wg sync.WaitGroup
for i := 0; i < 100; i++ {
    wg.Add(1)
    go worker(mux, &wg)
}
wg.Wait()

Critical Limitations

ConnMux works by interleaving commands from different logical connections. Because all commands are sent on the same underlying connection, any command that alters the state of the connection is not supported. Using such commands will lead to unpredictable behavior and errors.

Unsupported commands include, but are not limited to:

  • Transactions: MULTI, EXEC, DISCARD, WATCH, UNWATCH
  • Pub/Sub: SUBSCRIBE, PSUBSCRIBE
  • Monitoring: MONITOR

Attempting to use these commands on a multiplexed connection will return an error.

ConnMux vs. Pool

Feature redis.Pool redisx.ConnMux (Experimental)
Connections Manages a pool of real TCP connections. Manages logical connections over one TCP connection.
Use Case General purpose, robust, supports all commands. High-concurrency, stateless commands.
Supported Cmds All Redis commands. Only stateless commands.
Recommendation Recommended for most applications. Niche use cases requiring minimal connection overhead.

For the vast majority of applications, redis.Pool is the recommended choice for managing concurrent Redis operations. It is more robust and supports the full range of Redis features.