Hi,
I noticed that PlatformIO’s background Python process was consuming ~98% CPU on my Mac, causing significant fan noise and heat. After stopping all but one process, the issue subsided.
I captured a macOS sample profile of the process (pid 83226, python3.11) and analysed the call graph. Here’s what I found:
Environment
- macOS 15.4 (Apple Silicon, ARM64)
- Python 3.11
- PlatformIO (started via the IDE extension)
Root cause (from call graph analysis)
Two hotspots account for most of the CPU usage:
-
~25% of samples —
_Py_bytes_contains→_PyNumber_Index→PyErr_Format
An async task is using theinoperator on abytesobject while passing a non-integer type. This raises aTypeErrorinternally, which is caught and ignored — but because this runs in a tightasyncioloop with nosleep(), it fires hundreds of thousands of times per second. The cost of building the exception string viaPyUnicode_FromFormatV, allocating and deallocating exception objects, and clearing the error repeatedly adds up to significant CPU load. -
~21% of samples —
time.time()→clock_gettime→mach_absolute_time
Very frequent calls totime.time()suggest a polling loop running without anyasyncio.sleep()or equivalent yield, keeping the event loop spinning continuously.
The affected modules visible in the binary images are md.cpython-311-darwin.so and md__mypyc.cpython-311-darwin.so.
Suggested fix
- Add a type check before the
bytes.__contains__call to avoid the repeated TypeError. - Add
await asyncio.sleep(0)or a small sleep in the polling loop to yield control and reduce CPU usage to near 0% when idle.
Impact
On Apple Silicon this causes sustained high CPU load, elevated temperatures, and loud fan noise even when no build or upload is running — just having PlatformIO open in the background is enough to trigger it.
I’m happy to share the full sample output if that would help with debugging.
Thanks!