Network Guide Featured Tags: Clash url-test Mihomo

Clash url-test Keeps Picking Slow Nodes?Tune Interval and Tolerance

Automatic url-test policy groups should pick a healthy outbound—yet many profiles still hop to high-latency or unstable nodes right after a health check. The gap is usually configuration: interval, tolerance, lazy, and the probe url must match how you use the tunnel. A Chinese walkthrough of the same topic lives here (zh-CN) if you prefer that language.

Approx. 26 min read
Clash Editorial
On-site guides to open in parallel:

1. What url-test Actually Optimizes

You enabled automatic health checks because you wanted the fastest outbound without babysitting YAML every hour. In practice, url-test does not read your mind: it periodically issues lightweight HTTP requests through each candidate proxy, records latency (and sometimes packet loss semantics depending on the core), then picks a winner under rules you configured with interval, tolerance, and optional lazy behavior. When the chosen node feels slow for Netflix, Cursor, or games, the mismatch is often between what the probe measures and what your workload needs—not a mysterious bug inside Mihomo or Clash Meta.

Another common misconception is that a low ping to www.gstatic.com/generate_204 guarantees a low ping to every CDN on Earth. Probes are intentionally tiny: they warm a TLS stack, hit a predictable endpoint, and return quickly. Real applications open different hostnames, carry heavier payloads, and may traverse different anycast edges even when the exit city label on your subscription looks identical. Treat url-test as a relative ranking tool among your own nodes against one reference URL—not as a universal speedometer.

Finally, remember that policy groups sit downstream of rules. If traffic never reaches the group you tuned, no amount of interval tweaking will change behavior. When symptoms look like “bad nodes,” confirm the connection log shows the expected group name before you chase probe math. If you are new to how profiles fit together, skim the configuration documentation first—this article assumes you understand rule order, group types, and where DNS hooks in.

2. interval, tolerance, lazy: Plain-Language Semantics

interval controls how often the core re-runs health checks for members of the group. Short intervals make your profile feel responsive after a node dies, but they also amplify noise: Wi-Fi handoffs, brief congestion, or an overloaded probe target can create micro-spikes that trigger unnecessary node switching. Long intervals keep sessions steadier at the cost of riding a degraded path longer before the next measurement cycle.

tolerance introduces hysteresis. Without it, the core might bounce between two outbounds whose probe latencies differ by only a few milliseconds—noise that has nothing to do with user-visible quality. A tolerance window says, in effect: “If the current winner is still within X milliseconds of the theoretical best, do not rip it out from under open connections.” Larger tolerance reduces flapping; excessively large tolerance can lock you onto a mediocre node when a clearly better peer is available.

lazy (when supported by your build) changes when probes run. In lazy modes, the core may defer or coalesce probing work until the group is actually consulted, which can reduce background chatter on battery-powered laptops. The trade-off is psychological: dashboards look quieter until you navigate to a rule that touches the group, and then you may see a burst of measurements. Neither “always eager” nor “lazy” is universally correct—match the behavior to how often the group is used and how painful a cold start is for that traffic class.

Across Mihomo forks and Clash Premium derivatives, YAML keys are broadly compatible, but log wording differs. Focus on three observable artifacts: per-node probe latency lines, group-level “selected” transitions, and whether switches coincide with interval boundaries or with external events (sleep, network change, subscription refresh). Developers who split IDE traffic often pair this tuning with Cursor and GitHub split rules so long-lived HTTPS sessions do not fight the same url-test pool as bulk git clones.

3. Why You Still Land on “Slow” Nodes

The headline failure mode is probe URL mismatch. If your probe uses a host that is anycasted aggressively near the proxy exit, every node looks artificially similar—or artificially good—while the sites you care about terminate thousands of kilometers away. Swapping the probe to something closer to your real traffic (still HTTPS, still stable) often changes rankings more than nudging tolerance by ten milliseconds.

A second failure mode is congestion asymmetry. Probes are small GETs; video uploads, package restores, and AI streams are sustained high throughput flows. A node that wins micro-benchmarks can still buffer badly under load or carry aggressive carrier-grade NAT that hurts long flows. When probes lie, complement url-test with operational discipline: split sensitive hostnames into dedicated groups, or pin known-good outbounds with fallback semantics when you prioritize stability over optimality.

Third, watch for DNS and fake-IP interactions. If the resolver path for probe hostnames differs from the resolver path for your application hostnames, you may measure latency to one front door while browsing through another. Symptoms include nodes that “look fine” in the panel yet stall on TLS. Cross-read our fake-IP and DNS troubleshooting guide before you blame url-test itself.

Fourth, subscription hygiene matters. Providers sometimes rename nodes, deduplicate entries, or reorder lists after updates. If stale tags linger in proxy-groups, your group may reference outbounds that silently disappeared and were replaced by near-duplicates with different labels—creating the illusion that the selector “keeps picking weird nodes.” If your list emptied after an update, start with the empty node list checklist, then return here.

4. Reading Logs Without Guessing

Good tuning starts with timestamps. Enable debug or info logs (per client UI) and mark three columns mentally: event time, group name, outbound name. When a switch occurs, check whether it aligns with a multiple of your configured interval. If switches happen off-schedule, suspect external triggers—interface up/down events, manual UI selection, or hot reload after saving YAML.

When two nodes oscillate, print their reported probe numbers side by side. If the delta is consistently smaller than your configured tolerance, yet switches still occur, verify you edited the effective profile actually loaded by the running core (not a stale copy in Downloads). Many GUIs maintain a working directory that differs from where you think you saved the file.

For Linux daemons, journald timestamps paired with systemctl reload events help separate “probe noise” from “operator restarted the service.” Our Linux systemd walkthrough shows a reproducible layout for unit files and config paths—useful context when logs show reload storms that reset selection state.

5. A Reproducible Tuning Ladder

Step A — Freeze variables: pick one representative workload (for example, a single HTTPS site that misbehaves), one browser, and one interface (Ethernet vs Wi-Fi). Disable unrelated experiments like aggressive region hopping in other groups until you understand this group.

Step B — Validate the probe URL: try a neutral, small 204-style endpoint reachable from all nodes; avoid endpoints blocked in some regions. Document the exact URL string in your YAML comment so future you remembers why it exists.

Step C — Widen tolerance first: if you see rapid oscillation between two similarly ranked nodes, increase tolerance modestly (for example, double it) and observe for two full interval cycles. Oscillation should slow before latency drifts upward permanently.

Step D — Lengthen interval: once flapping calms, stretch interval to reduce background probes and connection churn—especially for WebSocket-heavy stacks referenced in our MCP routing article, where session longevity beats marginal RTT wins.

Step E — Revisit lazy: if the group is rarely used, lazy probing can cut idle work. If the group fronts your default browser path, lazy may cause perceptible “first hop after idle” delays—trade accordingly.

Step F — Split traffic: when tuning cannot reconcile competing workloads, duplicate the group: one url-test tuned for interactive traffic, another for bulk downloads. The duplication is honest engineering, not failure.

6. YAML Sketches You Can Adapt

Below is a conservative starting profile for a general-purpose PROXY bucket. Numbers are illustrative—treat them as a baseline, not gospel.

proxy-groups:
  - name: AUTO-GENERAL
    type: url-test
    proxies:
      - TOK-A
      - TOK-B
      - SGP-A
    url: https://cp.cloudflare.com/generate_204
    interval: 300
    tolerance: 50
    lazy: true

If interactive apps still stutter, consider a fallback chain for that hostname class instead of a wide url-test pool—document the operational meaning in comments so teammates do not “optimize” it back to flapping.

7. url-test vs fallback vs load-balance

url-test optimizes for measured latency to a probe among many candidates—great when peers are interchangeable and you want the “currently quickest” exit. fallback walks an ordered list until a member is healthy, which encodes human intent (“try Tokyo first, only then Singapore”) more clearly than overloading url-test with tiny tolerances. load-balance spreads flows for throughput, not minimal RTT; it is the wrong tool when you expect a single TCP session to magically become faster.

Mixing semantics across nested groups is a frequent foot-gun: a select group may point to another url-test child, and logs will show switches at both layers. When diagnosing, expand the effective tree mentally and note which layer actually owns the outbound socket.

8. Field Checklist Before You File an Issue

Symptom Likely cause First knob
Rapid back-and-forth between two cities Probe noise smaller than tolerance expectation Widen tolerance; verify effective YAML
Good panel latency, bad real sites Probe URL anycast vs app CDN geography Change url; split rules per hostname
Slow only after idle Lazy cold start or idle TCP resets Toggle lazy; lengthen interval cautiously
Switches at subscription refresh Renamed outbounds / provider merge Diff providers; prune dead proxies
Tip: Screenshot your probe results alongside a traceroute-style app measurement only after you align DNS modes—otherwise you compare unrelated paths. If TLS errors dominate, jump to TLS handshake timeout troubleshooting before changing intervals again.

9. Deeper Edge Cases Worth One Paragraph Each

IPv6 vs IPv4

Some nodes advertise dual-stack exits but one family is rate-limited or blackholed. Probes over the healthy family can mask broken user traffic if applications prefer the other family. When weirdness is familial, test with IPv6 temporarily disabled at the OS level and re-run probes.

UDP-heavy workloads

Default probes are TCP-centric HTTP checks. Voice, games, and QUIC may not correlate. Do not expect url-test to optimize Discord unless your probe and rules intentionally represent that path; see Discord voice on Windows for process-level ideas.

TLS fingerprint middleboxes

If a node rewrites TLS or breaks HTTP/2 coalescing, micro-latency can look fine while application layers stall. When logs show handshake retries, pivot to the TLS handshake timeout article before tuning intervals again.

10. Summary

Clash url-test groups are powerful when you treat them as measured comparisons among your own outbounds, not as a promise of omniscient routing. Tune interval to balance responsiveness and churn; tune tolerance to absorb meaningless jitter; decide lazy based on whether cold starts or background probes hurt you more. Align the probe url with the traffic class you care about, read Mihomo logs with timestamps, and split policy groups when interactive and bulk workloads fight for the same knob.

Compared with opaque one-tap VPNs, explicit YAML rewards the same habits as good observability: small controlled experiments, written-down baselines, and diffs you can review. When you are ready to install or refresh the client, use the official download page for verified builds, then iterate on measurements—not vibes.

Download Clash for free and experience the difference