16

Due to its high CPU usage i want to limit Chromium web browser by cpulimit and use terminal to run:

cpulimit -l 30 -- chromium --incognito

but it does not limit CPU usage as expected (i.e. to maximum to 30%). It again uses 100%. Why? What am I doing wrong?

2 Answers 2

28

Yeah, chromium doesn't care much when you stop one of its threads.

cpulimit is, in 2021, really not the kind of tool that you want to use, especially not with interactive software: it "throttles" processes (or unsuccessfully tries to, in your case) by stopping and resuming them via signals. Um. That's a terrible hack, and it leads to unreliability you really don't want in a modern browser that might well be processing audio and video, or trying to scroll smoothly.

Good news is that you really don't need it. Linux has cgroups, and these can be used to limit the resource consumption of any process, or group of processes (if you, for example, don't want chromium, skype and zoom together to consume more than 50% of your overall CPU capacity). They can also be used to limit other things, like storage access speed and network transfer.

In the case of your browser, that'd boil down to (top of head, not tested):

# you might need to create the right mountpoints first
sudo mkdir /sys/fs/cgroup/cpu
sudo mount -t cgroup -o cpu cpu /sys/fs/cgroup/cpu

# Create a group that controls `cpu` allotment, called `/browser`
sudo cgcreate -g cpu:/browser
# Create a group that controls `cpu` allotment, called `/important`
sudo cgcreate -g cpu:/important

# allocate few shares to your `browser` group, and many shares of the CPU time to the `important` group.
sudo cgset -r cpu.shares=128 browser
sudo cgset -r cpu.shares=1024 important


cgexec -g cpu:browser chromium --incognitio
cgexec -g cpu:important make -j10 #or whatever

The trick is usually giving your interactive session (e.g. gnome-session) a high share, and other things a lower one.

Note that this guarantees shares; it doesn't take away, unless necessary. I.e. if your CPU can't do anything else in that time (because nothing else is running, or because everything with more shares is blocked, for example by waiting for hard drives), it will still be allocated to the browser process. But that's usually what you want: It has no downsides (it doesn't make the rest of the system run any slower, the browser is just quicker "done" with what it has to do, which on the upside probably even saves energy on the average: when multiple CPU cores are just done, then things can be clocked down/suspended automatically).

16
  • 2
    @jamesqf have you confirmed that your behavior is caused by Firefox consuming too much CPU? That sort of thing can many causes, such as IO contention, GPU bugs, some other process hitting a CPU spike after Firefox interacts with it, &c. Of course, it could very well be Firefox using too much CPU, but that’s not always it.
    – gntskn
    Jul 25, 2021 at 1:44
  • 2
    @jamesqf If a given CPU time slice isn't going to be used anyway, giving it to Firefox/Chromium/whatever isn't going to slow the system down any. In fact, doing so will make the system more responsive as opposed to just wasting the slice. Jul 25, 2021 at 1:53
  • 2
    @jamesqf I'm almost certain the problem you describe here is a bug in something else; if you just start a program that hogs CPU time, you should still be able to do things with your computer, as the Linux scheduler should allocate some share of time to other tasks. The fact that it's this choppy might really be due to some unholy interaction between firefox and X or your graphics driver Jul 25, 2021 at 9:39
  • 2
    Cgroups are the right tool for the job, but they should probably be used through systemd, not directly. Create a new slice with a CPUWeight and systemd-run the application into it. It does not need sudo (user can control what's happening within their slice) and it sets the weight relative to the other user's applications (they already live in the /user.slice/user-$uid.slice cgroup).
    – Jan Hudec
    Jul 25, 2021 at 16:13
  • 1
    @jamesqf Sounds to me like you're running out of memory. If that is the case, you can reduce the number of firefox processes under the performance settings. Jul 25, 2021 at 21:27
4

I think it might be useful to focus on finding why it uses this much CPU, using the Taskmanager built-in to chromium to find which tab is using it, or a profiler like perf and flame graphs.

But if you really want to slow down the browser you should consider the modern built-in solution cgroups, see for example: https://forums.gentoo.org/viewtopic-t-1010870-start-0.html

Alternatively consider using (re)nice to lower the priority of chromium, using AdBlockers or upgrading your hardware.

Why cpulimit is not working as expected might be due to multiple threads, child processes not stopping when sigstop stops the parent proces but I'm not sure.

Update: this https://github.com/opsengine/cpulimit/issues/39 and this: https://stackoverflow.com/questions/31623697/limit-the-percentage-of-cpu-a-process-tree-is-allowed-to-use confirm my suspicion that you might not be limiting all child processes. Newer versions of cpulimit provide the option: --include-children or: -i for that.

2
  • A simple trial would be to run greedy programs in a VM - with limited resources. Jul 24, 2021 at 22:09
  • But in my case, trying to find out why is futile (beyond knowing what site I went to), because the browser grabs so much CPU &c that nothing else is responsive. And much of this is caused by going to news articles from Google News, where say a particular CNN story link causes the behaviour, but many other links work perfectly well.
    – jamesqf
    Jul 24, 2021 at 22:23

You must log in to answer this question.