85

I would like to limit the amount of CPU time dedicated to certain processes (e.g. Firefox, Safari, ...).

I can't understand why such programs, even when not used (nothing loading, no animations, running in the background, ...), are so resource hungry. Why must a browser eat 50% or more of my CPU? Can I limit it to 10%?

0

16 Answers 16

17

Its not exactly what you wanted, but, in regards of google drive and chrome this what did the trick for me:

Google Drive ("Backup and Sync")

  • de-prioritize:

    for f in $(pgrep 'Backup and Sync'; pgrep 'FinderSyncAPIExtension'); do renice +20 -p $f; done
    
  • set back to normal:

    for f in $(pgrep 'Backup and Sync'; pgrep 'FinderSyncAPIExtension'); do renice 0 -p $f; done
    

Chrome

  • de-prioritize all current processes:

    for f in $(pgrep 'Chrome'); do renice +20 -p $f; done
    
  • set back to normal all current processes:

    for f in $(pgrep 'Chrome'); do renice 0 -p $f; done
    
3
  • 2
    +1 - This is the most correct answer offered because 'nice' is part of the OS and directly ties into the algorithm used by the kernel's scheduler to decide which process gets the next slice of CPU time. It will always work on any Unix or Linux system and is not dependent on any 3rd party add-one. The bonus is that those processes can use more CPU if they aren't competing for CPU time with other processes. Commented Sep 12, 2020 at 21:26
  • I wonder what effect this has on a Zulu Java VM. Will it still perform reasonably? Will it not harm its internal timing mechanisms? Also on MacOS-X the "process" is not the basic object but rather the "Mach Task" and a process can have several tasks... is "nice" still the best way of doing this? Commented Jun 30, 2023 at 13:40
  • 2
    The OP asked how to "limit the %CPU used by a process" and this answer does not necessarily do that. It is true that nice will lower the priority of a process, but if nothing else is competing for those CPU cycles, the process will still get them. So, you can heavily nice a process only to find that it is using almost your entire CPU (e.g., "400%" CPU). Commented Jul 5, 2023 at 23:36
48

cputhrottle is the tool you need. You can install it with Homebrew.

You can monitor a series of processes by name by running the Bash script below. I'm not quite sure how to turn this into a login item since cputhrottle requires superuser permissions. Run it as a script, in an Automator workflow, whatever:

# Get the Process/App names from Activity Monitor and put them here
apps=("AppOne" "AppTwo" "AppThree")
# Set the respective limits here
limits={30 40 50)

while true; do
  for app in ${apps}; do
    for limit in ${limits}; do
      for pid in $(pgrep ${app}); do
        sudo /path/to/cputhrottle ${pid} ${limit}
      done
    done
  done
done

[Edited]

I've added a different version for this script (a bash script), which might be useful for people looking for limiting the CPU for multiple applications.

This new script also allows you to specify a list containing the application name and the CPU limit for it.

The main difference is that you can add cpu limit per application, and it will run only once per application. I've also added the option for killing all cputhrottle processes.

The script assumes that both cputhrottle and pidof are installed before running it.

#!/bin/bash

if [[ $EUID > 0 ]]; then
  echo "Please run this script as root/sudo"
  exit 1
fi

# Pass --kill as argument to kill all running cputhrottles
if [ $1 = "--kill" ]; then  
  echo "Looking for running cputhrottles..."
  pids=`pidof cputhrottle`
  for pid in ${pids}; do
    echo "> Killing PID ${pid}"
    sudo kill ${pid}
  done
  echo "Done!"
  exit 0
fi

declare -a applications

# Syntax='application;max-cpu'
applications[0]='Chrome;40'
applications[1]='Firefox;50'
applications[2]='pycharm;40'
applications[3]='webstorm;40'
applications[4]='Safari;35'

for i in "${applications[@]}"; do
  app=(${i//;/ })
  app_name=${app[0]}
  cpu_limit=${app[1]}

  printf "\nLooking for ${app_name}...\n"
  pids=`pidof ${app}`
  for pid in ${pids}; do
    echo "> PID=${pid}, CPU=${cpu_limit}"
    sudo cputhrottle ${pid} ${cpu_limit} &
  done
done

printf "\nDone!\n"
echo "Run this script passing '--kill' as argument to remove all cputhrottles."

Source:

6
  • 17
    As pointed out in another comment, cputhrottle's forumula was removed from Homebrew on Feb 17, 2019 because it doesn't work anymore. Yosemite was the last version of macOS to support cputhrottle.
    – Janosh
    Commented Mar 23, 2019 at 11:16
  • @Casimir and now, what to do? Commented Sep 16, 2019 at 15:35
  • @PeterSamokhin Sorry, I don’t know of an alternative. But I also haven’t searched recently.
    – Janosh
    Commented Sep 16, 2019 at 16:53
  • 2
    Just use Apppolice: github.com/AppPolice/AppPolice/releases Not sure what terminal command Apppolice is using but sourcecode is available. Commented Aug 22, 2020 at 14:06
  • 2
    AppPolice is working well with MacOs Big Sur. I was able to throttle down OneDrive to 30% so that the fan speed stay very low.
    – Thomas
    Commented Apr 15, 2021 at 13:33
18

You can indeed! There's CPUThrottle, which allows to specify a PID to restrict.

Note, they're trying to use that much for a reason, it's a useful tool but whether it'll make it better or worse for you on a day to day will be something you discover.

4
  • 2
    Interesting. But with this utility I have to launch a program, find its PID(s) and manually use cputhrottle. Every time I launch it. Is there something that allows me to tell the system: “From today always run this program with a maximum of 25% CPU” ?
    – Pietro
    Commented Sep 14, 2011 at 10:45
  • As far as I'm aware no, I've only ever come across CPUThrottle. Commented Sep 14, 2011 at 11:03
  • 2
    404 File not found Commented Jul 31, 2019 at 0:47
  • As posted above,CPUThrottle is here : medium.com/@sbr464/… Commented Sep 15, 2020 at 21:44
14

Although not a direct answer to the OP's question, if you're having an issue with a particular process taking up too much of your CPU time, and making your computer unusable, and you don't mind how long that process takes to finish the task it's working on, you can use the renice to alter the priority of that process, making it behave nicely (hence the name).

First, you need to find the PID of the process that's using up the CPU resources. You can either do that in Activity Monitor, or in Terminal.app with the ps command - e.g. to find the PID of the Safari browser, type:

MacBook:~😈  ps -ef | grep Safari
  501 17452   263   0 11:36pm ??         4:15.60 /Applications/Safari.app/Contents/MacOS/Safari

The second line above is the output, and the PID is 17452 in this particular case.

Then, the next task is to change the priority of the process (let's say it's Safari we want to make behave nicely). To do this, in Terminal.app type:

MacBook:~😈  renice -n 10 -p 17452

The -n option changes the nice level by adding 10 to the current value (0 by default). The range of values are -20 to 20, with lowest value meaning highest priority. As an ordinary user, you can use values 0 to 20. To assign a negative value, you need to have root privileges (e.g. use sudo command). Read more about nice and renice by typing man nice and man renice in Terminal.app.

nice and renice don't limit the percentage of the CPU available to a given application per se, they do however allow to change the scheduling priority, or in other words how much of the CPU time a process will get. This is all relative to the CPU load on your system, so if the system is under utilised, you most likely won't see any difference.

2
  • Is there a way to see the current priority of a process?
    – user150109
    Commented Oct 23, 2017 at 21:07
  • use top or htop to view the current nice value of a process. (brew install htop), (sudo apt install htop). You'll see one of the columns containing the value.
    – Tmanok
    Commented Dec 19, 2018 at 5:22
9

The link that Nicholas Smith posted doesn't work anymore. So I found one other app that does the trick for the people who are searching it again. the app calls Apppolice.

http://www.macupdate.com/app/mac/49836/apppolice

9
  • 3
    Similar to AppPolice, there is AppTamer (stclairsw.com/AppTamer). One word of caution: as of me writing this comment, AppTamer has yet to be OSX Sierra compatible. Commented Oct 21, 2016 at 15:48
  • 1
    Oh my, what a find. Just installed AppTamer. Pleased to report works fantastically well. I use it to keep the new StarCraft remastered in line when I alt-tab out. Oh and I forgot to mention, I'm running macOS Sierra 10.12.6. Thanks for the suggestion!
    – cavalcade
    Commented Aug 23, 2017 at 15:23
  • Apppolice has been discontinued. Commented Sep 27, 2017 at 16:48
  • But still works quite fine. Commented Jul 2, 2019 at 14:13
  • 2
    Brilliant find. Apppolice is much less complicated (and hence more troublefree) than fancypants AppTamer. Here's my mini review: Found the release over here on GitHub, installed, limited Lightroom Classic to 1600%, saw its CPU usage drop from 2200% to 1473% immediately. Have my computer back to work on while Lightroom imports 150,000 photos. I could see this as very useful for DaVinci Resolve renders as well. So simple to use. Brilliant. PS. Normally I don't use Lightroom, prefer FastRawViewer and DxO PhotoLab but need a catalogue of everything to merge some hard drives. Commented Aug 22, 2020 at 14:04
7

Use cpulimit

brew install cpulimit

and use as cpulimit -l (Number of threads x 100) -p (PID)

cpulimit -l 200 -p 947

where 200 means two threads.

2
  • Thanks. This answer works for me on Ventura (x64). It runs in the foreground, limiting the CPU until I quit it with Ctrl-C.
    – mwfearnley
    Commented Jan 28, 2023 at 13:31
  • 1
    On macOS cpulimit is available as Homebrew formula and works very well for single long-running processes (e.g. ffmpeg) but doesn't seem to work for processes that rapidly launch a large number of short-lived subprocesses (read: Homebrew upgrading llvm, rust or some other large package from source), even when using the -i option to include subprocesses. The commercial application App Tamer is however able to handle this, so I guess it must be somehow technically possible. Commented Dec 7, 2023 at 21:30
6

This is based off a previous answer, but adding the trap for ctrl+c to make sure the process being throttled gets left in a continue state, and adding set -e so this script will exit cleanly if the process itself exits:

trap ctrl_c_fn INT

function ctrl_c_fn() {
    echo "caught CTRL-C, exiting"
    kill -SIGCONT $pid
    exit
}

echo "enter process id"
read pid
echo "press Ctrl-C to exit"

set -e

while true; do
    kill -SIGSTOP $pid
    sleep 0.009
    kill -SIGCONT $pid
    sleep 0.001
done
6

There is a simple one-liner for doing all that:

ps axu | grep Chromium | grep -v grep | awk '{print $2}' | sudo xargs -n 1 -I'{}' sh -c 'cputhrottle {} 10 &'

Write your app name instead of Chromium and desired percentage instead of 10 and you're good to go!

3
  • 1
    This worked well, though it can be reduced to: pgrep Dropbox | sudo xargs -n 1 -I'{}' sh -c 'cputhrottle {} 10 &'. I'm not sure if macOS comes with pgrep installed, however.
    – bigsweater
    Commented Oct 1, 2018 at 21:19
  • 6
    cputhrottle no longer works on 10.14 Mojave
    – John Pang
    Commented Dec 15, 2019 at 23:47
  • cputhrottle works on 10.15 so if it wasn't working on Mojave, it might be now.
    – TJ Luoma
    Commented Jan 4, 2020 at 3:01
5

I just found CPUSetter, which, for me, is better than any of the previous options.

This app comes with additional control over hyperthreading, number of used cores, preference of physical CPU and separate power-related settings.

4
  • I was using this with some success, until I upgraded to Monterrey. Now it either won't run or worse, freezes the entire machine and logs me out.
    – KJH
    Commented Sep 16, 2022 at 14:14
  • The advantage of CPUSetter compared to cpulimit is that it limits the CPU usage not for the specific PID of a currently running or newly launched process but for all processes running or newly launched with a given name (e.g. ffmpeg) and remembers the setting. Commented Dec 7, 2023 at 22:13
  • The disadvantage of CPUSetter is that although there is an installable CLI it has only some very basic functionality and doesn't allow full control of the settings (e.g. changing the limit of a process). Also it doesn't help with the above mentioned situation of many rapidly launched short-lived processes as it occurs when building from source. Commented Dec 7, 2023 at 22:17
  • While CPUSetter isn't open source, as a nice bonus the developer describes how process limiting is implemented. My experience is that such low-level technical details are rarely shared. Only the developer of Carbon Copy Cloner comes to my mind as being rather open in that respect. Commented Dec 7, 2023 at 22:31
3

this sh worked for me

echo "enter process id"
read pid
echo "press Ctrl-C to exit"

while true; do
    kill -SIGSTOP $pid
    sleep 0.009
    kill -SIGCONT $pid
    sleep 0.001
done
1
  • Bart Meerdink's answer below (he presumably didn't have enough rep to comment at the time) suggests moving the first kill -SIGSTOP $pid into the while condition (replacing the true), so that it doesn't continue trying to kill the process after it's ended.
    – mwfearnley
    Commented Jan 28, 2023 at 13:58
3

The script Dimitri wrote does work well (on macOS), but it keeps running with errors after the application is closed. I changed it to make it finish (with an error message about PID not found):

echo "enter process id"
read pid
echo "press Ctrl-C to exit"

while kill -SIGSTOP $pid; do
    sleep 0.009
    kill -SIGCONT $pid
    sleep 0.001
done
1
  • This should probably be an edit made to Dimitri's original answer, in order to improve that answer, and not a separate answer with (basically) the same info.
    – fsb
    Commented Aug 4, 2018 at 14:34
2

This is my final script, keep clean the command cputhrottle only execute new one if doesn't exist

#!/bin/bash

###
# setup cputhrottle if doesn't exists
###
set_service_cpu_limit(){
    service_pid=$(pgrep $1)
    limit=$2
    if [[ ! -z $service_pid  ]]; then
        service_cpu=$(ps aux | grep "sudo cputhrottle $service_pid $limit" | grep -v grep | wc -l)
        if [[ ! $service_cpu -gt 0 ]]; then
            sudo cputhrottle $service_pid $limit &
        fi
    fi
}

###
# main loop
###
while true; do
    set_service_cpu_limit bzfilelist 2
    set_service_cpu_limit bztransmit 2
    sleep 0.5
done
2

I use AppPolice. It is a bit unstable and clunky but since there are no other options and the problems are minor I think it is a decent solution. Works on Catalina.

3
  • 1
    Except there are other options, such as AppTamer which is actually still under development.
    – TJ Luoma
    Commented Jan 4, 2020 at 2:43
  • This worked for me
    – atreeon
    Commented May 25, 2020 at 13:23
  • In macOS Mojave I don't find AppPolice to be unstable at all.
    – MiB
    Commented Apr 7, 2021 at 12:52
1

cputhrottle (refer to fny and Nicholas Smith's answers) works on macOS 10.15 as long as you sign the executable.

You can do so simply and quickly by following the steps listed here: https://web.archive.org/web/20191223180139/https://sourceware.org/gdb/wiki/PermissionsDarwin

You can download cputhrottle here: http://www.willnolan.com/cputhrottle/cputhrottle.html

4
  • Where would find find “cputhrottle”. And its better to include the essentials of the the link because they oftentimes go stale making the answer useless
    – Allan
    Commented Jul 2, 2020 at 2:10
  • @Allan, thanks. I added some extra links. I would have left my answer as a comment originally on the other answers but I don't have enough reputation.
    – Lambo
    Commented Jul 2, 2020 at 14:50
  • That's a different CPUThrottle, as far as I'm aware. The original one referred to above, which was on Homebrew, can be found here : medium.com/@sbr464/… I haven't tried the Will Nola one : All I see is it's a significantly smaller executable. Any idea why ? Commented Sep 15, 2020 at 21:49
  • @JPGConnolly the medium.com article links to Will Nolan's site. As for the binary sizes, when I built it for my machine with march=native, the executable was <20KiB, so there can be a lot of bloat based on compilation settings.
    – Lambo
    Commented Feb 17, 2021 at 14:18
1

This script is what I use: this code runs the app at full speed when the screen is locked else it runs at about 50% of the speed. On my M1 Pro MacBook Pro this works great for an app that normally takes 800% CPU. The computer remains responsive while the app is running in background.

#!/bin/bash

PID=$1

if [ "$PID" == "" ]; then
    echo "no process id given! Use something like:"
    echo "   ps -ef|grep whatever"
    exit
fi

# exit if any command fails
set -e
# continue running when we exit this script
trap 'kill -CONT '$PID'; exit' EXIT HUP TERM INT

status=none
prevstatus=none

while true; do
    if [ "$status" != "$prevstatus" ]; then
        date
        echo $status
        prevstatus=$status
    fi
    if python -c 'import sys,Quartz; d=Quartz.CGSessionCopyCurrentDictionary(); print d'|grep "CGSSessionScreenIsLocked = 1">/dev/null; then
        if [ "$status" != "running" ]; then
            kill -CONT $PID;
            status=running
        fi
        sleep 1;
    else
        if [ "$status" != "stopped" ]; then
            kill -STOP $PID;
            status=stopped
        else
            for _ in {1..10}; do
                sleep 0.05;
                kill -CONT $PID;
                sleep 0.05;
                kill -STOP $PID;
            done
        fi
    fi;
done

0

Some others have mentioned App Tamer and the fact that AppPolice is free. That's great, and if AppPolice meets your needs, you can be happy!

But if you use your computer professionally, the time you've lost on processes sucking down resources is probably vastly higher than the tiny cost of AppTamer.

All the options that AppTamer offers that AppPolice does not are there for a reason.

AppPolice requires you to configure each process individually. The only thing it can do globally is stop throttling. (Which could be done by closing it anyway.)

AppTamer on the other hand can distinguish before foreground and background apps, so that you can throttle an app in the background but give it full power in the foreground. Browsers, for example.

AppTamer

1
  • 1
    Maybe suggesting paid apps is not popular, but I'm glad for your answer. Personally I'm using AppTamer for this purpose and I think it's pretty much the most flexible and simplest way to throttle apps on a Mac. At least I didn't find anything better yet. I stopped using the app a while ago (Dropbox has been behaving fine for a while) but was looking for it today and didn't remember the name. Skype has been acting up lately with fequent 800% CPU usage spikes, so I'm using AppTamer to throttle it when it's in the background. I added VMware Fusion to my background throttled apps for good measure.
    – Form
    Commented Jan 24 at 14:36

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .