Cpulimit limits a process's CPU usage to a percentage you choose, by sending
SIGSTOP to pause it and SIGCONT to resume it as needed. With -i the
limit covers the process and all of its descendants.
Cpulimit works on Linux, macOS, and FreeBSD. It was originally developed by Angelo Marletta; this fork is maintained by HiGarfield and adds bug fixes and improvements. Prebuilt binaries are published on Releases.
Pick one of the four methods below.
Download the archive for your platform from Releases, then:
sudo install -d /usr/local/bin
sudo install -m 755 cpulimit-* /usr/local/bin/cpulimitRequires a C compiler.
-
Linux/macOS with
make:make sudo make install
-
FreeBSD with
gmake:gmake sudo gmake install
rm -rf build
mkdir -p build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local
cmake --build .
sudo cmake --build . --target installCompile all sources directly and install. gcc and clang are
interchangeable; only the trailing link flag differs per platform
(-lrt on Linux, -lproc on macOS, -lkvm on FreeBSD).
# Linux
gcc -O2 -D_TIME_BITS=64 -D_FILE_OFFSET_BITS=64 src/*.c -o cpulimit -lrt
# macOS
clang -O2 -D_TIME_BITS=64 -D_FILE_OFFSET_BITS=64 src/*.c -o cpulimit -lproc
# FreeBSD
gcc -O2 -D_TIME_BITS=64 -D_FILE_OFFSET_BITS=64 src/*.c -o cpulimit -lkvm
# install (any platform)
sudo install -d /usr/local/bin
sudo install -m 755 cpulimit /usr/local/bin/cpulimitcpulimit OPTION... TARGET| Option | Description |
|---|---|
| -l LIMIT, --limit=LIMIT | CPU percentage limit, range (0, N_CPU*100] |
| -v, --verbose | show control statistics and progress messages |
| -z, --lazy | exit if the target process is not running |
| -i, --include-children | limit total CPU usage of target and descendants |
| -h, --help | display this help message and exit |
Without -v, cpulimit prints nothing while it runs: no statistics, no
progress, and no warning about a condition it recovers from on its own — a
target that has not appeared yet, a process that refuses to be signalled, or a
scan that failed once and is retried. The one exception is the error that ends
the run, and it is printed once: for example a lazy run whose target does not
exist, or a process left stopped that only kill -CONT can recover.
With -v, all of it is reported, including the per-cycle progress that a
silent run withholds. Bad command-line arguments and their usage message are
always printed, with or without -v.
-l LIMIT is required. It is a percentage of one CPU core: -l 50
is half a core, -l 100 is one fully used core, and the maximum is
number_of_cores * 100 — -l 250 on a 4-core machine allows about two and a
half cores.
Exactly one target must be given:
| Target | Description |
|---|---|
| -p PID, --pid=PID | PID of the target process (implies -z) |
| -e FILE, --exe=FILE | executable name or path |
| COMMAND [ARG]... | run the command and limit CPU usage (implies -z) |
With -e, cpulimit matches the name each process was started with, not the
path of the executable on disk:
- An argument starting with
/is compared in full, so-e /usr/bin/myappdoes not match a process started asmyapp. - Any other argument is compared by name only, so
-e myappmatches/usr/bin/myappand./dir/myappalike. - An argument with an empty name (
-e /,-e bin/) is rejected withinvalid match name.
When several processes match, the topmost ancestor wins; if the matches are unrelated, the smaller PID wins. A match cpulimit cannot signal loses to any match it can control.
# Limit process 1234 to 50% of one core.
cpulimit -l 50 -p 1234
# Limit every process named "myapp" to 50% of one core.
cpulimit -l 50 -e myapp
# Run "myapp --option" limited to 50% of one core.
cpulimit -l 50 -- myapp --option
# Limit "myapp" and its children to 50% of one core.
cpulimit -l 50 -i -e myapp
# Run ffmpeg and its children, limited to 200% (two cores), with stats.
cpulimit -l 200 -v -i -- ffmpeg -i in.mkv -c:v libx264 out.mp4- Children are only included with
-i. - A suspended process makes no progress:
SIGSTOPfreezes it, holding its locks and serving no I/O untilSIGCONTarrives, so interactive and networked services gain latency. - Very short-lived children can be missed and then run unthrottled.
- Cpulimit controls only processes owned by the current user. To limit a
process owned by another user, run cpulimit as root (for example with
sudo). - As root, cpulimit raises its own priority. Run with
sudo, it switches itself to a real-time scheduling policy (and lowers itsnicevalue), so it reacts to usage spikes without delay and enforces the limit more precisely. - PID 1 (init) is never limited. Suspending it would freeze or crash the system, so there is no exception on any platform.
-pand command mode exit when the target stops. Use-z(or-p, which implies it) when the run should end as soon as the target is gone. Without it,-ekeeps waiting and re-attaches whenever the target reappears, so a program that starts later is still limited.- Do not kill cpulimit with
SIGKILL. For example,killall -9 cpulimit,killall -KILL cpulimit,kill -9 <cpulimit's PID>, orkill -KILL <cpulimit's PID>skip the cleanup that sendsSIGCONT, so any process cpulimit has paused withSIGSTOPstays frozen and never resumes. Stop cpulimit withSIGTERM/SIGINT(for examplekill -TERM <cpulimit's PID>orCtrl-C) instead, so it can restore the target to a running state.
| Exit Code | Description |
|---|---|
| 0 | Success |
| 1 | Bad args, target not found (-z), internal error |
| 126 | Command found but not executable (command mode only) |
| 127 | Command not found (command mode only) |
| 128+N | Command terminated by signal N (command mode only) |
| any other | In command mode, whatever the command itself exited with |
The three command-mode rows (126, 127, 128+N) follow the shell's own
conventions and apply only when cpulimit cannot start the command. Once the
command runs, cpulimit steps aside and reports the command's own status instead:
cpulimit -l 50 -- sh -c 'exit 7' exits 7. With -p or -e there is no
command to report on, so the status is always cpulimit's own.
Use the method matching the one you installed with.
sudo rm -f /usr/local/bin/cpulimit-
Linux/macOS with
make:sudo make uninstall
-
FreeBSD with
gmake:sudo gmake uninstall
sudo cmake --build build --target uninstallsudo rm -f /usr/local/bin/cpulimitRun the tests from the project build directory.
-
Run unit tests:
./tests/cpulimit_test
-
Test cpulimit with a single process:
./src/cpulimit -l 50 -v -- ./tests/busy
-
Test cpulimit with child processes:
./src/cpulimit -l 50 -i -v -- ./tests/multi_process_busy
Source code is available at https://github.com/HiGarfield/cpulimit, where bug reports and feature requests are welcome.