FAQ and troubleshooting
A process stays stopped after cpulimit died
If cpulimit is killed with SIGKILL, or by the out-of-memory killer, or crashes while the target is in its stop slice, the target stays stopped (state T in ps). No user-space program can prevent this; a supervising process could, but it would bring back the original's orphaned-limiter defect. Resume the target:
kill -CONT 1234
pkill -CONT -f 'the command line' # or by nameA normal stop of cpulimit (SIGINT, SIGTERM, SIGHUP, SIGQUIT, the target exiting, an error) always sends SIGCONT first. Use those, not SIGKILL, to stop a limiter.
The limit seems to have no effect
- Another user's process. If cpulimit may not signal it, it says
Process found but you aren't allowed to control itand does nothing. Run it as that user or as root. - The percentage is of one CPU.
-l 50on a program using four threads still allows half a CPU in total;-l 200allows two. - The children are not included. A shell script's work happens in its children: add
-i. -mis too high. Processes using less than M of a CPU are never stopped. Remember-m 0.05is 5 %, not-m 5.- Wrong pid.
-pexits when the pid ends (it implies-z);-ewaits for a match unless-zis given.
"already limited" and exit status 1
Another cpulimit holds the lock for that process (see one limiter per target). The message names its pid. Stop that one, or pass --no-lock if you really want two limiters; they will undo each other's stop and continue and the result is not a clean limit.
How accurate is it?
Within a few points of the requested share on a quiet machine, with the same bias as the original: it delivers slightly less than asked at 10 % to 25 % and overshoots by a point or two near 50 %. See the measurements. Shorter chunks (-c) track the limit more closely and cost more wake-ups. On a busy or emulated machine the CPU accounting itself is coarse (one clock tick, 10 ms at 100 Hz), and so is the limit.
Does it limit threads separately?
No. The target is limited as a whole: the signals go to the process, so all of its threads stop and continue together. A two-thread busy loop at -l 50 measured 53 to 54 % of one CPU over 10 s, with the old and the new binary alike.
Does it work with nice, ionice, taskset, chrt, timeout?
Yes, and the integration tests check each: a target started under nice, ionice, taskset or chrt is limited and keeps its nice value, I/O class, CPU affinity and scheduling policy; cpulimit -l N nice -n 5 cmd limits cmd (the wrapper replaces itself with the command, so cpulimit's child is the command) and returns its exit status. A wrapper that stays alive and forks, such as timeout or setsid -w, is the child cpulimit sees: add -i to reach the command below it. Running cpulimit itself under nice, ionice or taskset works too; a nice value you give it is kept with --no-boost and may be improved without it, if you have the privilege.
Why not nice, cgroups or a scheduler class?
nice only changes who wins when the CPU is contended; an idle machine still gives the process all of it. cgroup CPU quotas (cpu.max, systemd-run -p CPUQuota=) are the right tool on Linux when you control the service and have the privilege; they are enforced by the kernel and need no cpulimit process. cpulimit is for the cases where those are unavailable or too heavy: an already running process, another unix, a user without cgroup delegation, or a quick cap on one command.
Containers
cpulimit sees the processes of the PID namespace it runs in. To limit a container's process from the host, use the host pid; from inside, the container's. A cgroup CPU quota on the container applies in addition to the limit.
Pid reuse
A process is the pair (pid, start time); when a pid is recycled for a new process, cpulimit sees a new entry and does not limit it. A window of one control cycle remains between reading a process and signalling it, which no user-space program can close.
Why does -h exit with 1?
Every release of cpulimit has, and scripts may depend on it. -V exits 0.
Where does a daemon log?
To standard output and error as long as they exist, and with -s to syslog (facility LOG_DAEMON). A daemon detaches from the terminal, so use -s to keep a record.
Reporting a problem
Open an issue at GitHub with the version (cpulimit -V), the system, the command line and, for a limit that does not hold, the output of the same command with -v.