Split Routing Guide
Rule-based routing is Clash's core superpower. This article walks through everything from basic syntax to advanced techniques for controlling exactly where every connection goes.
Why Rule-Based Routing Matters
Rule-based routing is what separates Clash from a simple proxy toggle. A well-designed rule set turns Clash into an intelligent traffic controller: everyday local sites like your bank or Amazon load directly, at full speed, with zero added latency; a streaming service, GitHub, or a gaming server in another region gets automatically routed through a proxy node, seamlessly; ad and tracker domains get blocked outright, saving bandwidth and avoiding unnecessary delay.
Before rule-based routing existed, you were stuck with only two states — proxy on or proxy off — meaning either your everyday local sites got slower, or the sites you needed a proxy for stayed unreachable. Rule-based routing gives you the best of both, which is exactly why mastering rule configuration is a must for any serious Clash user.
The Clash.Meta (Mihomo) core has significantly extended the rule system, adding types like RULE-SET, DOMAIN-REGEX, and NETWORK, and adding support for large community-maintained rule sets (like Loyalsoldier's clash-rules), which makes rules both more expressive and far easier to maintain.
Rule Syntax Basics
In a Clash configuration file (YAML), the rules field is an ordered list. Each rule follows this format:
TYPE,VALUE,TARGET_POLICY_GROUP[,no-resolve]
Rules are matched top to bottom, and the first match wins — later rules are never checked once a match is found. That makes ordering critical: specific rules should come first, general ones last. A typical rule file looks like this:
rules:
# 1. LAN and special addresses connect directly
- IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
- IP-CIDR,10.0.0.0/8,DIRECT,no-resolve
- IP-CIDR,127.0.0.0/8,DIRECT,no-resolve
# 2. Ad blocking (kept near the top for priority)
- RULE-SET,reject,REJECT
# 3. Domains that should be proxied
- RULE-SET,proxy,Proxy
# 4. Local/everyday domains connect directly
- RULE-SET,direct,DIRECT
- GEOIP,US,DIRECT
# 5. Catch-all rule (must be last)
- MATCH,Proxy
That final MATCH line is a required catch-all — any traffic that didn't match an earlier rule falls through to it. It's usually set to route through the proxy, so unrecognized domains still reach the sites and services they need to.
Common Rule Types
DOMAIN matches a domain exactly, with no subdomains. DOMAIN,google.com,Proxy matches only google.com, not www.google.com.
DOMAIN-SUFFIX matches a domain and all of its subdomains — this is the rule type you'll use most. DOMAIN-SUFFIX,google.com,Proxy matches google.com, www.google.com, mail.google.com, and so on.
DOMAIN-KEYWORD matches if a domain simply contains a given keyword. It's convenient but a double-edged sword — easy to overreach. DOMAIN-KEYWORD,google,Proxy matches google.com, but also googledrive.com or even somegooglestuff.net, so use it carefully.
IP-CIDR matches a destination IP range — commonly used for local network ranges (like 192.168.0.0/16) or a specific service's known IP block. By default, an IP-CIDR rule resolves domains to IPs first; if you don't want that (for example, under Fake-IP mode), append no-resolve.
GEOIP checks which country a destination IP belongs to, based on a geolocation database. GEOIP,US,DIRECT (or the equivalent code for your own country) shows up in nearly every Clash config — it routes local IPs directly so everyday local services never get needlessly proxied. The Mihomo core uses MaxMind GeoIP or GeoSite data, which updates automatically.
RULE-SET references an external rule set file (or an inline one) — the recommended way to manage large numbers of rules, covered in the next section.
MATCH matches everything unconditionally, and can only appear as the final catch-all rule at the very end of the list.
Rules & Policy Groups
The "target policy group" in a rule refers to a name defined in the proxy-groups section of your config, or one of the built-in keywords DIRECT or REJECT.
A policy group's job is to bundle multiple nodes together and define how one gets selected:
select groups let you manually pick a node or sub-group — a good fit for a top-level "Select Node" group. Whichever node you've currently selected is where matched traffic goes.
url-test groups automatically test latency and pick whichever node responds fastest — ideal for an "Auto Select" group. Parameters like url (the test target), interval (test frequency in seconds), and tolerance (the latency margin before switching) control its behavior.
fallback groups try nodes in order and use the first one that's reachable, automatically failing over to the next when the current one drops — a good option when reliability matters most.
load-balance groups spread traffic across multiple nodes at once, which can help with concurrent download throughput.
Combining rules with policy groups gives you fine-grained control over "what traffic uses which strategy": route streaming traffic to a group with region-unlocked nodes, route large downloads to a group of high-bandwidth nodes, and let everyday browsing use an "Auto Select" group tuned for low latency.
Rule Sets
Manually maintaining hundreds of domain rules is tedious and goes stale fast. RULE-SET lets you reference an external file or URL as a rule set, effectively outsourcing rule maintenance to a community project.
The most widely used community rule set is Loyalsoldier's clash-rules project, which provides categorized sets like reject (ad blocking), proxy (domains to proxy), and direct (domains to connect directly). It updates automatically every day and covers tens of thousands of entries — far more coverage and accuracy than anyone could maintain by hand.
Referencing it in your config looks like this:
rule-providers:
reject:
type: http
behavior: domain
url: "https://cdn.jsdelivr.net/gh/Loyalsoldier/clash-rules@release/reject.txt"
path: ./ruleset/reject.yaml
interval: 86400 # updates once a day
proxy:
type: http
behavior: domain
url: "https://cdn.jsdelivr.net/gh/Loyalsoldier/clash-rules@release/proxy.txt"
path: ./ruleset/proxy.yaml
interval: 86400
rules:
- RULE-SET,reject,REJECT
- RULE-SET,proxy,Proxy
- GEOIP,US,DIRECT
- MATCH,Proxy
The Mihomo core downloads these rule set files to a local cache on first launch, then refreshes them automatically every interval seconds. Even if you lose connectivity, the cached rule set keeps working normally.
Writing Custom Rules
The subscription config your provider gives you usually already includes a sensible rule set, but you may want to add your own rules for specific situations. Clash Plus (Mihomo) supports adding rules through the GUI's "Override" feature, or merging custom config via a "Mixin," without touching your original subscription file.
Scenario 1: Force a specific app to connect directly. If an app you expect to connect directly is unexpectedly getting proxied because the rule set doesn't cover it, add a DOMAIN-SUFFIX rule pointing to DIRECT near the top of the list (so it takes priority):
prepend-rules:
- DOMAIN-SUFFIX,example-local-app.com,DIRECT
- DOMAIN-SUFFIX,example-cdn.net,DIRECT
Scenario 2: Pin a streaming service to specific nodes. Netflix's catalog is tied closely to the region your connection appears to be in, so it often needs dedicated unlock-capable nodes. You can create a dedicated policy group and point Netflix's domains at it:
prepend-proxy-groups:
- name: "Netflix Unlock"
type: select
proxies:
- US Netflix Node 1
- US Netflix Node 2
prepend-rules:
- DOMAIN-SUFFIX,netflix.com,Netflix Unlock
- DOMAIN-SUFFIX,nflxvideo.net,Netflix Unlock
- DOMAIN-SUFFIX,nflximg.net,Netflix Unlock
Scenario 3: Block a specific ad domain. If you spot an ad domain that isn't covered by your rule set, add a REJECT rule directly:
prepend-rules:
- DOMAIN-SUFFIX,specific-ad-domain.com,REJECT
Debugging Rules
When a site won't load or seems to be taking the wrong route, the "Connections" tab is your best debugging tool. Open the connection log in Clash Plus, reload the site in question, and check which rule matched (the Rule column) and where the connection ended up (the Chain column). Most of the time, the problem is obvious at a glance — either the wrong rule matched, or the node itself is failing to connect.
If a domain is showing up as "direct" but should be proxied, add a DOMAIN-SUFFIX rule pointing to your proxy group in the Override config. If a local site that should connect directly is being proxied instead, add a rule pointing to DIRECT.
http://127.0.0.1:9090/ui) offers more detailed connection logs and rule-testing tools than the desktop GUI, and is the recommended tool for serious rule debugging.
Want to dig into DNS and privacy next?
Rule-based routing paired with Fake-IP DNS is what makes truly leak-free traffic splitting possible. The next article covers this in detail.