{
  "schema_version": 2,
  "id": "develop/reference/clients",
  "title": "Redis client handling",
  "url": "https://redis.io/docs/latest/develop/reference/clients/",
  "summary": "How the Redis server manages client connections",
  "aliases": [
    "/reference/clients/"
  ],
  "tags": [
    "docs",
    "develop",
    "stack",
    "oss",
    "rs",
    "rc",
    "oss",
    "kubernetes",
    "clients"
  ],
  "last_updated": "2026-09-11T15:49:27+01:00",
  "page_type": "content",
  "content_hash": "70877070c3637ce0f43a0e1384832363ecdea0607c86413b63f48091bbf7c82f",
  "sections": [
    {
      "id": "overview",
      "title": "Overview",
      "role": "overview",
      "text": "This document provides information about how Redis handles clients at the network layer level: connections, timeouts, buffers, and other similar topics are covered here.\n\nThe information contained in this document is **only applicable to Redis version 2.6 or greater**."
    },
    {
      "id": "accepting-client-connections",
      "title": "Accepting Client Connections",
      "role": "content",
      "text": "Redis accepts clients connections on the configured TCP port and on the Unix socket if enabled. When a new client connection is accepted the following operations are performed:\n\n* The client socket is put in the non-blocking state since Redis uses multiplexing and non-blocking I/O.\n* The `TCP_NODELAY` option is set in order to ensure that there are no delays to the connection.\n* A *readable* file event is created so that Redis is able to collect the client queries as soon as new data is available to read on the socket.\n\nAfter the client is initialized, Redis checks if it is already at the limit\nconfigured for the number of simultaneous clients (configured using the `maxclients` configuration directive, see the next section of this document for further information).\n\nWhen Redis can't accept a new client connection because the maximum number of clients\nhas been reached, it tries to send an error to the client in order to\nmake it aware of this condition, closing the connection immediately.\nThe error message will reach the client even if the connection is\nclosed immediately by Redis because the new socket output buffer is usually\nbig enough to contain the error, so the kernel will handle transmission\nof the error."
    },
    {
      "id": "what-order-are-client-requests-served-in",
      "title": "What Order are Client Requests Served In?",
      "role": "content",
      "text": "The order is determined by a combination of the client socket file descriptor\nnumber and order in which the kernel reports events, so the order should be \nconsidered as unspecified.\n\nHowever, Redis does the following two things when serving clients:\n\n* It only performs a single `read()` system call every time there is something new to read from the client socket. This ensures that if we have multiple clients connected, and a few send queries at a high rate, other clients are not penalized and will not experience latency issues.\n* However once new data is read from a client, all the queries contained in the current buffers are processed sequentially. This improves locality and does not need iterating a second time to see if there are clients that need some processing time."
    },
    {
      "id": "maximum-concurrent-connected-clients",
      "title": "Maximum Concurrent Connected Clients",
      "role": "content",
      "text": "In Redis 2.4 there was a hard-coded limit for the maximum number of clients\nthat could be handled simultaneously.\n\nIn Redis 2.6 and newer, this limit is configurable using the `maxclients` directive in `redis.conf`. The default is 10,000 clients.\n\nHowever, Redis checks with the kernel what the maximum number of file\ndescriptors that we are able to open is (the *soft limit* is checked). If the\nlimit is less than the maximum number of clients we want to handle, plus\n32 (that is the number of file descriptors Redis reserves for internal uses),\nthen the maximum number of clients is updated to match the number\nof clients it is *really able to handle* under the current operating system\nlimit.\n\nWhen `maxclients` is set to a number greater than Redis can support, a message is logged at startup:\n\n[code example]\n\nWhen Redis is configured in order to handle a specific number of clients it\nis a good idea to make sure that the operating system limit for the maximum\nnumber of file descriptors per process is also set accordingly.\n\nUnder Linux these limits can be set both in the current session and as a\nsystem-wide setting with the following commands:\n\n* `ulimit -Sn 100000 # This will only work if hard limit is big enough.`\n* `sysctl -w fs.file-max=100000`"
    },
    {
      "id": "output-buffer-limits",
      "title": "Output Buffer Limits",
      "role": "returns",
      "text": "Redis needs to handle a variable-length output buffer for every client, since\na command can produce a large amount of data that needs to be transferred to the\nclient.\n\nHowever it is possible that a client sends more commands producing more output\nto serve at a faster rate than that which Redis can send the existing output to the\nclient. This is especially true with Pub/Sub clients in case a client is not\nable to process new messages fast enough.\n\nBoth conditions will cause the client output buffer to grow and consume\nmore and more memory. For this reason by default Redis sets limits to the\noutput buffer size for different kind of clients. When the limit is reached\nthe client connection is closed and the event logged in the Redis log file.\n\nThere are two kind of limits Redis uses:\n\n* The **hard limit** is a fixed limit that when reached will make Redis close the client connection as soon as possible.\n* The **soft limit** instead is a limit that depends on the time, for instance a soft limit of 32 megabytes per 10 seconds means that if the client has an output buffer bigger than 32 megabytes for, continuously, 10 seconds, the connection gets closed.\n\nDifferent kind of clients have different default limits:\n\n* **Normal clients** have a default limit of 0, that means, no limit at all, because most normal clients use blocking implementations sending a single command and waiting for the reply to be completely read before sending the next command, so it is always not desirable to close the connection in case of a normal client.\n* **Pub/Sub clients** have a default hard limit of 32 megabytes and a soft limit of 8 megabytes per 60 seconds.\n* **Replicas** have a default hard limit of 256 megabytes and a soft limit of 64 megabyte per 60 seconds.\n\nIt is possible to change the limit at runtime using the [`CONFIG SET`](https://redis.io/docs/latest/commands/config-set) command or in a permanent way using the Redis configuration file `redis.conf`. See the example `redis.conf` in the Redis distribution for more information about how to set the limit."
    },
    {
      "id": "query-buffer-hard-limit",
      "title": "Query Buffer Hard Limit",
      "role": "content",
      "text": "Every client is also subject to a query buffer limit. This is a non-configurable hard limit that will close the connection when the client query buffer (that is the buffer we use to accumulate commands from the client) reaches 1 GB, and is actually only an extreme limit to avoid a server crash in case of client or server software bugs."
    },
    {
      "id": "client-eviction",
      "title": "Client Eviction",
      "role": "content",
      "text": "Redis is built to handle a very large number of client connections.\nClient connections tend to consume memory, and when there are many of them, the aggregate memory consumption can be extremely high, leading to data eviction or out-of-memory errors.\nThese cases can be mitigated to an extent using [output buffer limits](#output-buffer-limits), but Redis allows us a more robust configuration to limit the aggregate memory used by all clients' connections.\n\n\nThis mechanism is called **client eviction**, and it's essentially a safety mechanism that will disconnect clients once the aggregate memory usage of all clients is above a threshold.\nThe mechanism first attempts to disconnect clients that use the most memory.\nIt disconnects the minimal number of clients needed to return below the `maxmemory-clients` threshold.\n\n`maxmemory-clients` defines the maximum aggregate memory usage of all clients connected to Redis.\nThe aggregation takes into account all the memory used by the client connections: the [query buffer](#query-buffer-hard-limit), the output buffer, and other intermediate buffers.\n\nNote that replica and master connections aren't affected by the client eviction mechanism. Therefore, such connections are never evicted.\n\n`maxmemory-clients` can be set permanently in the configuration file (`redis.conf`) or via the [`CONFIG SET`](https://redis.io/docs/latest/commands/config-set) command.\nThis setting can either be 0 (meaning no limit), a size in bytes (possibly with `mb`/`gb` suffix),\nor a percentage of `maxmemory` by using the `%` suffix (e.g. setting it to `10%` would mean 10% of the `maxmemory` configuration).\n\nThe default setting is 0, meaning client eviction is turned off by default.\nHowever, for any large production deployment, it is highly recommended to configure some non-zero `maxmemory-clients` value.\nA value `5%`, for example, can be a good place to start.\n\nIt is possible to flag a specific client connection to be excluded from the client eviction mechanism.\nThis is useful for control path connections.\nIf, for example, you have an application that monitors the server via the [`INFO`](https://redis.io/docs/latest/commands/info) command and alerts you in case of a problem, you might want to make sure this connection isn't evicted.\nYou can do so using the following command (from the relevant client's connection):\n\n[`CLIENT NO-EVICT`](https://redis.io/docs/latest/commands/client-no-evict) `on`\n\nAnd you can revert that with:\n\n[`CLIENT NO-EVICT`](https://redis.io/docs/latest/commands/client-no-evict) `off`\n\nFor more information and an example refer to the `maxmemory-clients` section in the default `redis.conf` file.\n\nClient eviction is available from Redis 7.0."
    },
    {
      "id": "client-timeouts",
      "title": "Client Timeouts",
      "role": "content",
      "text": "By default recent versions of Redis don't close the connection with the client\nif the client is idle for many seconds: the connection will remain open forever.\n\nHowever if you don't like this behavior, you can configure a timeout, so that\nif the client is idle for more than the specified number of seconds, the client connection will be closed.\n\nYou can configure this limit via `redis.conf` or simply using `CONFIG SET timeout <value>`.\n\nNote that the timeout only applies to normal clients and it **does not apply to Pub/Sub clients**, since a Pub/Sub connection is a *push style* connection so a client that is idle is the norm.\n\nEven if by default connections are not subject to timeout, there are two conditions when it makes sense to set a timeout:\n\n* Mission critical applications where a bug in the client software may saturate the Redis server with idle connections, causing service disruption.\n* As a debugging mechanism in order to be able to connect with the server if a bug in the client software saturates the server with idle connections, making it impossible to interact with the server.\n\nTimeouts are not to be considered very precise: Redis avoids setting timer events or running O(N) algorithms in order to check idle clients, so the check is performed incrementally from time to time. This means that it is possible that while the timeout is set to 10 seconds, the client connection will be closed, for instance, after 12 seconds if many clients are connected at the same time."
    },
    {
      "id": "the-client-command",
      "title": "The CLIENT Command",
      "role": "content",
      "text": "The Redis [`CLIENT`](https://redis.io/docs/latest/commands/client) command allows you to inspect the state of every connected client, to kill a specific client, and to name connections. It is a very powerful debugging tool if you use Redis at scale.\n\n[`CLIENT LIST`](https://redis.io/docs/latest/commands/client-list) is used in order to obtain a list of connected clients and their state:\n\n[code example]\n\nIn the above example two clients are connected to the Redis server. Let's look at what some of the data returned represents:\n\n* **addr**: The client address, that is, the client IP and the remote port number it used to connect with the Redis server.\n* **fd**: The client socket file descriptor number.\n* **name**: The client name as set by [`CLIENT SETNAME`](https://redis.io/docs/latest/commands/client-setname).\n* **age**: The number of seconds the connection existed for.\n* **idle**: The number of seconds the connection is idle.\n* **flags**: The kind of client (N means normal client, check the [full list of flags](https://redis.io/docs/latest/commands/client-list)).\n* **omem**: The amount of memory used by the client for the output buffer.\n* **cmd**: The last executed command.\n\nSee the [`CLIENT LIST`](https://redis.io/docs/latest/commands/client-list) documentation for the full listing of fields and their purpose.\n\nOnce you have the list of clients, you can close a client's connection using the [`CLIENT KILL`](https://redis.io/docs/latest/commands/client-kill) command, specifying the client address as its argument.\n\nThe commands [`CLIENT SETNAME`](https://redis.io/docs/latest/commands/client-setname) and [`CLIENT GETNAME`](https://redis.io/docs/latest/commands/client-getname) can be used to set and get the connection name. Starting with Redis 4.0, the client name is shown in the\n[`SLOWLOG`](https://redis.io/docs/latest/commands/slowlog) output, to help identify clients that create latency issues."
    },
    {
      "id": "tcp-keepalive",
      "title": "TCP keepalive",
      "role": "content",
      "text": "From version 3.2 onwards, Redis has TCP keepalive (`SO_KEEPALIVE` socket option) enabled by default and set to about 300 seconds. This option is useful in order to detect dead peers (clients that cannot be reached even if they look connected). Moreover, if there is network equipment between clients and servers that need to see some traffic in order to take the connection open, the option will prevent unexpected connection closed events."
    }
  ],
  "examples": [
    {
      "id": "maximum-concurrent-connected-clients-ex0",
      "language": "plaintext",
      "code": "$ ./redis-server --maxclients 100000\n[41422] 23 Jan 11:28:33.179 # Unable to set the max number of files limit to 100032 (Invalid argument), setting the max clients configuration to 10112.",
      "section_id": "maximum-concurrent-connected-clients"
    },
    {
      "id": "the-client-command-ex0",
      "language": "plaintext",
      "code": "redis 127.0.0.1:6379> client list\naddr=127.0.0.1:52555 fd=5 name= age=855 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=0 events=r cmd=client\naddr=127.0.0.1:52787 fd=6 name= age=6 idle=5 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=ping",
      "section_id": "the-client-command"
    }
  ]
}
