I have a 2019 MacBook Pro, and it’s a nice machine for its time; with an i9 processor it handles
most tasks quite well. However, for some reason Apple decided to give it a battery that doesn’t
have enough power to supply what the CPU needs when it’s using all 16 cores, such as when I’m
transcoding video with ffmpeg
. Even using a 140W power supply, it will slowly drain the battery
when at full speed, and with a large enough encoding job (such as encoding AV1 content) it could
easily drain it all the way and shut down.
If only there were a way I could tell ffmpeg to slow down a bit, just enough to let the battery at least stay at a constant level while the transcoding is happening…
Well, fortunately I, and anyone else with this problem, are in luck. There’s a utility called cpulimit
which does exactly what the situation calls for. It’s available on most Linux
distributions, and also, thanks to some kind soul that created a formula for it, is available
on homebrew as itself.
All one has to do (if you have homebrew already installed) is brew install cpulimit
. One caveat, however, and this is most unfortunate: it’s only functional on Intel CPUs at the moment. Apparently no one has recompiled it for ARM yet, or the necessary hooks aren’t there for the M series CPUs. My sympathies to those of you stuck with fabulously high-powered new machines. (If anyone has mad skillz and feels like being heroic, the source code for cpulimit
can be found here)
In any case, to use cpulimit
one has to look up the process ID (PID) of the program that’s eating all the CPU. This can be done with ps
; just look for the number in the leftmost column; that’s the PID. If the process isn’t one of your own, you might want to use ps ax
in order to see all processes, but in that case you might also want to filter the list to find what you’re looking for: ps ax | grep <programname>
. Also, the top
, htop
, or the wonderful bpytop
utility, can show you which processes are taking all the CPU.
Once you have the PID, you run cpulimit
, telling it how much CPU to give the process, anywhere from 1 to 1600:
cpulimit -l <cpu amount> -p <PID>
The cpulimit
process will stay active, rather than setting something and exiting immediately. To undo the limit and release the process to use as much CPU as it wants again, just use Ctrl-C to stop cpulimit
.
Note that the percentage of CPU you give to cpulimit
doesn’t necessarily behave like you think it might, especially with highly multithreaded programs like ffmpeg
. On my machine, limiting ffmpeg
with a parameter of -l 50
actually results in an overall CPU usage of about 15%, much lower than perhaps would be expected. So, you will probably need to experiment to find a level that will keep your battery from draining without the process taking forever and a day to finish.
If you want to just completely pause a process temporarily, you can use the STOP
and CONT
signals to do this:
kill -STOP <pid> # This will completely stop a process without killing it (temporarily)
kill -CONT <pid> # This will resume a process stopped by the above command
(Hint: this works quite well with annoying processes in Mac OS like photoanalysisd
and corespotlightd
.)
Share and enjoy…