Clash TUN Mode vs System Proxy: How Traffic Interception Differs
Compare TUN mode and system proxy in Clash: interception layer, coverage, and compatibility. Learn which apps bypass system proxy and when to switch to TUN mode.
Compare TUN mode and system proxy in Clash: interception layer, coverage, and compatibility. Learn which apps bypass system proxy and when to switch to TUN mode.
Before you touch a single toggle in Clash, it helps to understand how traffic actually gets "hijacked" into the proxy engine in the first place. Clash and its popular fork Clash Meta (mihomo) offer two fundamentally different approaches: system proxy and TUN mode. Both aim to solve the same problem — routing outbound requests from your device into Clash's rule engine before forwarding them — but they intervene at completely different layers, which directly shapes their coverage, compatibility, and setup effort.
A system proxy is a configuration interface exposed by the operating system itself. In essence, it tells any app that supports the setting: "send your HTTP/HTTPS requests to this address and port first." Windows and macOS both have built-in system proxy settings, and browsers, some download managers, and IDE networking components read from this configuration. TUN mode takes a completely different approach. It creates a virtual network interface inside the OS, which the system treats as a real network exit point. Any IP packet that the routing table decides should go through this exit — regardless of which process created it or what protocol it uses — flows into this virtual adapter first, where the Clash core parses it, matches rules, and forwards it to the right node.
System proxy wins on simplicity, low resource usage, and quick on/off switching — it's usually the first method anyone tries with Clash. But it only works because apps have to actively "cooperate": each program reads the proxy address from the system or an environment variable and connects to it on its own to relay requests. That means only apps that follow this convention actually get intercepted correctly.
This is exactly where the problem lies. Not every networked app respects system proxy settings. Common cases where traffic slips past the proxy include:
HTTP_PROXY/HTTPS_PROXY.In other words, system proxy is more of a "gentleman's agreement": cooperative apps forward traffic properly, while uncooperative ones just connect directly regardless. This is exactly why some users see Clash running fine yet a specific app still shows "not connected to proxy" or produces unexpected results — it's rarely a rule mistake; it's usually that the app never went through the system proxy path to begin with.
TUN mode takes a much more thorough approach. It doesn't rely on whether an app "wants" to cooperate — instead, it inserts a virtual network adapter directly into the OS network stack and, combined with routing table rules, redirects nearly all qualifying IP packets on the device into this virtual interface. Once packets enter the virtual adapter, the Clash Meta (mihomo) core handles protocol parsing in userspace (commonly implemented via gVisor or the system's native stack), domain matching, and rule evaluation, then decides which proxy node — or direct connection — to route through.
Because interception happens at the network layer rather than the application layer, TUN mode is largely app-agnostic. Browsers, CLI tools, game clients, and even the OS's own background services all get managed uniformly as long as their traffic matches the routing rules — including UDP traffic that system proxy simply can't touch. That's why anyone who needs fine-grained routing for games, voice chat, or cross-platform clients eventually ends up switching to TUN mode.
TUN mode requires creating a virtual network adapter, which typically needs administrator privileges (run as administrator on Windows, or grant network extension/root permissions on macOS/Linux). It's normal to see a system authorization prompt the first time you enable it.
Broader coverage doesn't come free. Since traffic is intercepted at the network layer, passed through a userspace protocol stack, and then forwarded onward, packets go through an extra layer of encapsulation and parsing. This adds a small performance overhead in theory, which may be noticeable on low-end devices or in latency-sensitive scenarios. There's also potential for the virtual adapter to interact with your local routing table, firewall rules, and VPN clients:
By comparison, system proxy carries none of these low-level risks: settings take effect instantly and revert instantly when turned off, and troubleshooting is more straightforward — it's almost always a case of some app not reading the proxy settings. That's why system proxy remains the default choice for plenty of lightweight use cases.
| Comparison | System Proxy | TUN Mode |
|---|---|---|
| Interception layer | Application layer, depends on apps reading proxy settings | Network layer, unified interception via virtual adapter and routing table |
| Protocol coverage | Mainly HTTP/HTTPS; limited UDP support | Covers TCP and UDP with virtually no protocol restrictions |
| Requires elevated permissions | Usually no administrator privileges needed | Requires administrator/root privileges to create the virtual adapter |
| Compatibility risk | Low, but some apps bypass the proxy entirely | Possible conflicts with other virtual networking tools |
| Best suited for | Everyday browsing, light workloads, quick temporary use | Game traffic splitting, CLI tools, fine-grained per-process control |
If a specific app's traffic never seems to follow your proxy rules, it's usually one of the following:
Rather than hunting down proxy settings in every individual app, it's usually faster to switch to TUN mode and solve the "incomplete coverage" problem once, at the network layer.
Based on the comparison above, here's a reasonably clear rule of thumb:
process-name) offers a level of granularity that's impossible at the application layer.Most clients support running system proxy and TUN mode side by side or switching between them quickly. Try system proxy first to confirm your nodes and rules are working correctly, then switch on TUN mode once everything checks out to expand coverage — this makes troubleshooting much clearer.
From a config file perspective, system proxy needs no extra declaration in your Clash config — it's controlled by a toggle in the client UI that calls a system API directly. TUN mode, on the other hand, usually requires explicitly declaring related fields in the config, such as whether it's enabled, which protocol stack to use, and whether it takes over DNS. Here's a common example from Clash Meta (mihomo):
tun:
enable: true
stack: system
dns-hijack:
- any:53
auto-route: true
auto-detect-interface: true
auto-route controls whether the routing table is automatically configured to send traffic into the virtual adapter, while dns-hijack takes over DNS queries so certain domain resolutions don't slip past rule matching. Most GUI clients already wrap these fields into simple toggles, so most users never need to hand-edit the config — but knowing what they do helps when troubleshooting occasional connection glitches.
Do I still need system proxy once TUN mode is on? Generally not — TUN mode's coverage already includes everything system proxy handles, and running both at once can confuse routing decisions. Pick one.
Does TUN mode slow down all my traffic? There's some overhead from the extra encapsulation and parsing, but on most modern devices it's barely noticeable. Speed differences you notice are far more likely caused by the proxy node's line quality than by the interception method itself.
Is there a TUN mode equivalent on mobile? On Android, it's typically implemented through the VpnService API, which works conceptually the same way as a desktop virtual adapter and can intercept traffic that app-layer methods miss. On iOS, similar functionality relies on the Network Extension framework.