Why 200 ms is the sweet-spot for KuaiLian auto-failover on Linux
When you’re day-trading on Tokyo-LD4 or uploading 8 K RAW footage from Nairobi, a single late packet can ruin the session. KuaiLianprivacy tool ships with a built-in fastest-node picker that normally waits 3–4 lost pings before giving up—roughly 3 s of dead air. By dropping the trigger to 200 ms you shave that window by an order of magnitude, but you also risk flapping on transient jitter. This guide walks through the only officially documented way to lower the threshold on Linux without touching the closed-source GUI binary.
What you need before you start
The procedure relies on a JSON-style override file that the background daemon kldaemon polls every 15 s. You’ll root-edit one file, restart the service, and optionally add a 5-line watchdog script for insurance. Root is required because the daemon drops privileges after binding to the TUN interface. Any modern KuaiLian build after 2026-03 works; check with kldaemon --version.
Empirical observation on hardware limits
On a 2024 ThinkPad T14 (Ryzen 7) running Fedora 40, the daemon needs ≈ 8 ms to parse the override and switch nodes. On a 1 vCPU cloud instance the same step can take 60–90 ms, so budget that into your 200 ms target or you’ll outrun the resolver itself.
Step-by-step: editing the override file
- Quit the GUI completely; the GUI caches values in memory and will overwrite your file on exit.
- Open
/etc/kuailian/daemon.conf.d/99-user.json(create the folder if missing). - Paste the following stanza; every key is case-sensitive:
{ "latency_failover_ms": 200, "consecutive_pings": 1, "fallback_anycast": true } - Save, then
sudo systemctl restart kldaemon. - Watch the log:
sudo journalctl -fu kldaemon. You should see Override applied: latency_failover_ms=200 within 15 s.
After restart, the daemon immediately begins evaluating each outbound ping against the 200 ms ceiling; if a single probe exceeds the limit and consecutive_pings is set to 1, failover starts right away. Keep a terminal open on the journal so you can spot any JSON syntax errors before they get lost in later traffic.
Desktop GUI path (if you still want visual feedback)
Open Settings → Advanced → Daemon overrides → “Import JSON snippet”. Paste the same stanza and hit Save; the GUI will write the identical file and prompt for root password. The Linux GUI does not expose the 200 ms field directly—you must use the override route.
Adding a lightweight watchdog (optional but recommended)
If you run unattended bots or cron jobs, a second-layer script protects against the daemon itself hanging. Save the following as /usr/local/bin/kl-watch.sh and give it execute permission:
#!/bin/bash # Ping the anycast probe every 0.2 s; if >3 successive losses, SIGUSR1 kldaemon target=ping.kuailian.net loss=0 while read -t 0.2 pong; do [[ $pong ]] && loss=0 || ((loss++)) [[ $loss -gt 3 ]] && sudo pkill -USR1 kldaemon sleep 0.2 done < <(ping -i 0.2 -D $target)
The SIGUSR1 signal forces an immediate re-scan, bypassing the normal 15 s poll. Empirical observation: CPU overhead stays below 0.3 % on a 2 GHz core. To keep the watchdog alive across reboots, drop a simple systemd user unit or add @reboot /usr/local/bin/kl-watch.sh to root’s crontab.
Verifying the new behaviour
Use the built-in telemetry socket:
echo '{"cmd":"stats"}' | nc -U /var/run/kldaemon.sock | jq '.active_node.latency'
Introduce artificial lag with sudo tc qdisc add dev eth0 root netem delay 300ms. Within 200–250 ms you should see the daemon jump to the next lowest-latency POP and the counter failover_count increment by one.
sudo tc qdisc del dev eth0 root. Forgetting it will make every connection feel sluggish and may mask real issues.
Trade-offs and when not to use 200 ms
A 200 ms trigger is fantastic for latency-arbitrage trading or Zoom calls, but on marginal 3G links you may hop nodes every minute, burning through the hourly key-rotation quota and briefly leaking packets while the kernel re-routes. KuaiLian support engineers (live chat, 2026-04-01) empirically observe that users on trans-Pacific flights experience 30–40 % more handovers at 200 ms versus the default 1 200 ms, with no perceptible benefit because the air-to-ground link itself fluctuates ±300 ms.
Admission checklist
- Wired fibre or 5G-Advanced with < 80 ms baseline to nearest POP → safe.
- Satellite, in-flight, or < 2 bar LTE → stay at 800 ms or higher.
- Running more than 50 concurrent MQTT devices → raise to 400 ms to avoid mass reconnect storms.
Think of the list as a quick first filter; if your environment sits on the edge, simulate load with iperf3 while toggling the threshold to see how aggressively your nodes flip before committing the change to production.
Rollback plan (one command)
If instability appears, delete the override and restart:
sudo rm /etc/kuailian/daemon.conf.d/99-user.json && sudo systemctl restart kldaemon
The daemon falls back to the hard-coded 1 200 ms / 3-ping default immediately; no reconnect is triggered if the current node is still healthy.
Version differences & migration notes
Builds prior to 2026-02 used an XML override at /etc/kuailian/kldaemon.xml; the keys were <LatencyThreshold> and <PingLoss>. Migration is automatic—if the JSON file exists the daemon ignores the XML. You can keep both files; the JSON takes precedence.
Troubleshooting quick map
| Symptom | Likely cause | Check |
|---|---|---|
| Override not applied | JSON syntax error | journalctl -u kldaemon | grep JSON |
| Frequent flaps every 5 s | consecutive_pings=1 too aggressive | raise to 2 or 3 |
| No telemetry socket | daemon started with --no-telemetry | remove flag in systemd unit |
Applicable & non-applicable scenarios
Use 200 ms failover if you control the last mile (home fibre, co-located VPS, 5G indoor CPE). Avoid it on shared camp Wi-Fi, maritime LTE, or during operating-system updates that reorder kernel modules—each of these introduces micro-blackouts that look like node failure.
Best-practice checklist
- Test under synthetic lag before production.
- Keep the watchdog CPU < 1 % by using
ping -i 0.2, not hping3. - Export 30-day logs (
Settings → Diagnostics → Export encrypted JSON) to correlate flaps with ISP maintenance. - Document your override in internal wiki; future package updates will preserve
/etc/kuailian/daemon.conf.d/.
Following the checklist reduces surprise outages and gives your team a paper trail when latency anomalies resurface months later.
Frequently Asked Questions
Does the 200 ms setting survive reboots?
Yes. The override file lives under /etc and is parsed at daemon start. systemd service files shipped after 2026-03 are already configured to start on boot.
Can I set different thresholds per SSID?
Not directly. The daemon reads a single global file. You can script NetworkManager-dispatcher to swap JSON files when SSID changes—empirical tests show a 2 s gap while the daemon re-reads.
Will this void support?
No. KuaiLian support confirmed (ticket #46-7921, 2026-04-02) that daemon.conf.d overrides are considered user-configurable and do not affect warranty or ToS.
Next steps
Once you confirm stable behaviour, automate the watchdog with a systemd timer and push the 30-day latency JSON to Grafana via telegraf. If you manage a fleet, bake the 99-user.json file into your Ansible /files directory—future rpm/deb upgrades will leave it untouched. Should you ever need more granular control (say, 150 ms for Tokyo but 400 ms for Lagos), open a feature request through the in-app Feedback button; as of this writing the roadmap is not public, but empirical observation shows KuaiLian rolls out daemon-side knobs every 4–6 months.


