As a developer heavily reliant on ChatGPT Plus for cross-lingual open-source project research (such as OWASP and the Rust ecosystem), I have suffered over the past few days from the endless spinning and feigned death of the web version during the daytime, with the screen flooded with rqstr errors. Initially, I suspected that OpenAI was throttling computing resources for Plus accounts, and I even considered upgrading to the $100/month Pro plan. It was not until I used iperf3 to aggressively stress-test the link from my local machine to my self-built VPS that I completely uncovered the real culprit: host machine maintenance caused severe packet loss in the underlying network, which in turn triggered a “head-of-line blocking” effect under the TCP-over-TCP architecture.
But there is a crucial turning point in my understanding here—just a few days earlier, on October 16, I had written an article titled A Troubleshooting Record of Slow ChatGPT Web Loading, and the conclusion at that time was completely different. This article fully documents the reversal of my understanding between the two troubleshooting sessions, as well as the entire process from “suspecting external service degradation” to “digging deep into local link packet loss.”
I. Environment and Architecture Background: My Self-Built Proxy Network Link
Before diving into the specific troubleshooting, it is necessary to explain the full picture of the entire network link. After all, “web lag” can occur at any stage, and without knowing which nodes the traffic passes through, troubleshooting is impossible.
In May 2026, I wrote an article titled ZgoCloud + Wstunnel + WireGuard 4x Speedup: Clash Verge Rev Auto Routing and Port 443 Anti-Blocking Practical Guide, which documented the complete setup process of my self-built proxy network service. This architecture has been running stably since it was built. A brief summary of its data flow is as follows:
Local Device (Ubuntu Desktop + CLI)
↓
Clash Verge Rev (TUN mode, virtual NIC global takeover)
↓
Wstunnel Client (Encapsulates WireGuard’s UDP traffic into WebSocket/TLS, using TCP port 443)
↓
ZgoCloud Los Angeles VPS (Triple-network optimization: CN2 GIA + 9929 + CMIN2)
↓
Wstunnel Server → WireGuard Server → Target Website
In this architecture, each component bears specific responsibilities:
- ZgoCloud VPS: A KVM virtualized server located in Los Angeles, focusing on optimized routing for China’s three major networks. It serves as the exit point and computing host for the entire proxy link.
- WireGuard: Acts as the underlying encrypted tunnel, responsible for packet encryption/decryption and point-to-point transmission. Its native protocol is UDP, which is highly efficient, but UDP traffic characteristics are very obvious and easily throttled or blocked by ISP QoS in domestic network environments.
- Wstunnel: To solve the problem of WireGuard being easily blocked, I use Wstunnel to “wrap” WireGuard’s UDP packets inside standard WebSocket over TLS connections, disguising them as normal HTTPS traffic over TCP port 443. This makes it difficult for DPI (Deep Packet Inspection) to identify this as VPN traffic.
- Clash Verge Rev: The local traffic dispatch center. After enabling TUN mode (virtual NIC mode), it takes over all outbound system traffic (including
curl,gitin the terminal, and websites accessed by the browser), and then routes it based on rules: domestic traffic goes direct, and traffic requiring a proxy is sent into the Wstunnel tunnel.
This architecture has an important side effect: Wstunnel’s TCP tunnel and WireGuard’s UDP tunnel have a “nesting” relationship. When packet loss occurs on the underlying physical network, Wstunnel’s TCP retransmissions are further amplified by WireGuard’s UDP retransmissions—this is the root cause of the “TCP-over-TCP head-of-line blocking” problem that gave me a long headache during later troubleshooting.
And this ChatGPT web lag issue occurred precisely on this self-built link. Specifically, the stability of the underlying physical line took a cliff-like dive after ZgoCloud VPS host machine maintenance. All subsequent troubleshooting and optimizations revolved around this link.
II. Dire Situation: The “Feigned Death” Experience of Being Completely Unusable During the Day
While researching multilingual cross-comparisons for OWASP and the Rust community’s licensing situation, I encountered the following extreme conditions:
- Absurd time discrepancy: The chat interface showed “Thought for 3m 1s”, but I waited a full 30 minutes for the result to completely return; there were even a few times where it showed thinking for over a minute, but the actual delay before text appeared was 17 minutes.
- Screen full of red errors: I pressed
F12to open the developer tools, and the Network panel was densely packed with red errors forrqstr?k=client-sY.... These are the heartbeat requests used by the ChatGPT web version to maintain streaming output (SSE). - Only revives at night: Only after 10 PM does the web version restore its silky smooth streaming output.
![[Figure 1: Before optimization, the ChatGPT web version Network panel is flooded with red, stuck in infinite retries]](https://media.shuijingwanwq.com/2026/11/1-1024x640.png)
![[Figure 2: Before optimization, the frontend indicates thinking has finished, but the page is actually still frozen]](https://media.shuijingwanwq.com/2026/11/2-1024x650.png)
Technical analysis: ChatGPT’s output is streamed. Once packet loss occurs at the underlying layer, TCP will “hold back” all subsequent packets to wait for retransmission to maintain order (head-of-line blocking). The frontend waits in vain for new data, determines a timeout, and cuts off the connection to reconnect—this is the fundamental reason for the screen full of rqstr red errors I saw.
III. Previous Recap: The First Troubleshooting on October 16—Why Did I Reach a Different Conclusion Then?
Before falling into the desperate situation of 17-minute delays, I had already done a full-link troubleshooting on October 16 and written it up as a blog post. The troubleshooting process at that time was rigorous and comprehensive:
3.1 The Troubleshooting Path and Data at That Time
- Local proxy layer: Clash Verge upgraded to v2.5.8, confirming
chatgpt.comtraffic goes through the ZgoCloud-WG node. Local download speed via proxy was about 3.1 MB/s, Ping to server was 188ms, 0% packet loss, and YouTube opened instantly. - VPS server layer: Bandwidth 200 Mbps, system load extremely low, WireGuard handshake normal. Server direct to Cloudflare speed test reached 18 MB/s, proving there was no problem with the outbound bandwidth.
- Key anomaly point: When the server directly used
curlto request ChatGPT’s CDN static resources (JS files), TTFB was only 0.06s (extremely fast), but the download speed was firmly stuck at 543 KB/s.
3.2 The Conclusion and Reflection at That Time
Based on the above data, my logical deduction at the time pointed to an external server-side problem: since the bandwidth from the VPS to Cloudflare was 18 MB/s, and only the path to chatgpt.com/cdn/assets/ was throttled to 543 KB/s, the only explanation was that the OpenAI server (or its Cloudflare edge node) was undergoing service degradation at the time, implementing conservative anti-abuse throttling on that path.
Therefore, I wrote the following reflection in that blog post:
“For a node that has been running stably for months to suddenly slow down, the vast majority of cases are not configuration issues, but sudden changes in the external environment. During troubleshooting, I almost went to modify BBR and adjust MTU, which proved to be over-configuration.”
This conclusion was completely reasonable given the data support at the time, but it precisely became the starting point for my blind spot a few days later.
IV. Cognitive Turning Point: A Delayed Maintenance Notification Brings the Truth to Light
Right after the October 16 blog post was published, I received an email from ZgoCloud: at 00:00 Beijing time on October 17, they would perform an emergency security update and forced restart for the Linux kernel high-severity vulnerability CVE-2026-99999(PwnEscape) on all host machines.
![[Figure 5: Screenshot of the CVE vulnerability maintenance notification published by ZgoCloud]](https://media.shuijingwanwq.com/2026/11/5-1024x650.png)
I did not receive this email until October 19, but it made me re-examine the troubleshooting data from October 16.
I realized an extremely crucial blind spot: Although the official maintenance start time was the 17th, the email was not sent until the 19th. This means that the so-called “anomalous data” I measured on October 16 (such as the VPS direct to Cloudflare CDN speed being firmly stuck at 543 KB/s) was highly likely not an OpenAI server-side degradation at all, but rather a precursor to ZgoCloud’s underlying kernel network stack adjustments. The provider’s batched maintenance might have already started, and I only received this “late” notification on the 19th. In other words, the problem on the 16th was also highly likely caused by kernel fixes/host machine adjustments.
To verify this conjecture, I took out iperf3 again and gave the link from my local machine to the VPS a more comprehensive checkup—and this time, the results completely overturned the October 16 conclusion.
4.1 Re-testing Speeds: The “Retransmission Hell” Not Seen on October 16
![[Figure 3: needrestart popup when installing iperf3]](https://media.shuijingwanwq.com/2026/11/3.png)
# VPS 端
iperf3 -s
# 本地端(下行方向,模拟接收 ChatGPT 数据)
iperf3 -c 154.21.196.249 -t 10 -R
iperf3 -c 154.21.196.249 -u -b 100M -t 10![[Figure 4: iperf3 speed test screenshot, highlighting Bitrate and Retr (Retransmissions) data]](https://media.shuijingwanwq.com/2026/11/4.png)
The test results shocked me:
- Downstream bandwidth remained very high (200–300 Mbps), indicating no shrinkage in physical bandwidth—this is consistent with the October 16 conclusion.
- TCP retransmissions reached as high as 13,481 times/10 seconds—this is a brand new metric that was not exposed on October 16.
- UDP speed test receiver was directly at 0 Bytes—a large number of UDP packets were being discarded by the ISP during the day.
4.2 Re-evaluating the October 16 Conclusion
In retrospect, the “VPS direct to Cloudflare 18 MB/s” I measured on October 16 only verified bandwidth, not stability. And what truly determines the ChatGPT streaming long-connection experience is precisely the TCP retransmission rate, not peak bandwidth. The October 16 troubleshooting caught “sufficient bandwidth” but missed “severe packet loss.”
The final puzzle of the truth should be as follows: The provider performed kernel upgrades on the host machines on the 17th (or even earlier in batched operations). This underlying change caused BGP route drift and fine-tuning of network stack parameters. The slowdown I felt on the 16th was likely an early warning that the underlying environment had already started to become turbulent on the eve of maintenance; after the maintenance was completed on the 17th, the line became completely “fragile,” and the already marginal QoS resistance was broken, leading to the subsequent disastrous situation of being completely unusable during the day and having a screen full of rqstr errors.
V. Counterattack: Four Hardcore Optimizations from VPS to Local
Now that I knew it was a case of “sufficient bandwidth, severe packet loss,” and my architecture was Wstunnel(TCP) 套 WireGuard(UDP), I had to apply the right remedy to the situation.
Optimization 1: VPS Side—MSS Clamping to Prevent Large Packet Fragmentation
Wstunnel encapsulates UDP in TCP over port 443. If a TCP packet is too large, it will be fragmented; losing one fragment means the entire packet must be retransmitted. So I forcibly reduced the MSS to make TCP actively adapt to the narrow MTU:
sudo ss -tlnp | grep -i wstunnel
sudo iptables -t mangle -A OUTPUT -p tcp --sport 443 --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
sudo iptables -t mangle -L OUTPUT -n -v![[Figure 6: Confirming port 443 listening and adding MSS Clamping rules on the VPS]](https://media.shuijingwanwq.com/2026/11/6-1024x159.png)
To ensure the rules were not lost after a VPS reboot, I installed a persistence tool and saved them:
sudo apt install iptables-persistent -y
sudo netfilter-persistent save![[Figure 9: Using netfilter-persistent save to persist firewall rules]](https://media.shuijingwanwq.com/2026/11/9.png)
Optimization 2: Wstunnel Enables “Long Connection Pool”
With poor line conditions during the day, every new handshake has a very high probability of timing out. I used --connection-min-idle 10 to make the client always maintain 10 idle channels, so ChatGPT requests can directly reuse them:
sed -i 's/wstunnel client -L/wstunnel client --connection-min-idle 10 -L/' ~/VPN/start-vpn.sh![[Figure 8: Contents of start-vpn.sh after successful modification]](https://media.shuijingwanwq.com/2026/11/8-1024x120.png)
![[Figure 7: Wstunnel client startup log, batch establishing 10 TCP connections]](https://media.shuijingwanwq.com/2026/11/7-1024x428.png)
[Figure 7: Wstunnel client startup log, batch establishing 10 TCP connections]
Optimization 3: Strict Dual-End MTU Alignment to 1280
This was the deepest pit in this troubleshooting. The WireGuard configuration specified mtu: 1280, but the Clash Verge TUN virtual NIC’s MTU defaults to 1500. Sending a 1500-byte packet from the local machine into a 1280 tunnel inevitably leads to fragmentation, and fragmentation in a high-packet-loss environment is a disaster.
I had to change the MTU from 1500 to 1280 in Clash Verge’s “Virtual NIC Mode” as well.
![[Figure 13: WireGuard configuration on the left is 1280, Clash Verge TUN on the right is also changed to 1280]](https://media.shuijingwanwq.com/2026/11/13-1024x548.png)
Optimization 4: Multi-threaded Download to Break Through QoS Throttling
When downloading the 500+ MB ChatGPT desktop client, the single-threaded wget was throttled to 5.15 KB/s. I planned that if the web version’s speed was still unsatisfactory after optimization, I would switch to the desktop version.
![[Figure 10: wget single-thread download speed is only 5KB/s]](https://media.shuijingwanwq.com/2026/11/10-1024x169.png)
I decisively switched to aria2 with 16 concurrent threads, and the speed soared to 4.4 MB/s:
aria2c -x 16 -s 16 https://persistent.oaistatic.com/codex-app-prod/linux/deb/latest/chatgpt_amd64.deb![[Figure 11: aria2 multi-thread download speed takes off]](https://media.shuijingwanwq.com/2026/11/11-1024x348.png)
VI. Pitfall Record: Do Not Randomly Switch TUN Stacks Under Ubuntu
During the optimization process, I tried switching Clash Verge’s TUN stack from gVisor to System, which resulted in local routing and DNS chaos, causing Codex in the terminal to directly throw errors and GitHub port 443 connection failures.
![[Figure 12: After switching to the System stack, Codex throws errors, GitHub port connection times out and fails]](https://media.shuijingwanwq.com/2026/11/12-1024x396.png)
Conclusion: In the Ubuntu environment, the sandbox isolation of gVisor is the most stable. After switching back to gVisor and restarting the kernel, everything returned to normal.
![[Figure 14: Switching back to the gVisor stack and restarting the kernel]](https://media.shuijingwanwq.com/2026/11/14.png)
VII. Final Results and Comparative Reflection on the Two Troubleshooting Sessions
Final Effect
- Daily replies: Basically no delay, silky smooth streaming output.
- Heavy search tasks: Delay compressed from 17 minutes to within a few minutes.
rqstrerrors: Changed from a screen full of red crosses to occasionally one or two, and the Network panel returned to a screen full of green.
![[Figure 15: After optimization, the ChatGPT web version Network panel returns to healthy]](https://media.shuijingwanwq.com/2026/11/15-1024x634.png)
Core Differences Between the Two Troubleshooting Sessions
| Dimension | October 16 Troubleshooting | This Troubleshooting |
|---|---|---|
| Core Metric | Bandwidth (18 MB/s), TTFB (0.06s), Ping packet loss rate (0%) | TCP retransmission count (13,481/10s), UDP receiver packet loss |
| Conclusion Direction | External server-side degradation / Cloudflare CDN throttling | Local to VPS link packet loss + TCP-over-TCP head-of-line blocking |
| Triggering Event | Gradual slowdown during daily use | Sharp deterioration after host machine kernel maintenance on October 17 (inferred to have been affected on the 16th) |
| Optimization Focus | None (considered no optimization needed at the time) | MSS Clamping, connection pool, dual-end MTU alignment, multi-threaded download |
A Few Thoughts
- Do not blindly upgrade to Pro: If the underlying layer is frantically dropping packets, no matter how fast OpenAI’s computing power is, the data cannot reach my screen. You must troubleshoot the local link first.
- Bandwidth ≠ Stability: The October 16 troubleshooting taught me to “look at TTFB and bandwidth,” and this troubleshooting taught me to “look even more at the TCP retransmission rate.” For streaming long-connection scenarios, packet loss is more fatal than retransmitted bandwidth.
- Wstunnel’s ceiling: It can disguise UDP to evade blocking, but the price is weak resistance to packet loss. If it is still unbearable during the day, the ultimate solution is to switch to Hysteria2, which is based on QUIC and inherently resistant to packet loss.
- Adapt to network tides: Break down tasks and use the desktop client during the day; leave heavy long tasks for after 10 PM.

![[Figure 1: Before optimization, the ChatGPT web version Network panel is flooded with red, stuck in infinite retries]](https://media.shuijingwanwq.com/2026/11/1.png)