{"record":{"id":"981aa1244a9ec45a","repo":"redis/redis-py","slug":"timeout-writing-to-socket-981aa1","errorCode":null,"errorMessage":"Timeout writing to socket","messagePattern":"Timeout writing to socket","errorType":"exception","errorClass":"TimeoutError","httpStatus":null,"severity":"error","filePath":"redis/connection.py","lineNumber":1352,"sourceCode":"                self._ping_failed,\n                with_failure_count=True,\n            )\n\n    def send_packed_command(self, command, check_health=True):\n        \"\"\"Send an already packed command to the Redis server\"\"\"\n        if not self._sock:\n            self.connect_check_health(check_health=False)\n        # guard against health check recursion\n        if check_health:\n            self.check_health()\n        try:\n            if isinstance(command, str):\n                command = [command]\n            for item in command:\n                self._sock.sendall(item)\n        except socket.timeout:\n            self.disconnect()\n            raise TimeoutError(\"Timeout writing to socket\")\n        except OSError as e:\n            self.disconnect()\n            if len(e.args) == 1:\n                errno, errmsg = \"UNKNOWN\", e.args[0]\n            else:\n                errno = e.args[0]\n                errmsg = e.args[1]\n            raise ConnectionError(f\"Error {errno} while writing to socket. {errmsg}.\")\n        except BaseException:\n            # BaseExceptions can be raised when a socket send operation is not\n            # finished, e.g. due to a timeout.  Ideally, a caller could then re-try\n            # to send un-sent data. However, the send_packed_command() API\n            # does not support it so there is no point in keeping the connection open.\n            self.disconnect()\n            raise\n\n    def send_command(self, *args, **kwargs):\n        \"\"\"Pack and send a command to the Redis server\"\"\"","sourceCodeStart":1334,"sourceCodeEnd":1370,"githubUrl":"https://github.com/redis/redis-py/blob/6a6b581b48225afa0b76912d1028c6035baee932/redis/connection.py#L1334-L1370","documentation":"Raised in send_packed_command (connection.py:1350-1352) when socket.sendall raises socket.timeout while writing a command to the server. The socket's write timeout (socket_timeout) elapsed before all bytes were sent, so the connection is disconnected and a redis.exceptions.TimeoutError is raised. This is a write-side stall, distinct from a read timeout.","triggerScenarios":"A command is sent on a connection whose socket_timeout is set, and the server/network is too slow to accept the bytes within that window (server paused, GC stop-the-world, saturated link, paused VM).","commonSituations":"Large PIPELINE/MULTI payloads on a slow link; Redis blocked (DEBUG SLEEP, slow script/LUA, big SAVE); cloud network blips; socket_timeout set too aggressively; overloaded instance under memory pressure / fork (BGSAVE).","solutions":["Increase socket_timeout to comfortably exceed your largest expected send time.","Batch smaller pipelines or split very large commands.","Check for server-side stalls (slowlog, LATENCY, INFO persistence — bgsave in progress).","Add retry_on_timeout=True / a Retry policy to recover from transient stalls.","Scale the Redis instance or reduce concurrent load."],"exampleFix":"# before\nr = redis.Redis(host=h, port=p, socket_timeout=0.1)\n# after\nr = redis.Redis(host=h, port=p, socket_timeout=2.0, retry_on_timeout=True)","handlingStrategy":"retry","validationCode":"# Size timeouts for your largest payload; enable retry\nr = redis.Redis(\n    host=h, port=p,\n    socket_timeout=max(2.0, estimated_worst_send_seconds),\n    retry_on_timeout=True,\n    retry=Retry(ExponentialBackoff(), 3),\n)","typeGuard":"null","tryCatchPattern":"from redis.exceptions import TimeoutError\nfor _ in range(3):\n    try:\n        r.execute_command(*cmd)\n        break\n    except TimeoutError as e:\n        if 'writing to socket' in str(e):\n            continue  # transient; pool reopens\n        raise","preventionTips":["Set socket_timeout larger than your slowest expected send (incl. big pipelines).","Split oversized pipelines/MULTI into batches.","Monitor Redis slowlog / INFO persistence (BGSAVE stalls).","Use retry_on_timeout=True for transient write stalls."],"tags":["timeout","network","write","performance"],"backgroundTag":null,"analyzedSha":"6a6b581b48225afa0b76912d1028c6035baee932","analyzedAt":"2026-08-10T12:52:44.840Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}