[Regression][Remote SSH][Linux] Cursor 3.15.19 blocks server-main for seconds in os.cpus() on high-core-count AMD hosts

Where does the bug appear (feature/product)?

Cursor IDE

Describe the Bug

Cursor 3.15.19 introduces a Remote SSH performance regression on a 384-logical-CPU AMD EPYC Linux host.
server-main periodically blocks its Node event loop for approximately 4–8 seconds while CursorProclistService calls os.cpus().
During the stall, ptyHost heartbeats are not processed and integrated-terminal input freezes. Plain SSH to the same host remains responsive.

Steps to Reproduce

SSH to a multi-CPUs remote host, then open a terminal and try to type something.

Operating System

Linux

Version Information

Last known good: Cursor 3.15.6 / a1f686545fd0ce8917bbd2449f733551a9bce420
First known bad: Cursor 3.15.19 / de07bee81cefe43461ebf4f40c3d2d78d15052aa

Does this stop you from using Cursor

Yes - Cursor is unusable

Hey, thanks for the report, it’s one of the most detailed we’ve seen. Profiling server-main and bisecting 3.15.6 → 3.15.19 helped a lot, your analysis is spot on.

Confirmed, what you’re describing is reproducible, and it’s not anything in your setup. It’s on our side. I’ve passed it to the team.

You don’t need to do anything else, and you don’t need to install a client update for this. I can’t share an exact timeline yet, but I’ll post here once there’s an update.

Where does the bug appear (feature/product)?

Cursor IDE

Describe the Bug

Affected: 3.16.17 — commit 6b2afae0257df2bb5e1835f15165dc2f0de056b0, built 2026-08-14
Last good: 3.12.17 — commit 0fb762053c34788bb7760d5673f8a6d4c8589d50, built 2026-07-17
Scope: Remote-SSH windows. Local editing is unaffected.

Symptom

In any remote terminal, typing and echo freeze for ~1.9 seconds on a precise 10.0-second
period — roughly a 19% duty cycle. The editor is unaffected. A plain ssh session to the
same host over the same network is unaffected.

Rolling the client back to 3.12.17 eliminates it completely; reinstalling 3.16.17 reproduces it.

Measurement

Terminal round-trip latency, measured by writing a Device Status Report (ESC[6n) and timing
the terminal’s reply — so it exercises the full server → client → server path. 600 samples at
50 ms intervals, same host, same session, same Wi-Fi.

3.16.17 3.12.17 plain ssh (control)
p50 24.1 ms 26.5 ms 35.2 ms
p90 30.9 ms 31.0 ms 40.5 ms
p99 127.7 ms 90.4 ms 53.6 ms
max 1923.7 ms 128.7 ms 256.6 ms
spikes > 1 s 5 0 0

Note that 3.16.17 is faster than plain ssh at p50 and p90. This is not a slow link — it is a
discrete, periodic block.

The five spikes in one 55-second capture:

09:51:44.68   1861.8 ms
09:51:54.67   1896.1 ms     +9.99 s
09:52:04.62   1923.7 ms     +9.95 s
09:52:14.67   1761.5 ms     +10.05 s
09:52:24.67   1883.3 ms     +10.00 s

Mechanism

At every stall, server-main.js enters D state (uninterruptible sleep), wchan=msleep,
0% CPU, for the duration of the stall:

09:51:44.x  2258242:D:20   <- enters D
09:51:45-46 2258242:D:0    <- blocked, zero CPU
09:51:46.x  2258242:S      <- releases

It is the only process in D on the entire 96-core host at those instants
(D_procs=[node,]). Sampling the process state 4x/second:

D-state samples per 30 s
3.16.17 21
3.12.17 0

Steps to Reproduce

  1. Connect a Remote-SSH window to a Linux host.
  2. In a terminal, run cat > /dev/null and type. It stalls — so this is not shell integration,
    command suggestions, or a TUI application.
  3. Reproduces with a single terminal open.
  4. Reproduces on a fresh server process: pkill -f cursor-server, reconnect, and the 10.0 s
    pattern is present within 16 seconds of the new server-main.js starting. Not stuck state.

To measure it, run this in a remote terminal:

import sys, time, termios, tty, os
N = 600
fd = sys.stdin.fileno(); old = termios.tcgetattr(fd); rows = []
try:
    tty.setraw(fd)
    for i in range(N):
        a = time.time()
        os.write(1, b"\033[6n"); buf = b""
        while not buf.endswith(b"R"): buf += os.read(fd, 1)
        rows.append((a, (time.time() - a) * 1000))
        time.sleep(0.05)
finally:
    termios.tcsetattr(fd, termios.TCSADRAIN, old)
    for t, l in rows:
        if l > 100: print("  %s  %8.1f ms\r" % (time.strftime("%H:%M:%S", time.localtime(t)), l))

Expected Behavior

Ruled out by direct measurement

hypothesis evidence against
Memory reclaim allocstall, compact_stall, pgscan_direct all +0 during every D window
Disk I/O 3 writes/s on the device, iowait 0%, remoteagent.log grew 0 bytes in 10 s
Network filesystem None mounted; workspace is local ext4
The new multiplex-server broker S state, 0% CPU throughout every stall
Extension host Periodic 40–60% bursts on a ~6.4 s cycle — does not align with the 10.0 s stalls
File watcher Idle: 1 active sample of 120, 2% peak
Git polling 0 git processes spawned in 40 s
Shell integration / terminal suggest cat > /dev/null (raw pty, no shell) also stalls
Number of terminals Reproduces with 1
Network path mtr end-to-end 0% loss; plain ssh control max 257 ms
Input path 280 keystrokes arrived at the server at mean 28.2 ms, sd 16.1 ms, max excursion 132 ms — inbound is clean

What would help

The block is in server-main.js on a 10.0 s timer. A kernel stack captured during the D state
would name the syscall — happy to provide that, or any other trace, on request.

Operating System

MacOS

Version Information

Environment

  • Client: macOS (Darwin arm64 25.5.0), Apple Silicon. Electron 40.10.3, Chromium 144.0.7559.236,
    Node 24.15.0, V8 14.4.258.32-electron.0, xterm.js 6.1.0-beta.256, VS Code Extension API 1.128.0.
  • Host: Ubuntu, kernel 5.15.0-153-generic, 96 cores, 503 GB RAM, ext4 on local NVMe, no network
    mounts. Host otherwise idle: 98–100% idle CPU, 0% iowait, 400 GB memory available.
  • Link: Remote-SSH over Wi-Fi (5 GHz, RSSI −58 dBm, SNR 37 dB), ~15–25 ms RTT, 0% end-to-end loss.

Does this stop you from using Cursor

Sometimes - I can sometimes use Cursor

Hey @Yangfan_Zhou, and thanks again for the detailed report. Profiling server-main and running a bisect really helped.

Quick correction to my last message: you’ll actually need a client update for this. The fix for the periodic server-main stalls that freeze terminal input over Remote SSH on high core count hosts is included in Cursor 3.19.10 or newer. Once you update to 3.19.10+ and reconnect, the remote server will update along with the client, and the stalls should be gone.

Please try again when you’re on that version and let me know if anything remains.

cc @Bram_Pol