ClientList() on a connection with many thousands of clients causes a large, avoidable memory spike
Description
ClientList() returns a *StringCmd — the entire CLIENT LIST reply as one fully-materialized string. Against a server with a large number of connected clients, this reply can be very large, and there's no way to consume it incrementally; the whole thing must be resident in memory (and typically gets copied again immediately afterward, e.g. via strings.Split, to do anything useful with it).
Observed behavior
Testing with an increasing number of connected clients showed memory usage during a single ClientList() call scaling roughly linearly with connection count, reaching multi-GB territory once the connection count climbs into the tens of thousands — realistic for a busy, long-lived server. This is on top of whatever additional copies application code makes when splitting/parsing the raw string.
Steps to reproduce
- Start a Redis server and open several thousand to tens of thousands of client connections against it.
- From a separate connection, call
client.ClientList(ctx). - Observe memory usage before/after the call.
Suggested fix
A streaming variant that reads the reply incrementally off the socket and yields one client record at a time (e.g. via a callback or iterator), bounding peak memory to roughly the read-buffer size rather than the total client count. This would also help any application that only needs a subset of the result (e.g. filtering by client type) avoid materializing the full reply at all.
Related
Believe the same underlying limitation exists at the hiredis level for the C/Python ecosystem, and in the redis Rust crate — filing there too for visibility, since the root cause (bulk-string replies aren't streamable) seems shared across client implementations rather than being go-redis-specific.
Source: redis/go-redis