Claude Code CLI unresponsive for ~5 minutes after laptop resume from suspend (Linux)

Resolved 💬 5 comments Opened Mar 8, 2026 by spkrka Closed Apr 6, 2026

Claude Code CLI unresponsive for ~5 minutes after laptop resume from suspend

Summary

After resuming from s2idle suspend on Linux, Claude Code CLI becomes unresponsive for approximately 5 minutes before it can process new prompts. The delay is caused by the CLI sending an API request on a stale TCP connection (which silently succeeds into the kernel buffer), then waiting ~4 minutes for a response that will never come before eventually reconnecting.

Environment

  • Claude Code version: 2.1.71
  • OS: Ubuntu 24.04.4 LTS
  • Kernel: 6.14.0-37-generic
  • Hardware: ThinkPad X1 Carbon Gen 12 (Meteor Lake)
  • Suspend type: s2idle (modern standby)

Steps to Reproduce

  1. Start a Claude Code session (interactive mode)
  2. Have an active conversation (so there are open API connections)
  3. Suspend the laptop for >5 minutes (systemctl suspend or lid close)
  4. Resume and immediately type a prompt + press Enter
  5. Observe: no response for ~5 minutes

Expected Behavior

Claude Code should detect stale connections and reconnect within seconds after resume.

Actual Behavior

The CLI sits unresponsive for ~5 minutes after resume. It eventually reconnects and responds, but the delay is very noticeable and disruptive.

Root Cause Analysis (via strace)

We attached strace to the Claude process filtering on network syscalls with wall-clock timestamps. The trace was captured with no external interference (no socket killing, no network manager hooks).

strace command

strace -f -tt -T -s 256 \
    -e trace=connect,sendto,recvfrom,shutdown,close \
    -e signal=none \
    -p <claude_pid> \
    2>&1 | tee /tmp/claude-trace.log

Timeline (clean trace, ~7 minute suspend)

12:48:05  Last network activity before suspend
          ---- LAPTOP SUSPENDED (s2idle) ----
12:55:31  Kernel: PM suspend exit (resume)

12:55:42  sendto(17, <API request>, 562, MSG_DONTWAIT|MSG_NOSIGNAL) = 562
          ^ Sends prompt to Anthropic API on STALE connection.
            sendto succeeds because data goes into kernel send buffer,
            but the remote end will never receive it (TCP connection is dead).

12:55:42 – 12:59:45  *** 4 MINUTE GAP ***
          CLI is idle, waiting for a response on the dead connection (fd 17).
          No reconnection attempts. No timeout handling.
          Only periodic 10-second keep-alive close() calls on fd 26/27.

12:59:46  connect(18, {AF_INET, 10.173.6.27:443}) = EINPROGRESS
          ^ First reconnection attempt — MCP server, not the API.

13:00:45  connect(24, {AF_INET, 142.250.110.95:443}) = 0
          ^ OAuth token refresh to googleapis.com

13:00:50  connect(25, {AF_INET, 160.79.104.10:443}) = EINPROGRESS
          ^ Finally reconnects to platform.claude.com — API is back.

13:00:50+ Response arrives, CLI is functional again.

Total unresponsive time: ~5 minutes 8 seconds (12:55:31 → 13:00:50)

Confirmed in multiple suspend cycles

We reproduced this across multiple suspend/resume cycles with consistent results:

| Suspend duration | Delay after resume |
|---|---|
| ~10 min | ~5 min 30 sec |
| ~7 min | ~5 min 8 sec |
| ~1 min | instant (connections survived) |

Short suspends (<~2 min) don't trigger the issue because TCP connections survive.

Key Finding: sendto on dead socket succeeds silently

The critical issue is the sendto(17, ..., 562) at 12:55:42. This socket was connected to the Anthropic API before suspend. After resume, the TCP connection is dead (the remote end has long closed it), but:

  1. sendto returns success (562 bytes) because the kernel accepts data into the send buffer
  2. The kernel will eventually detect the dead connection via TCP retransmissions, but this takes minutes
  3. The CLI waits for a response that will never come
  4. After ~4 minutes, some internal timeout fires and the CLI starts reconnecting

For reference, fd 17 (the stale connection) never received any data in the trace — confirming it was completely dead.

Suggested Fixes

  1. Detect resume from suspend: On Linux, subscribe to systemd's PrepareForSleep(false) D-Bus signal (fires on resume). Alternatively, detect wall-clock jumps by comparing CLOCK_MONOTONIC vs CLOCK_REALTIME — if wall clock jumped forward but monotonic didn't, a suspend occurred.
  1. Invalidate all connections on resume: When resume is detected, immediately close all HTTP/TLS connections and re-establish them. After suspend, remote connections are always dead.
  1. Set TCP_USER_TIMEOUT on sockets: Setting this socket option (e.g., to 30 seconds) makes the kernel report dead connections much faster than the default TCP retransmission timeout (~15 minutes).
  1. Add application-level request timeouts: The API request sent at 12:55:42 should have a reasonable timeout (e.g., 30-60 seconds). If no response comes within that window, close the connection and retry on a new one.

Potentially Related

  • #26729 — "[FEATURE] Streaming Resilience: Detect network loss, save in-flight state, and auto-resume on reconnect" describes similar symptoms (CLI hangs indefinitely after network disruption, including sleep/wake). That issue covers network disruptions broadly (WiFi drops, VPN reconnects, etc.) while this one is specifically about suspend/resume with strace-level root cause analysis. The underlying fix may overlap, but suspend/resume is uniquely detectable via OS signals (D-Bus PrepareForSleep) which could enable a more targeted solution.

View original on GitHub ↗

This issue has 5 comments on GitHub. Read the full discussion on GitHub ↗