Why people search for tcp-concurrent
A typical search path reads like “Clash Meta tcp-concurrent how to turn on” right after someone notices odd first packet delays on international SaaS, CDN-heavy downloads, or game patches. They already configured healthy nodes, maybe even tightened url-test intervals, yet some sessions still feel like they “pick the wrong IP” on the first try. The feature is not a magic throughput booster; it is a dial strategy. If your resolver only ever hands back a single address, racing has nothing to race. When the answer set is richer—multiple anycast edges, regional load-balancers, or IPv4 and IPv6 in the same bag—parallel setup can surface the survivor that actually answers promptly.
Conversely, operators in regulated networks sometimes need the opposite guarantee: every flow should present as a single straightforward TCP attempt because security analytics count SYNs, or because an upstream expects one canonical path per client credential. Those readers arrive with the same keyword but want a crisp recipe to disable racing. This article covers both directions with the same YAML knob, because symmetry keeps runbooks short.
What the option does in plain language
Official upstream wording describes tcp-concurrent as enabling concurrent TCP connections that use all IP addresses produced by DNS for the target, keeping the first successful session. That framing matters: it is not deferring work to QUIC or altering your TLS fingerprint; it is strictly about how the proxy chooses which socket finishes the three-way handshake soonest among several candidate destinations tied to one logical hostname.
Think of the resolver as handing your core a small bucket of addresses. With the flag off, the core may still try more than one path eventually, depending on other timeout logic, but you are not explicitly inviting synchronized trials. With the flag on, you volunteer for a burst of connection attempts bounded by that bucket. Success keeps one TCP session; the others should disappear from the user-visible story. The user experience change, when it exists at all, is usually a smoother cold open when one of the addresses in the bundle was stale, overloaded, or routed through a bad peering arrangement while a sibling address remained healthy.
Compatibility: Meta cores versus everything else
Treat tcp-concurrent as a Mihomo / Clash Meta family feature. Classic Clash Premium distributions that have not adopted the Meta configuration surface will not honor the same global semantics; they may ignore the key entirely or fail validation depending on how strict your wrapper is. Before you chase mysterious “no effect” results, confirm which engine your GUI embeds—about dialog, log banner, or package maintainer notes usually spell it out.
Router builds and memory-tight appliances sometimes strip optional globals to keep YAML minimal. If your OpenWrt profile parser rejects unknown keys, mirror upstream examples from the same major version rather than cargo-culting lines from desktop tutorials. When in doubt, consult the general configuration chapter maintained for Meta-class cores rather than decade-old blog snippets aimed at vanilla Clash.
Version drift: defaults and accepted aliases evolve. When you upgrade Mihomo for security fixes, re-open release notes—global networking toggles occasionally gain companion flags such as unified-delay that change how you interpret latency panels.
Where to put tcp-concurrent in YAML
Place the key alongside other top-level general options: mode, ipv6, log-level, unified-delay, and friends. It is not nested under proxies or proxy-groups; it is a global instruction to the dialer. A minimal illustrative fragment looks like this:
# Illustrative root-level snippet for Meta-class cores
mode: rule
ipv6: true
unified-delay: true
tcp-concurrent: true
log-level: info
GUI-first users may never type the line by hand because a well-designed profile editor exposes a checkbox mapped to the same field. If your client only offers a raw text view, paste the key once, save, and let the parser validate indentation—two-space conventions rule the Clash ecosystem, and tabs remain an avoidable source of support tickets.
DNS shapes that make racing meaningful
Parallel TCP only helps when parallel addresses exist. FakeIP stacks, narrowly scoped caches, or custom mapping files can collapse a hostname to a single synthetic answer by design. In those regimes, enabling tcp-concurrent should not hurt dramatically, but it also will not manufacture diversity that DNS never provided. Readers who recently reworked resolvers should revisit Meta core DNS leak prevention before blaming the dialer: inconsistent answers between the OS stub and Meta’s DNS module still produce stranger symptoms than a missed optimization knob.
Conversely, when you point at a resolver that returns several A records for a streaming CDN or multiple viable exit routers for the same anycast name, racing aligns with how large clients already treat the public Internet. The proxy simply inherits a strategy power users expect from desktop browsers, packaged where transparent MITM or enterprise proxies cannot see inside TLS but can still count sockets.
Latency and user-perceived startup time
The wins people report cluster around first connection or first TLS byte after a cold DNS cache. Interactive sites that open dozens of sockets still spend most of their time in rendering; shaving tens of milliseconds off one handshake does not move Core Web Vitals alone. Bulk downloads, package managers that open single long-lived TCP pipes, or games that gate matchmaking on a single login hop are more likely to show anecdotal improvement when one IP in the pool was bad.
Because outcomes depend on topology, maintain humility. Measure with repeated trials at different times of day, not single-shot hero numbers. Pair logs with your existing health-check policy—our url-test and fallback guide explains how automatic group selection interacts with latency reports so you do not chase the wrong variable.
When parallel dials annoy networks or servers
Every extra SYN is visible somewhere. Corporate transparent proxies, campus egress monitors, or abuse heuristics on small VPS providers sometimes assume well-behaved clients attempt one path at a time. Racing is legitimate on the modern web, yet legacy appliances still flag burst dial patterns as reconnaissance. If your security team hands you a polite note about “SYN flooding behavior from the proxy host,” switching tcp-concurrent back to false is cheaper than winning an argument about standards compliance.
The same caution applies to servers that enforce per-client concurrency limits or expect sticky paths for session affinity. Most applications handle winner-takes-all TCP cleanly, but quirky legacy middleware occasionally binds session state to the first observed source tuple even when the client retried elsewhere. When you migrate a fragile internal tool through Meta, disable racing during the pilot, document the finding, then re-enable if operations sign off.
Observability: packet captures during debugging will look busier with the flag on. Filter by destination subset before concluding there is an unexpected loop.
Relationship to unified-delay and benchmarks
Meta documentation lists unified-delay near tcp-concurrent because both options influence how sophisticated users read comparative latency. Unified delay attempts to normalize measurement methodology across heterogenous proxy protocols so dashboards stay comparable; tcp-concurrent influences how quickly a live session acquires a working socket. They solve different problems. Turning both on is common in enthusiast profiles, yet neither substitutes for selecting nodes that actually reach your targets.
Avoid the trap of stacking every global speed flag and assuming the scoreboard must improve. Some combinations interact with mobile power management—always sample laptop battery runs if you live on airplanes or long train commutes where radios throttle aggressively.
Step-by-step: enable, test, and roll back
1Snapshot the working profile
Copy your current YAML or export from the GUI before touching globals. If the edit breaks parsing, you want a one-click restore unrelated to git blame drama.
2Insert or flip tcp-concurrent
Add tcp-concurrent: true in the general section, or set false to disable. Remove duplicate keys if an older merge layer duplicated the block; the last writer wins in many loaders, but duplicates confuse human reviewers.
3Reload and watch the log
Trigger a configuration reload and read the boot banner. Mis-indented YAML fails fast; silent ignores usually mean you edited the wrong file path or the service points at a different working directory than you thought.
4Exercise realistic applications
Cold-start a browser profile with cleared caches, launch the game you actually play, or run the package manager you rely on at work. Note subjective startup, but also peek at connection traces if your GUI lists timing columns.
5Document the decision
One line in your runbook—“tcp-concurrent on since 2026-05; revisit after Mihomo bump”—saves the next maintainer a forty-message forum thread.
Quick decision matrix
- Turn on when DNS often returns multiple healthy addresses and you want the fastest successful TCP without scripting external probes yourself.
- Leave off when compliance, idiosyncratic servers, or monitoring alerts prize single-path behavior.
- Investigate DNS first when results look random regardless of the flag—alignment between resolver modes still dominates mystical latency bugs.
- Pair with process-aware routing when only certain binaries should ever race handshakes; see PROCESS-NAME routing for executable-scoped policy layers.
Frequently asked questions
Does tcp-concurrent replace proper node selection? No. It accelerates picking a working TCP path among DNS answers for a given outbound attempt. It does not rank which data-center exit you should prefer—that remains the job of proxy groups, provider quality, and your ethics about traffic engineering.
Does it help UDP or QUIC-heavy games by itself? Not directly. The documented behavior centers on TCP handshaking toward IP sets. UDP-focused titles still depend on correct TUN capture, firewall exemptions, and sensible policy order—our UDP-oriented troubleshooting walkthroughs remain relevant when voice chat misbehaves.
Will mobile users drain battery faster? Possibly a little on chatty sites because more radio wakeups occur during the race window. The magnitude is usually smaller than leaving a debug log at debug for a weekend, but measure on your own handset if you live on a thin battery budget.
Summary
tcp-concurrent tells a Clash Meta core to attempt parallel TCP handshakes across the IP addresses DNS returned, keeping the first success. It lives next to other global options such as unified-delay, not inside proxy definitions. Enable it when multi-answer DNS and real-world latency justify happier racing; disable it when compliance or brittle servers read burst dialing as hostile. Pair the knob with honest DNS policy, organized rules, and resilient proxy groups rather than expecting it to rescue a bad subscription.
Many wrapper apps expose every Meta toggle behind a friendly panel, yet others leave you in raw YAML land where one indent error blocks an entire team. Lightweight installers that prioritize reproducible defaults, cross-platform GUI polish, and documentation in one place tend to feel less fragile than juggling multiple unsigned forks whenever a global like tcp-concurrent ships in a new upstream release. If you are still bouncing between configs that fight your OS or hide errors in silent fallbacks, download Clash from our official page: you get a maintained client line built around the same Meta-class capabilities this article describes, without forcing you to reverse-engineer which unofficial build actually merged the tcp-concurrent patch you read about in a changelog.