System resources management in modern Linux is provided by Cgroups & System. Unfortunately, most Linux distributions ignore its power. RAM and CPU abuse by modern applications is common practice. That is why we experiment recurrent CPU over-heating, memory allocation abuse and overall system slowness in consequence.

Let’s try to smoothly run Ubuntu 18.04 on an old laptop, in summer. It is likely going to meld! Because system resources in Linux desktop distributions aren’t taking advantage of modern kernel functionality! Desktop apps are allowed to abuse system resources!

Let’s fix this!

Setting up Resource Control in Linux (4.5 and up)

  1. Setup a controlled slice of system resources for heavy apps. File: /etc/systemd/system/custom.slice

    Description=Custom system resources slice

    NOTE; CPUQuota=200% is equivalent to assigning 2 cores. 300% would be 3 and so on.

  2. Setup a wrapper for running desktop apps
    File: /usr/local/bin/rcrun

    #!/usr/bin/env sh
    CMD="/usr/bin/systemd-run -p NoNewPrivileges=yes -p WorkingDirectory=${HOME} \
      --uid ${USER} --gid ${USER} -- ${2} ${3}"
    eval $CMD

    Make the script executable: $ chmod a+x /usr/local/bin/rcrun

  3. Setup policykit (polkit) to allow invoking rcrun password less:

    1. Create a polkit rule for our rcrun (v0.106 and up): File: /usr/share/polkit-1/rules.d/99-nopass-rcrun.rules

      polkit.addRule(function(action, subject) {
        if (
          ( == "org.freedesktop.systemd1.manage-units") &&
          subject.local && &&
        ) {
          return polkit.Result.YES;
    2. Create a polkit local authority for our rcrun (older than v0.106): File: /etc/polkit-1/localauthority/50-local.d/99-nopass-rcrun.pkla

      [Run user apps under resource control]
  4. Monitoring

     $ systemd-cgls # list of running services grouped by cgroup slice
     $ systemd-cgtop # list of running services interactively sorted by resource usage
  5. Testing

     $ journalctl --no-hostname --follow --unit=custom.slice
     $ rcrun custom.slice lua5.1 "-e 'a=1;t={}; while true do a=a+1;t[a]=10^10; end'"

Known issues

  • Failed to start transient service unit: Unit browser.service already exists!

    $ systemctl daemon-reload
    $ systemctl reset-failed