为什么 Claude Code 用着慢?
一句话:网络很好,慢在本机 —— 4GB 的 WSL 被一堆 Claude 会话挤爆、正在重度 swap(拿硬盘当内存);再叠加 effort=max 的最慢档位。
① 网络(本机 ↔ Claude 服务器)健康 · 不是问题
直连官方 api.anthropic.com(无任何中转、OAuth 登录)。线路质量优秀,这一环完全不用动。
| 指标 | 实测 | 判断 |
|---|---|---|
| 往返 ( ping) | 平均 5.3 ms / 0% 丢包 | 极好 |
| 解析 | 15 – 38 ms | 正常 |
| 连接 | 22 – 52 ms | 正常 |
| 握手 | 稳定后 ~80–110 ms | 正常 |
| 首字节 | 稳定 ~90–115 ms | 好 |
说明:解析到 160.79.104.10(Anthropic 自有 IP)。
注:ping 宿主网关 100% 丢包是 WSL 的正常现象 —— Windows 防火墙默认拦 ICMP,与性能无关。
② 本机系统瓶颈就在这
内存爆满 → 重度 swap 换页,把 CPU 和磁盘一起拖垮。
- WSL 内存上限仅 4GB ——
.wslconfig里memory=4GB(因为宿主总共才 8GB)。实测free仅剩 67 MB、可用 715 MB。 - 20G 已用掉 7.7G —— 正在重度换页(vmstat 有 si/so 活动)。换页 = 拿硬盘当内存,必然卡。
- 元凶:此刻同时开着 8+ 个
claude进程 —— 内存占用 top 8 全是它,光前 8 个就 ≈ 1.6 GB,4GB 根本装不下 → 全压进 swap。
| 子系统 | 实测 | 正常参考 | 差距 |
|---|---|---|---|
| 单核 CPU(5 千万次加法) | 1.6 s | ~0.1 s | 慢约 15× 3 次稳定复现,非偶发 |
| 磁盘写入() | 23 MB/s | 数百 MB/s | swap I/O 抢带宽 |
| 登录 shell 启动 | 0.9 s / 次 | — | 每次 Bash 工具都吃 |
注:磁盘「空闲时」本不慢(曾测 ~186 MB/s),此刻掉到 23 MB/s 是换页 I/O 抢占带宽所致 —— 二者不矛盾。
③ 模型 / 配置档位最慢档 · 属设定
opus[1m] + 最高档(effortLevel: xhigh + 本会话 /effort max + CLAUDE_EFFORT=max)。
这部分慢是 Anthropic 服务器端的「思考时间」,是你主动选的最高质量设定,不是故障,也与网络、本机硬件无关。想更快 → 把 effort 降到 medium/high,或换 sonnet。
慢的三个来源 · 按影响排序
三者相互独立,叠加在一起造成「整体很慢」的体感。
延伸追问 · 把这台电脑带到美国会更快吗?不会有可感知提升
用一台在美国硅谷的服务器做了对比实测,结论有数据支撑。
- 真相:
api.anthropic.com是 (任播)IP。它注册在旧金山,却在全球多地广播 —— 你在台湾连的其实是 Anthropic 的东亚边缘节点,RTT 才 6ms,并非真连到旧金山。Anthropic 的网络已把"美国的就近优势"提前送到台湾家门口。
| 指标 | 🇹🇼 台湾(本机 HiNet) | 🇺🇸 美国硅谷(Santa Clara) |
|---|---|---|
| 往返 | 6.0 ms | 2.1 ms |
| 连接 | 22–52 ms | 4–8 ms |
| 握手 | 80–110 ms | 76–160 ms |
| 首字节 | 90–115 ms | 81–168 ms |
| 连到的 IP | 160.79.104.10(两地同一个 anycast IP) | |
- RTT 差距只有 4ms(6→2ms),都是个位数毫秒,人完全无法感知。
- 关键:TTFB 两地几乎一样(都在 ~80–160ms)。说明那 ~100ms 大头是 Anthropic 服务器处理请求的时间,不是网络距离 —— 搬到美国根本省不到。
- 美国唯一明显占优的是 TCP 首次连接,但那是一次性握手(keep-alive 会复用),对持续使用基本无影响。
| 慢源 | 影响 | 搬到美国会变吗? |
|---|---|---|
| ① 本机 4GB 内存爆 + swap | 最大 | 不变(还是 4GB、还是 swap) |
| ② effort=max + opus 思考时间 | 中 | 不变(服务器端思考) |
| ③ 网络 | ≈0 | 基本不变(实测台湾≈美国) |
结论:带到美国,Claude Code 不会用得更快。三个慢源里两个跟地理完全无关,第三个(网络)实测两地一样。真正能变快的还是那三条(关多余会话 / 降 effort / 加内存)—— 全都在台湾就能做,不用搬。
建议 · 按性价比
从「立刻见效」到「根治」。
-
关掉多余的 claude 会话 立刻见效现在 8+ 个实例挤 4GB,只留 1–2 个。内存一松、swap 回落,整机马上变顺。
-
降 effort 或换模型 想更快日常任务把 effort 降到
medium/high,或换sonnet;把max留给真正难的活。 -
重启 WSL 清 swap 清理闲时在 Windows 执行
wsl --shutdown再重开,清掉那 7.7G 换页抖动。 -
加物理内存 根治8GB 对「WSL + 多会话 Claude Code + 生信工具」太小。加到 16–32G 后,把
.wslconfig的memory提到 12–24G,从根上不再 swap。 -
精简 .bashrc 次要把 0.9s 的登录 shell 启动压下来(每次 Bash 工具调用都会吃这段时间)。
常见疑问
关于内存分配,以及"活跃的 Claude Code 为什么跟 swap 有关"。
- 8G 是 Windows 宿主的总量,要和 WSL 共享。
.wslconfig里memory=4GB是上限——必须给 Windows 自己留一份(系统 + 桌面 + 浏览器也吃内存),否则把 Windows 饿死、整机更卡。不设的话 WSL2 默认也约拿宿主一半(≈4G),所以 4G ≈ 默认值。 - 能适当多分,已调到 5G(WSL +1G、Windows 留 3G);配合已开的
autoMemoryReclaim=gradual(WSL 空闲时把内存还给 Windows)相对安全。⚠️ 需在 Windows 执行wsl --shutdown重启 WSL 才生效(会关掉所有 WSL 会话)。想更激进可设 6G,但 Windows 只剩 2G 会比较紧。 - 但 8G 总量太小,4 / 5 / 6 怎么切都是拆东墙补西墙。根治是加物理内存条(加到 16–32G,再把 WSL 设到 12–24G,从此不再 swap)。
- Linux / WSL 是「」:物理内存(RAM)不够时,内核把最久没被访问的「冷」内存页换到 swap(硬盘)腾出 RAM。判断依据是「多久没用」,不是「进程是否活着」。
- 你开了 8+ 个 claude,但同一刻通常只用 1 个。其余几个虽然活着,大多在空闲等待(等你输入 / 等 API 响应),内存页变「冷」→ 被换进 swap;切回它们时再换回 → 卡一下。
- 正在用的那个也会被连累。即使是你正在用的前台 claude,它的内存也并非全是"热"的;加上 Node 的 会定时翻一遍整个堆、把 里的部分全搬回来。这点最反直觉,下面单独详解 ↓
- swap = 拿硬盘当内存,比 RAM 慢上千倍。所以只要总内存需求 > 物理 RAM,就必然有数据被挤到 swap,活跃进程也跑不掉。解法只有让「总需求 ≤ 物理 RAM」:关掉多余 claude(立竿见影),或加内存。
① 进程里也有"冷数据"。一个 claude 占几百 MB,但不是每一块都时时在用:当前对话、正在跑的任务是"热"的,启动时加载的库、翻过的历史记录是"冷"的。RAM 一紧张,内核连"你正在用的那个 claude 里的冷数据"也照换到 不误——它只看"这一页多久没被访问",不管进程是不是你正盯着的前台。等你刚好要用到那块(翻历史、调某个功能),就得从硬盘换回来 → 卡一下。
② GC「翻旧账」(这点更关键)。 是 Node.js(claude 的运行时)周期性自动跑的,每次都要扫描整个内存堆。平时全在 RAM,扫得飞快;可一旦你这个 claude 的堆有一部分被换到了 swap,GC 这一扫就得把硬盘里的部分全部搬回 RAM → 一次 GC 就引发一大轮换入换出。GC 躲不掉、又定时来,所以你这个前台 claude 每隔一会就被它拖一下——这正是实测「单核算力慢 15×」的真凶:CPU 不是不够,而是大量时间在等硬盘搬数据。
附 · 原始实测数据
展开查看实测命令输出
#1 dns=0.038 tcp=0.052 tls=0.200 ttfb=0.213 total=0.213 http=405 #2 dns=0.037 tcp=0.043 tls=0.116 ttfb=0.127 total=0.127 http=405 #3 dns=0.030 tcp=0.041 tls=0.107 ttfb=0.115 total=0.115 http=405 #4 dns=0.015 tcp=0.022 tls=0.096 ttfb=0.106 total=0.106 http=405 #5 dns=0.025 tcp=0.032 tls=0.081 ttfb=0.091 total=0.091 http=405 解析 IP: 160.79.104.10
6 packets transmitted, 6 received, 0% packet loss rtt min/avg/max/mdev = 4.231/5.271/7.738/1.158 ms
total used free shared buff/cache available Mem: 3.8Gi 3.1Gi 67Mi 2.0Mi 789Mi 715Mi Swap: 20Gi 7.7Gi 12Gi loadavg: 1.08 0.82 1.53 (4 核)
r b swpd free buff cache si so bi bo in cs us sy id wa 2 0 8044456 70524 36788 771740 89 97 182 114 1128 4 4 4 91 1 0 0 8044472 70488 36796 771500 0 32 0 76 1891 2634 3 6 91 0 0 0 8044472 69496 36796 771508 0 0 0 0 2350 3424 6 10 83 0 (swpd ≈ 7.7G 常驻 swap;首行 si/so 有换页活动)
USER %MEM RSS(MB) CMD hgt 8.9% 349 claude --dangerously-skip-permissions hgt 7.9% 312 claude --dangerously-skip-permissions hgt 5.1% 202 claude --dangerously-skip-permissions hgt 4.0% 159 claude --dangerously-skip-permissions hgt 3.8% 152 claude --dangerously-skip-permissions hgt 3.7% 146 claude --dangerously-skip-permissions hgt 3.4% 135 claude --dangerously-skip-permissions hgt 3.4% 135 claude --dangerously-skip-permissions (前 8 个 claude 合计 ≈ 1.59 GB)
5e7 次: 1.594 s / 1.674 s / 1.724 s (正常机 ~0.1s → 慢约 15×,稳定复现) 5e8 次: 16.825 s (= 5e7 ×10,比例一致)
磁盘写(256MB,fdatasync): 23 MB/s bash -lic 启动: 0.904 / 0.958 / 0.892 s 空 node 启动: 0.08 – 0.13 s /bin/true: 0.003 – 0.005 s
[wsl2] memory=4GB processors=4 swap=20GB [experimental] autoMemoryReclaim=gradual