{"record":{"id":"540ed7c6584947f8","repo":"redis/redis-py","slug":"timeout-writing-to-socket","errorCode":null,"errorMessage":"Timeout writing to socket","messagePattern":"Timeout writing to socket","errorType":"exception","errorClass":"TimeoutError","httpStatus":null,"severity":"error","filePath":"redis/asyncio/connection.py","lineNumber":1193,"sourceCode":"            await self.connect_check_health(check_health=False)\n        if check_health:\n            await self.check_health()\n\n        try:\n            if isinstance(command, str):\n                command = command.encode()\n            if isinstance(command, bytes):\n                command = [command]\n            if self.socket_timeout:\n                await asyncio.wait_for(\n                    self._send_packed_command(command), self.socket_timeout\n                )\n            else:\n                self._writer.writelines(command)\n                await self._writer.drain()\n        except asyncio.TimeoutError:\n            await self.disconnect(nowait=True)\n            raise TimeoutError(\"Timeout writing to socket\") from None\n        except OSError as e:\n            await self.disconnect(nowait=True)\n            if len(e.args) == 1:\n                err_no, errmsg = \"UNKNOWN\", e.args[0]\n            else:\n                err_no = e.args[0]\n                errmsg = e.args[1]\n            raise ConnectionError(\n                f\"Error {err_no} while writing to socket. {errmsg}.\"\n            ) from e\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            await self.disconnect(nowait=True)\n            raise\n","sourceCodeStart":1175,"sourceCodeEnd":1211,"githubUrl":"https://github.com/redis/redis-py/blob/6a6b581b48225afa0b76912d1028c6035baee932/redis/asyncio/connection.py#L1175-L1211","documentation":"Raised as TimeoutError from send_packed_command() when asyncio.wait_for(_send_packed_command, self.socket_timeout) elapses before the writer drains. The library first disconnects the connection (nowait=True) and then raises, so the socket is dead. socket_timeout is the per-operation read/write budget.","triggerScenarios":"Issuing any command while socket_timeout is set and the network/server cannot accept bytes fast enough; e.g. a large PIPELINE/MULTI bulk write, a slow server, or a saturated link. Also triggered by a server that has stopped reading from its socket buffer.","commonSituations":"Default-omitted socket_timeout suddenly set to a low value; large MULTI/EXEC or big value (MB-sized SET) against a constrained server; TCP send buffer full because the peer stopped draining; cross-region latency exceeding the configured timeout.","solutions":["Increase socket_timeout to comfortably exceed the slowest expected write.","Reduce the size of pipeline batches / individual payloads.","Diagnose server-side slowlog and CPU/memory pressure that stalls socket reads.","Confirm socket_keepalive is enabled so dead peers are detected earlier rather than stalling until the write timeout."],"exampleFix":"// before\nr = redis.asyncio.Redis(host=h, socket_timeout=0.2)\n// after\nr = redis.asyncio.Redis(host=h, socket_timeout=5.0, socket_keepalive=True)","handlingStrategy":"retry","validationCode":"def timeout_supports_payload(size_bytes: int, socket_timeout: float, bandwidth_bps: int) -> bool:\n    return (size_bytes * 8) / bandwidth_bps < socket_timeout","typeGuard":"def is_write_timeout(exc: BaseException) -> bool:\n    return isinstance(exc, TimeoutError) and 'writing to socket' in str(exc).lower()","tryCatchPattern":"from redis.retry import Retry\nfrom redis.backoff import ExponentialBackoff\n\nr = redis.asyncio.Redis(\n    host=h,\n    socket_timeout=5.0,\n    retry=Retry(ExponentialBackoff(), 3),\n    retry_on_timeout=True,\n)","preventionTips":["Size socket_timeout above your largest write / slowest link.","Keep pipeline batches bounded.","Enable socket_keepalive to detect dead peers."],"tags":["network","timeout","write","socket-timeout","async","pipeline"],"backgroundTag":null,"analyzedSha":"6a6b581b48225afa0b76912d1028c6035baee932","analyzedAt":"2026-08-10T12:52:44.840Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}