Clash Latency Tests Explained: Why Low Ping Doesn’t Mean Faster Downloads
Learn how Clash clients run latency tests, choose test URLs, and handle timeouts—and why low-latency nodes can still lag. Compare bandwidth and packet loss to judge real-world performance.
The milliseconds in a node list measure one request
In Clash clients, a “latency test” usually means the core sends a request through a selected node to a test URL, times the probe, and displays the result in milliseconds. It’s closer to measuring the response time of a small HTTP request than testing bandwidth with a sustained large-file download. An 80 ms result means only that this probe completed quickly; it doesn’t tell you how many megabytes per second the node can download.
The client handles buttons, lists, and result display; the Clash or Clash Meta (now generally called mihomo) core handles the actual connection. Test methods, timing boundaries, and result caching can vary between clients and core versions, so numbers from different interfaces aren’t necessarily comparable. First make sure they use the same test URL and method before deciding which node is faster.
What happens during a typical probe
- You click a node’s latency-test button, or a proxy group runs a scheduled check, and the core receives the test task.
- The core opens an outbound connection through the selected proxy node. It may first need to resolve the node server’s domain and complete a proxy-protocol handshake.
- Traffic passes through the proxy server to the test site. With HTTPS, this also involves negotiating TLS with the destination.
- The core checks whether the response meets its requirements, then returns the elapsed time or a failure status to the client.
Not every step necessarily runs from scratch each time: DNS caching, connection reuse, and protocol session reuse can shorten subsequent probes. Some implementations also send more than one request. That’s why the displayed “latency” shouldn’t be taken as the round-trip time of a single network packet, and isn’t the same as the result of the system ping command.
How test URLs, timeouts, and automatic selection affect results
The test URL determines where the probe goes
Common test URLs return a small response or an HTTP 204 status, such as https://www.gstatic.com/generate_204. A tiny response minimizes the time spent downloading data itself. But the result reflects only the route from the node to the network hosting that service—it doesn’t mean every site will be just as fast.
A node may have a good route to the test service but take a different route to a video site or work platform. CDNs may also direct traffic to different edge servers based on egress location, DNS results, and server load. Switching the test URL from HTTPS to HTTP changes the connection steps, too; don’t mix results from the two and simply pick the lowest number.
A timeout means the test didn’t finish in time—not that the node is permanently down
Suppose a test has a timeout of 5000 ms. If the core can’t complete a valid probe within that window, it may report a failure. The cause could be a failed proxy connection, an unreachable destination, a TLS error, or temporary congestion—not just an offline node. Increasing the timeout to 10000 ms only extends the wait; it won’t make the route faster.
A client may show Timeout, Error, a blank value, or 0 ms to represent different failure or untested states. Check the connection logs for the specific error instead of assuming every abnormal result means packet loss.
url-test picks low-latency nodes; it doesn’t measure peak bandwidth
Here’s an example of a mihomo-style proxy group. Hong Kong 01 and Japan 01 must be node names already defined in your current configuration. This is a configuration snippet, not a complete subscription you can import as-is.
proxy-groups:
- name: Auto Low Latency
type: url-test
proxies:
- Hong Kong 01
- Japan 01
url: https://www.gstatic.com/generate_204
interval: 300
tolerance: 50
lazy: true
interval: 300: The check interval is in seconds—300 seconds, or 5 minutes. It doesn’t run a new test every time you open a webpage.tolerance: 50: The switching tolerance is in milliseconds. It helps prevent unnecessary switching over small differences; it isn’t a bandwidth threshold.lazy: true: Scheduled checks may be skipped while the group is unused, so the results in the list may not be current.
Clicking “Test All,” automatic checks by a proxy group, and health checks for a proxy provider may each use different test entry points and settings. Changing a group’s url doesn’t necessarily change the URL used by the client’s manual test. Check compatibility against your current core version. For related concepts, see the protocol and configuration reference.
Why a low-latency node can still download slowly or buffer video
| Factor | Typical symptom | What to check next |
|---|---|---|
| Limited egress bandwidth or shared congestion | Low latency, but large downloads remain slow | Compare throughput on the same node during peak and off-peak hours |
| Packet loss and retransmissions | Speeds fluctuate; pages occasionally take a long time to load | Track failed tests over multiple runs and compare them with real-world interruptions |
| Destination and CDN routing | The test URL is fast, but a particular video site is slow | Use the same resource and compare nodes |
| Local Wi-Fi or device load | Several nodes slow down at once, and switching nodes makes little difference | Try a wired connection and check CPU usage and background downloads |
| Routing rules don’t match the traffic you’re testing | The test uses node A, but the app’s connection goes through node B or directly | Check the matched rule and proxy chain in the client’s connection log |
A small response requires very little throughput. Even a connection with sustained bandwidth of just 5 Mbps can return a response of a few dozen or a few hundred bytes quickly. Bandwidth limits become much more noticeable with high-bitrate video or large installers. Low latency and slow downloads aren’t contradictory.
Packet loss can make the problem harder to spot. A single probe may succeed and show a good number, while TCP retransmissions and congestion control reduce the effective rate during a sustained transfer. Apps using QUIC also depend on the UDP path; a single HTTPS probe over TCP can’t prove that a node supports UDP or indicate how well its UDP connection performs.
A repeatable process for testing nodes
Step 1: Make sure your traffic actually uses the node being tested
Select the node you want to test, then check the target domain’s entry on the client’s “Connections” page. Verify the matched rule and proxy chain. Page names vary by client, but the key question is the same: which egress did the connection actually use? Don’t leave an automatic-switching group active during the test; a large download and the next page request could end up using different nodes.
The system proxy affects only apps that follow that setting. Command-line tools, games, and some download managers may ignore it. TUN mode can route more traffic, but you still need to check routes, exclusions, and actual connection records. Enabling TUN doesn’t speed things up by itself or turn a low-bandwidth connection into a high-bandwidth one.
Step 2: Keep conditions consistent and run multiple tests
- Stop other high-bandwidth tasks and use the same network, test URL, and timeout setting throughout.
- Test each node 10 times, roughly 5 seconds apart. Record successful response times and the number of failures.
- Compare median response times to see typical wait time, and note the maximum to avoid hiding variation behind one unusually low result.
- Repeat the test during a time you typically use the service—for example, between 8 and 10 p.m.—to see how the node performs at busy times.
If 2 out of 10 requests fail, say “the application-level probe failure rate was 20% in this run”—not “the network packet loss rate was 20%.” A request may involve multiple packets or fail because of DNS, TLS, or the destination service. Even 10 successful requests in a row aren’t enough to prove a connection will be stable over a long period.
Step 3: Check bandwidth and stability with real-world traffic
Choose a file you’re authorized to access with a known size, or the same video, and compare nodes using the same source. For downloads, watch the initial connection and ramp-up for about 10 seconds, then check the sustained rate over 30–60 seconds. For video, track how often and how long it buffers, along with any connection-speed data shown by the player. Both approaches reflect everyday performance better than the node list alone.
Make sure you’re comparing the same units: 8 Mbps is about 1 MB/s in decimal units, and 80 Mbps is about 10 MB/s. Protocol overhead reduces the actual rate. If a tool reports MiB/s, it uses binary units, so the number will be slightly different. Sustained bandwidth tests use subscription data, so limit how often you run them—especially on mobile networks.
Use curl to separate connection time from time to first byte
To see where time is being spent, explicitly route curl through the local HTTP proxy and print the timing for each stage. This example assumes the client’s HTTP or mixed-port listener is set to 7890. That’s a common setting, not a default for every client, so check the client’s port settings before running it.
curl --proxy http://127.0.0.1:7890 \
--connect-timeout 5 \
--max-time 15 \
--output /dev/null \
--silent --show-error \
--write-out 'connect=%{time_connect}s tls=%{time_appconnect}s first_byte=%{time_starttransfer}s total=%{time_total}s\n' \
https://www.gstatic.com/generate_204
This command works in common shells on macOS and Linux. In Windows PowerShell, call curl.exe, put the command on one line, and change --output /dev/null to --output NUL. Specifying the proxy explicitly means you don’t have to guess whether the command line uses the system proxy—but first confirm which egress the client is currently using.
time_connect: With this local HTTP proxy setup, this mainly measures the connection to127.0.0.1:7890; it isn’t the latency to the remote node.time_appconnect: The time when the HTTPS TLS handshake completes. With an HTTP proxy, this also includes earlier steps such as establishing the proxy tunnel.time_starttransfer: The cumulative time until the first response byte arrives, including the connection steps and time spent waiting for the destination service.time_total: The total time for this request. Since the test page returns almost no response body, this doesn’t show large-file throughput.
These are cumulative times measured from the start of the request; don’t add them together. They also may not match the client core’s latency result, since test methods and connection reuse can differ. This command is most useful for troubleshooting comparisons: run it repeatedly with the same node, destination, and options to see whether the slowdown happens during connection setup or before the first byte arrives.
FAQ: Timeouts, packet loss, and automatic node selection
A node test times out, but webpages still load. Should I switch nodes?
First confirm that the webpage is actually using the node, rather than going direct or reusing an existing connection. Then check whether the test URL is reachable through that node and whether the logs show a certificate or connection error. If only the test service is unreachable, try another stable HTTPS URL with a small response. Don’t assume all traffic is unusable just because one test URL failed.
Can I ping the node server to check for proxy packet loss?
You can use ping as a rough check of the path between your device and the server, but the server may limit ICMP responses or give them lower priority. Ping also doesn’t cover the rest of the route, from the proxy’s egress to the destination site. A router in between may ignore probes without dropping application traffic. Consider end-to-end request failures, retransmissions, and real app performance together.
Can an automatic low-latency group always pick the fastest node for downloads?
No. url-test selects nodes based on the latency of small requests and the switching tolerance; it doesn’t continuously compare large-file bandwidth. Checks also run at intervals, so changes in load won’t appear immediately in existing results. If you need reliable download speeds, compare nodes with a short real-world test, then manually select the one that performs best.
What latency is low enough to be usable?
There’s no single threshold that works for every task. For cross-region connections, a steady 150 ms may be better for sustained work than a route that jumps between 40 and 800 ms. Real-time apps also depend on their own latency and UDP performance. Evaluate nodes by asking whether access is reliable, whether the wait is acceptable, and whether throughput meets your needs—instead of sorting by milliseconds alone.
Use latency for an initial shortlist, then confirm your choice with sustained throughput, failure frequency, and performance in the apps you care about. When something looks wrong, change one condition at a time: first fix the egress, then the test destination, and finally compare networks or time of day. This makes your results easier to reproduce and more useful for troubleshooting than repeatedly clicking “Test All.”