Choose by goal: low latency, fixed priority, or connection distribution

url-test selects an available node based on measured latency; fallback uses the first available node in the configured order; load-balance distributes connections according to a chosen algorithm. All three can use health checks, but checking whether a node is available and deciding where a connection goes are separate things. Automatic checks do not mean all three automatically pick the fastest node.

Group type Selection criteria Best for Main limitation
url-test Latency to the test URL and the switching tolerance Everyday browsing with automatic selection of a responsive node Test latency does not measure download bandwidth
fallback Candidate order and node availability Keeping a primary route and switching to a backup on failure A lower-latency node later in the list will not be preferred
load-balance Distribution algorithms such as hashing or round-robin Distributing connections across multiple nodes Does not combine multiple nodes' bandwidth for a single connection

For example, suppose three nodes return test latencies of HK-A: 90 ms, HK-B: 65 ms, and JP-A: 130 ms. An automatic latency-testing group tends to select HK-B when the switching conditions are met. A fallback group ordered HK-A, HK-B, JP-A continues using healthy HK-A. A load-balancing group may route different destinations through different nodes. These figures illustrate routing behavior only; they are not real-world measurements or a speed guarantee.

url-test configuration: use tolerance to smooth out small latency fluctuations

url-test sends requests through candidate nodes to a specified URL and uses the response time to guide selection. It does not simply send an ICMP ping to each node's server. Results can be affected by the node handshake, outbound route, destination site, and connection reuse. Choose a stable test URL that reflects the destinations you actually access, if possible.

proxy-groups:
  - name: Automatic Latency Test
    type: url-test
    proxies:
      - HK-A
      - HK-B
      - JP-A
    url: https://www.gstatic.com/generate_204
    interval: 300
    tolerance: 50
    lazy: true

Understand these three settings and their units

  • interval: 300: Checks run every 300 seconds (5 minutes), not every 300 milliseconds.
  • tolerance: 50: A switching tolerance of 50 milliseconds helps avoid switching over minor latency fluctuations; it is not a request timeout.
  • lazy: true: Enables lazy checks. Periodic checks may pause while the group is unused; this does not mean every app request triggers a speed test first.

Suppose the current node is around 90 ms and another is around 65 ms—a difference of just 25 ms. With a 50 ms tolerance, do not expect the group to switch immediately. If the other node drops to around 30 ms, the difference is more likely to meet the switching threshold. Selection also depends on whether the current node is healthy and whether test results have been refreshed. If the current node is unavailable, tolerance does not force the group to keep using a failed node.

For everyday use, start with a 300-second interval and 50 ms tolerance, then see how it behaves. Reducing the interval to 5 seconds usually just increases test requests, wakes mobile devices more often, and adds load on the server. Setting tolerance to 0 may cause frequent route changes for differences of just a few milliseconds, affecting subsequent connections. For stable sessions, avoid unnecessary switching rather than chasing the lowest number in the UI.

fallback configuration: node order sets priority

The point of fallback is not “use whichever is fastest,” but “use the first healthy node in the list.” If the primary route is healthy, a lower-latency backup will not take its place. This suits setups with a preferred region, fixed exit, or cost-based priority.

proxy-groups:
  - name: Primary and Backup Routes
    type: fallback
    proxies:
      - HK-A
      - HK-B
      - JP-A
    url: https://www.gstatic.com/generate_204
    interval: 300
    lazy: true
  1. If HK-A and HK-B are both healthy, HK-A is selected first.
  2. If a health check marks HK-A unavailable while HK-B is available, subsequent connections use HK-B.
  3. If a later check confirms HK-A is back, the group prioritizes HK-A again.

“Back” here means the health check reports the node as healthy. A 300-second check interval does not mean every failure will trigger a switch within one second, nor does it mean a switch will always happen exactly 300 seconds later. Manual tests, client behavior, and core implementation can all affect status updates. Existing TCP sessions are not automatically migrated to the backup server; disconnected downloads, SSH sessions, or video streams still need to reconnect in the app.

load-balance configuration: distribute connections, not single-connection bandwidth

load-balance distributes connections across multiple healthy nodes. It does not send packets in rotation or automatically combine three 100 Mbps lines into one 300 Mbps tunnel. A single TCP connection still travels through its selected node. You may see multiple nodes carry traffic at once when an app opens multiple connections.

proxy-groups:
  - name: Connection Distribution
    type: load-balance
    proxies:
      - HK-A
      - HK-B
      - JP-A
    url: https://www.gstatic.com/generate_204
    interval: 300
    lazy: true
    strategy: consistent-hashing

Choosing between consistent-hashing and round-robin

  • consistent-hashing: Applies consistent hashing to destination information and tends to keep the same destination on the same exit. The exact hash key depends on the core implementation and whether domain information is available; it does not permanently bind every account session to one node.
  • round-robin: Distributes connections in rotation. Use it when you want to observe how traffic spreads across multiple connections, but different connections to the same website may use different exits.

To use round-robin, change the last line of the example to strategy: round-robin; there is no need to rewrite the whole group. Do not judge load balancing by whether a single download gets faster. Instead, check the client’s connection list to see which proxy chains are used by multiple destinations and new connections.

Even with consistent hashing, a webpage may connect to separate domains for login, images, APIs, and CAPTCHA checks. There is no guarantee that all of them will use the same node. Avoid cross-region load balancing for services that rely on regional access, account security, or a consistent source IP. Changes to the node pool or health status can also remap existing destinations.

Nested select groups: keep manual switching and rule-based routing

Automatic groups do not usually need to handle every traffic entry point directly. A more maintainable setup uses an outer select group to choose the operating mode, with inner groups for latency testing, primary/backup failover, and connection distribution. If testing behaves unexpectedly, you can switch to a specific node in the client UI instead of editing the group type on the fly.

The integrated snippet below can replace the three standalone snippets above. Every candidate name must resolve to an existing node or defined proxy group. Do not add “Proxy Egress” as a candidate in one of its own child groups, or you will create a circular reference.

proxy-groups:
  - name: Proxy Egress
    type: select
    proxies:
      - Automatic Latency Test
      - Primary and Backup Routes
      - Connection Distribution
      - HK-A
      - HK-B
      - JP-A

  - name: Automatic Latency Test
    type: url-test
    proxies: [HK-A, HK-B, JP-A]
    url: https://www.gstatic.com/generate_204
    interval: 300
    tolerance: 50
    lazy: true

  - name: Primary and Backup Routes
    type: fallback
    proxies: [HK-A, HK-B, JP-A]
    url: https://www.gstatic.com/generate_204
    interval: 300
    lazy: true

  - name: Connection Distribution
    type: load-balance
    proxies: [HK-A, HK-B, JP-A]
    url: https://www.gstatic.com/generate_204
    interval: 300
    lazy: true
    strategy: consistent-hashing

rules:
  - DOMAIN-SUFFIX,example.com,Proxy Egress
  - MATCH,DIRECT

If your nodes come from proxy-providers, you can use use in supported groups to reference an existing provider rather than putting the provider name in proxies as if it were a node. Also check the provider's health-check: configure health checks on the relevant provider. Having a url in the group does not mean every provider node is being tested as expected.

Subscription updates may overwrite direct edits. Back up your configuration first, then check whether your client supports local overrides, configuration merging, or temporary editing. These examples cover the core's YAML structure; do not assume every client has the same “Settings” menu. For basic import steps, see Getting Started. For how rules interact with DNS, see Advanced Configuration.

After applying the changes, verify these four things to avoid “the group switched, but traffic didn’t”

  1. Confirm the configuration loaded successfully. After reloading, check the error log first. Incorrect node-name capitalization, indentation errors, an unknown group type, or duplicate top-level keys can prevent the new configuration from taking effect. If the UI still shows the old group, resolve the loading issue before proceeding.
  2. Confirm the mode and matched rule. Check the current outer-group selection under Proxies, verify the target rule under Rules, and confirm the final route in Logs or the connection details. Traffic follows rules only in Rule mode; Global mode may bypass the entry point set up for a specific domain.
  3. Run a test and record the results. Trigger a group test manually and note the time, URL, node latency, and selected node. Use the same test URL when comparing results; latency to different destinations is not an apples-to-apples comparison.
  4. Recheck with a new connection. After a group switches, existing connections may remain on the old node. Make a new command-line request or close the test app's connections before retrying, then check the proxy chain. Do not rely solely on perceived speed after refreshing a page.

Use curl to rule out browser connection reuse

If your local HTTP or mixed proxy listens on 127.0.0.1:7890, run the command below. Use the port in your current client configuration; if 7890 is a SOCKS-only port, you cannot use the HTTP proxy scheme as shown.

curl --proxy http://127.0.0.1:7890 --connect-timeout 10 --max-time 20 --head https://example.com/

In Windows PowerShell, replace the command at the start with curl.exe to avoid command alias differences in some environments. This request uses the example.com rule above and can be checked against the logs to confirm it went through “Proxy Egress.” It verifies only the request path and response for that destination—not every website, UDP traffic, or TUN routing.

With TUN enabled, traffic may be captured by a virtual network interface, but the selected proxy group still depends on the operating mode and rules. Enabling TUN does not turn fallback into a latency-testing group or let load-balance combine bandwidth for a single connection.

Common issues: check test results before changing settings

All latency tests time out, but some websites still open

This usually means “the test URL is unreachable” has been mistaken for “all traffic is unreachable.” Check DNS resolution for the test URL, TLS, and access through the node's exit, then cross-check with another HTTPS URL that returns a small response. Avoid using a login page, a site with challenge redirects, or a rate-limited homepage as a long-term health-check endpoint.

url-test keeps selecting the old node

First check whether the group is in use, whether lazy checks are delaying refreshes, and whether the latency difference exceeds tolerance. Then check whether the current connection was already established. If the UI shows another node is 10 ms faster but tolerance is 50 ms, that is not a configuration failure. Check the core version and group references only if test results are fresh, the difference is significant, and new connections still do not behave as expected.

fallback does not select the lowest-latency backup

That is expected: fallback prioritizes list order. If you want to pick the fastest backup after the primary fails, put a url-test group in the backup position of the fallback group, then verify the nested selection with a real connection. Nesting adds complexity to state tracking; with only two or three routes, a flat setup is easier to troubleshoot.

Websites repeatedly ask you to log in after enabling load balancing

Route that site through a dedicated node or manual-selection group, then check whether new sessions stay stable. Switching from round-robin to consistent hashing may not be enough because the site may use multiple domains to verify region and IP together. Resolve the session issue first, then decide whether distributing connections for that service is still worthwhile.

In short: Use url-test with a reasonable tolerance for everyday browsing, fallback for a preferred primary route, and load-balance only when you specifically need to distribute multiple connections. Keep a select group around them, and verify rule matches, health checks, and new-connection logs. This gives you clearer results than repeatedly changing the test interval.