{"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/da03cdc7e8731092b13e395605c3c1fb2de25de1/redis/asyncio/connection.py#L1175-L1211","documentation":"Raised as a TimeoutError from send_packed_command() when self.socket_timeout is set and the write (writelines + drain) does not complete within that timeout. The connection is forcibly disconnected (nowait=True) before the error propagates, because a stuck write means the socket is unusable.","triggerScenarios":"Calling any command (send_command/send_packed_command) with socket_timeout configured, where the underlying writer.drain() blocks longer than socket_timeout. Happens when the server or network stops draining the TCP send buffer (slow consumer, full kernel buffers).","commonSituations":"Pipelining/transactions with very large payloads that saturate the receive window; a server under extreme load or paused (DEBUG SLEEP, GC stall, swap thrash); a network link with high latency loss causing TCP backoff; socket_timeout set too low for the workload.","solutions":["Increase socket_timeout to accommodate the largest expected command/pipeline size and worst-case latency.","Reduce the size of pipelines/batches or stream large values (e.g. SCAN) instead of sending them at once.","Investigate server-side pauses (slowlog, latency monitor, DEBUG SLEEP left running, memory pressure).","Verify network bandwidth and TCP window scaling between client and server."],"exampleFix":"// before\nr = redis.asyncio.Redis(host=h, port=p, socket_timeout=0.1)\n\n// after\nr = redis.asyncio.Redis(host=h, port=p, socket_timeout=5)","handlingStrategy":"retry","validationCode":"def safe_socket_timeout(workload_seconds: float) -> float:\n    # at least 2x the expected worst-case command time\n    return max(1.0, workload_seconds * 2)","typeGuard":null,"tryCatchPattern":"from redis.exceptions import TimeoutError, ConnectionError\nfor attempt in range(3):\n    try:\n        await r.execute_command(*big_cmd)\n        break\n    except TimeoutError as e:\n        if \"writing to socket\" in str(e):\n            await asyncio.sleep(2 ** attempt)\n            continue\n        raise","preventionTips":["Size socket_timeout to the largest pipeline/transaction.","Chunk very large writes instead of one giant pipeline.","Monitor server slowlog / latency for stalls."],"tags":["network","timeout","write","socket-timeout","async"],"analyzedSha":"da03cdc7e8731092b13e395605c3c1fb2de25de1","analyzedAt":"2026-08-04T20:26:47.563Z","schemaVersion":2}