Three automatic proxy groups: choose by latency, priority, or connection

proxy-groups defines how egress is selected, not the proxy servers themselves. Nodes usually come from proxies or proxy-providers. A group selects an egress only after a rule matches it. Adding a group to the config without referencing it in any rule won't change the traffic route.

First, check which core and version your client actually uses. Clash GUI clients provide the interface; the original Clash core and its successor, Clash Meta's mihomo, parse these fields. The complete config below targets mihomo. Older cores may support different fields and load-balancing algorithms, so check the startup logs and documentation for your version.

TypeSelection criteriaBest forMain limitation
url-testProbe latency and switching toleranceAutomatically choosing the fastest-responding egressProbe latency doesn't indicate download throughput
fallbackList order and health statusKeeping a primary route with a backup if it failsA faster node later in the list may not be used
load-balanceAlgorithm assigns new connectionsSharing connections across multiple available egressesDoesn't combine nodes to increase bandwidth for one connection

url-test: How interval and tolerance work together

url-test probes a specified url through candidate nodes, records the results, and selects an egress accordingly. The measurement is the request time to that probe URL, which depends on both the proxy route and the target's response. It's not an ICMP ping or a full performance test of a video service or file host.

Know the units of these three settings

  • url: The health-check URL. Choose a small, reliable HTTPS endpoint that candidate nodes can reach, such as one that returns HTTP 204.
  • interval: 300: The interval between periodic checks, in seconds—about once every 5 minutes. It's not 300 milliseconds or a connection timeout.
  • tolerance: 50: The switching tolerance, in milliseconds. It helps prevent frequent route changes caused by small latency fluctuations. It's not a packet-loss rate or the maximum acceptable latency.

Suppose the current node's latest probe is 105 ms and another node's is 80 ms—a difference of just 25 ms. With a 50 ms tolerance, don't expect an immediate switch based on that small advantage alone. If the current node rises to 155 ms while the other stays at 80 ms, the 75 ms gap makes a switch more likely. These figures illustrate how tolerance works; they aren't measurements from this site. The final choice still depends on the core's health state and implementation.

The check interval doesn't guarantee a recovery time

Changing interval from 300 to 60 increases probe frequency, but doesn't guarantee that all traffic will recover within 60 seconds of a failure. Probes take time, and existing connections may wait for a timeout. The more candidate nodes you have, the more periodic requests are sent. For everyday use, start at 300 seconds and adjust based on the logs.

In mihomo, lazy affects periodic checks for unused groups. For troubleshooting, set it explicitly to false to avoid confusion over whether an unused group is being probed continuously. If your nodes come from a provider, also check its health-check setting. Provider checks and group-level probes are separate timers.

fallback: Choose the first available egress in the list

fallback selects the first available node in the candidate list. If the list is “Node A” followed by “Node B,” expect A to be used whenever its health check passes—even if A is at 180 ms and B at 60 ms. To prioritize the fastest node, use url-test; changing the probe interval won't help.

  1. Put your everyday primary route first in proxies, followed by backup routes.
  2. Use a check URL that all candidate nodes can reach, so restrictions on the target site aren't mistaken for node failures.
  3. Reload the config, check the group's node order on the Proxies page, then trigger a check manually.
  4. Temporarily disable the service for the primary node and see whether new connections switch to the backup. Restore the service after testing.

Once the primary node is marked available again, the priority logic will favor the node earlier in the list. This works well for a primary route with a backup, but doesn't migrate existing TCP connections. Short web requests usually reconnect; downloads, SSH sessions, and long-lived video connections may need the app to retry.

load-balance: Distribute connections, not bandwidth

load-balance distributes connections across available candidate egresses according to an algorithm. In mihomo, set the algorithm with strategy; this example uses consistent-hashing. For logins, payments, and session-based services, a stable egress is often more important than an even distribution. Start with consistent hashing, or route those domains to a fixed node.

strategy valuePurposeWhat to check
consistent-hashingMap destinations to egresses with relative consistencyKeeps the same service on one egress when possible, but node changes may remap it
round-robinRotate assignments for new connectionsConnections to the same site may use different egresses

The hash inputs, domain handling, and support for additional algorithms vary by core implementation. “Consistent hashing” doesn't mean a permanently fixed public IP. Nodes going up or down, reloading the config, or changing the candidate list can all change the mapping. If a service requires a fixed egress, use a rule that points directly to a manual-selection group.

For example, if a browser opens 10 connections at once, a round-robin algorithm may assign them to different nodes. Each established TCP connection still uses a single egress. HTTP/2 and HTTP/3 may also reuse connections, so refreshing a page won't necessarily trigger a new assignment. To verify load balancing, check the policy chain and actual node in the connection log; repeatedly refreshing the same IP lookup page isn't enough.

Complete YAML example: all three groups with a manual selector on top

This complete example shows a valid mihomo config structure. The select group acts as a single entry point, letting you switch between low latency, primary/backup, and load-balancing modes. The two nodes use documentation-only addresses, 192.0.2.10 and 192.0.2.11, and cannot connect to real proxies. Before use, replace each complete node definition with the protocol, address, port, and credentials provided by your service.

config.yaml · mihomo config example
mixed-port: 7890
allow-lan: false
mode: rule
log-level: info

proxies:
  - name: Node A
    type: ss
    server: 192.0.2.10
    port: 8388
    cipher: aes-128-gcm
    password: "example-only-change-before-use"
  - name: Node B
    type: ss
    server: 192.0.2.11
    port: 8388
    cipher: aes-128-gcm
    password: "example-only-change-before-use"

proxy-groups:
  - name: Egress selector
    type: select
    proxies:
      - Low latency
      - Primary/backup
      - Load balancing
      - Node A
      - Node B
      - DIRECT

  - name: Low latency
    type: url-test
    proxies:
      - Node A
      - Node B
    url: https://www.gstatic.com/generate_204
    interval: 300
    tolerance: 50
    lazy: false

  - name: Primary/backup
    type: fallback
    proxies:
      - Node A
      - Node B
    url: https://www.gstatic.com/generate_204
    interval: 300
    lazy: false

  - name: Load balancing
    type: load-balance
    proxies:
      - Node A
      - Node B
    url: https://www.gstatic.com/generate_204
    interval: 300
    lazy: false
    strategy: consistent-hashing

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

Rules are matched from top to bottom. In this example, example.com and its subdomains go direct; all other traffic uses “Egress selector.” This is a demonstration rule, not a complete split-routing setup. mixed-port: 7890 provides a combined HTTP and SOCKS entry point. Whether the system proxy is enabled is still controlled by the client or system settings.

Using a subscription provider

If your existing config defines a proxy-providers entry named “Subscription Nodes,” you can replace the static candidates in the groups below with this version. use references a provider name; proxies references a node or group name. They belong to different namespaces. This snippet depends on an existing provider definition and can't run as a complete config on its own.

proxy-groups snippet · reference an existing provider
proxy-groups:
  - name: Low latency
    type: url-test
    use:
      - Subscription Nodes
    url: https://www.gstatic.com/generate_204
    interval: 300
    tolerance: 50
    lazy: false

Don't edit a temporary config that will be overwritten by a remote subscription. If your client supports overrides, merges, or extension configs, save custom groups there; check the client documentation for the exact location. Update the subscription afterward and confirm the groups and rules are still present to verify that your changes persist.

Nested groups: test latency within regions, fail over between regions

For a more structured setup, create a separate url-test group for each region, then have an outer fallback group reference them in priority order. For example, “Primary Region Test” should contain only nodes in the primary region, and “Backup Region Test” only nodes in the backup region; keep the primary region first in the outer group. This lets each region optimize for latency while preserving priority between regions.

  • The outer group can reference only groups that have already been defined. Don't add the group itself to its candidate list or create a circular reference, such as A referencing B while B references A.
  • The outer group sees the path currently selected by the inner group; don't assume it flattens all the nodes and compares them again.
  • The inner and outer groups have their own check intervals, so recovery may take several update cycles. Test one layer first, then add the second.
  • For services sensitive to login sessions, route traffic to a fixed node or a select group instead of sharing the load-balancing policy used for bulk downloads.

For automatic routing during everyday browsing, “outer select + inner url-test” from the example is usually enough. More nesting makes connection logs harder to troubleshoot. Add layers only when you need distinct regional, cost, or primary/backup priorities.

Common misconfigurations and how to verify them

SymptomCheck firstWhat to do
The low-latency group doesn't switch nodesCurrent latency gap, tolerance, and time of last probeRun a manual check, then confirm that a rule matches this group
The primary/backup group keeps using a slower nodeList order and health statusThat's priority by list order. For latency-based selection, use url-test
All nodes time out at onceCheck the probe URL, local DNS, and system clockFirst test a single node against the same probe endpoint instead of just changing the group type
Config reports that a proxy can't be foundGroup, node, and provider names, plus indentationCheck every reference character by character; use spaces, not tabs, in YAML
An existing download still has problems after switching nodesCheck whether it is still using an existing connectionReconnect the affected service; if needed, close only its connection entry
Custom groups disappear after a subscription updateCheck whether you edited the source config or a temporary oneSave changes using a persistent override supported by the client

Verify the active result in four steps

  1. Validate the config: Use the client's config checker. If running mihomo directly, execute mihomo -t -f config.yaml. A successful check means the config parses; it doesn't confirm that node credentials or network access work.
  2. Reload the config: Enable the updated config on the Config page and check the logs for unknown fields, duplicate names, or missing references. When merging into an existing config, don't create duplicate proxy-groups or rules keys at the same level.
  3. Check the rule chain: In Rule mode, make a new request and verify the matched rule, outer group, inner group, and final node on the Connections page. Global or Direct mode may bypass the rule entry you're trying to test.
  4. Test the services: Check web access, sign-in to the target service, and an actual download separately. Note the test time, egress node, and probe latency before deciding whether to change the 300-second interval or 50 ms tolerance.

Choosing a group comes down to three questions: Want to automatically use the lower-latency option? Choose url-test. Need a primary route with a backup if it fails? Choose fallback. Want multiple egresses to handle different new connections? Choose load-balance. Choose the group that fits your needs before adjusting parameters; it's easier to verify and maintain than layering every strategy together.