On this page
You change an inbound setting and connections stop, yet Mihomo keeps using CPU. Another change may push idle usage even higher. Distinguish a brief spike while loading configuration from a loop that keeps running after a listener closes. First identify the busy process and exactly which inbound was just closed.
Why does CPU stay high after a reload with no traffic?
Official #3314 concerns closing a Shadowsocks inbound that uses a legacy stream cipher. After a relevant listeners entry is changed or removed, or ss-config is changed, the old listener’s accept loop may fail to exit. It can keep consuming CPU with no traffic, and repeating the same close operation may add more lingering loops. Error logs may not appear.
This differs from a slow proxy node, an ordinary SS outbound failure or a generic reload delay. v1.19.33 contains the relevant fix. If you do not use this kind of inbound, or usage is high only while forwarding normal traffic, this article does not establish the cause.
Distinguish the process and timing
| What you observe | What to check next |
|---|---|
| The actual Mihomo process keeps using CPU at idle after the relevant SS inbound closes | Check the inbound type, cipher, running core and time of closure. |
| Usage rises briefly while loading a large configuration, then falls once loading finishes | Check configuration-validation costs; do not mistake this for a loop left running after a listener closes. |
| The client interface is busy, but Mihomo process usage is normal | Check interface, system-tray or log processing. |
| There is no relevant inbound, or usage rises only during heavy traffic forwarding | Record the workload and investigate other runtime causes; this article cannot confirm the root cause. |
Find the inbound settings, not the SS nodes in a subscription
An inbound is an entry point through which other programs or devices connect to this Mihomo instance. An outbound is a proxy node Mihomo uses to reach external services.
Inspect the final configuration passed to the core: look for type: shadowsocks under listeners and check its cipher. For the older shorthand entry point, check the top-level ss-config. Seeing type: ss under proxies alone does not meet the conditions for this issue.
Examples of the stream ciphers concerned include aes-128-ctr, aes-256-cfb, rc4-md5, chacha20, chacha20-ietf and xchacha20.
The fixed v1.19.33 source routes these compatibility algorithms through the embedded listener implementation. The none, AEAD and 2022 ciphers use another implementation and are outside this close-handling defect. Do not group chacha20-ietf with chacha20-ietf-poly1305 merely because their names look similar.
The current Wiki’s table of common inbound ciphers does not list those legacy stream algorithms as options for new configurations. This article uses source pinned to the release tag to explain the compatibility path for existing configurations; do not create a legacy-cipher inbound just to reproduce the issue. Do not change cipher on only one side either: the peer using this inbound must match.
Save this evidence from the existing fault
- Observe Mihomo and the interface process separately, and identify the actual instance responsible for high CPU.
- Record the client version, the running core version and how it starts; “latest” is not enough.
- Keep before-and-after copies of the relevant listeners or ss-config settings. Record the original inbound type, cipher and time of closure.
- Check whether the fault immediately followed a change, removal or closure of the relevant inbound, rather than an unrelated reload.
- Keep the original configuration locally. Remove inbound passwords, subscription tokens, private keys and server details before posting feedback publicly.
Back up a working configuration and stop repeated hot reloads
First make a separate backup of the complete configuration in use, overrides, external resources and client settings. Record the core version, system-proxy state and TUN state. If other devices depend on this inbound, arrange a time when connections can be interrupted and keep a management path that does not depend on it. Do not update subscriptions, change DNS or clear the entire data directory while investigating.
If a loop is already spinning, do not try to clear it by repeatedly removing and adding the inbound. The older defect occurs after listener closure, so another hot reload may trigger it again. To recover temporarily, use the application’s or service’s supported normal stop procedure. Confirm that the affected old instance has actually exited, then start a configuration verified to work beforehand. Closing the window, disabling TUN or seeing no connections does not confirm process exit.
You do not need to reproduce the fault repeatedly on an old release, expose external-controller, or copy the official reproduction and reload scripts to follow this article. A successful -t configuration test shows only that the relevant configuration checks completed; it does not prove that the running listener’s close-handling loop is fixed.
Install the fix, then fully restart the running core
The Mihomo v1.19.33 release notes list fix commit 349af19. In listener/shadowsocks/tcp.go at the fixed tag, Close() sets closed before closing the listener; the accept loop then exits when it encounters the closure error. This fixes close handling, rather than lowering a CPU limit or changing node latency tests.
Make sure the running instance uses the fix
Use the original project’s supported stable update method
For a standalone core, select the release matching your system and architecture from MetaCubeX/mihomo. For a graphical client, follow that project’s supported application or core update procedure; do not arbitrarily overwrite binaries in a service directory.
Confirm that the update includes 349af19
v1.19.33 is the released fix version verified for this article. FlClash v0.9.2 explicitly lists Mihomo v1.19.33 in its changelog and is one documented example. For other clients and core forks, check their own records; comparing interface version numbers alone is insufficient.
Stop the old instance normally, then start the updated instance
Keep copies of the configuration and resources. Restart normally as required by the application or service, confirm that the old instance exits, and check that the new instance’s startup log shows the expected core. Changing configuration alone does not establish that loops left in the old process have gone away. Replacing program files while leaving that process running does not mean the fix is active.
mihomo -vmihomo -v identifies the program invoked by that command; it may be another file with the same name on PATH. It must match the core actually used by the service or client. For an app-managed core, prefer the project’s version information and startup logs; do not extract an internal program solely to query its version.
Check idle usage, later reloads and real connections
Compare Mihomo process usage before and after the full restart on the same device, with the same configuration and similar background activity. Temporarily stop test traffic through that instance, observe an idle period, then resume normal work. A startup spike or a peak during real traffic is not evidence of a loop that keeps spinning after closure.
Make only the inbound changes or removals and restorations you actually need, after the fixed core is running and only where a brief network interruption is acceptable. If normal operation requires several such reloads, record idle CPU after each and check that it does not keep rising with the number of relevant closes. There is no need to keep toggling an old release or generate heavy load merely to reach a test count.
Acceptance checks
- The running core is confirmed to include 349af19, and the old instance has exited.
- After test traffic stops, the core returns to usage similar to its previous normal idle state, without a persistent spinning loop. Do not adopt someone else’s CPU percentage as a target.
- When the inbound genuinely needs to close or change later, the same persistent usage or stepwise accumulation does not recur.
- After restoring the required inbound, the original authorized clients reconnect and complete a real HTTPS request. Rules, outbounds and connection records match the intended design.
- Restore the system proxy or TUN only for its original purpose. After exiting or disabling it, the device can still return to the network state recorded beforehand.
This site has not run this reproduction on a real client, router or server, and makes no claim of a particular performance multiplier or zero CPU use. These checks are based on the official defect report, pinned source and fix records. Your network, other causes of high usage and the client’s integration still require separate verification.
If problems remain, restore a working setup and share minimal evidence
If the updated program will not open, the inbound cannot connect or the configuration is incompatible, save the first error and the current configuration copy, then stop reloading. Use the project’s supported method to restore the previously verified program version, matching configuration and external resources. Avoid making old and new programs share the only data directory, and restore system-proxy and TUN settings to the recorded working state.
An older release may still have this defect; rollback is an emergency measure, not a fix. If you need to disable the faulty inbound temporarily, first identify the connections and management access that depend on it. Stop the affected instance normally, then use a verified working configuration. Do not merely remove the entry from an old process that is still spinning and continue hot reloading.
If the problem recurs, give the project your system and architecture, actual running core, inbound type and cipher, the precise operation that closed it, idle CPU trends under the same conditions, and the difference between a full restart and later reloads. Without those conditions, leave the cause unconfirmed rather than attributing every high-usage case to #3314. Share only the essential configuration relationships and redacted error messages needed for reproduction; do not upload complete subscriptions or passwords.
References
- Mihomov1.19.33 release: embedded Shadowsocks listener close fix
- MihomoOfficial #3314: close path, affected ciphers and reproduction tests
- MihomoPinned v1.19.33 source: closing the embedded TCP listener
- MihomoPinned v1.19.33 source: Shadowsocks cipher implementation branches
- Mihomo WikiMihomo inbound configuration: listeners and ss-config
- Mihomo WikiShadowsocks inbound fields and current cipher list
- FlClashFlClash v0.9.2 changelog: Mihomo core version
