Notes on Resource Limits in FreeBSD
Server
Published: 2022-08-10

I wasn’t very familiar with this, so I did a brief research.

To use RCTL in FreeBSD, a kernel with RACCT and RCTL enabled is required. The Generic kernel of FreeBSD 13.1 seems to have this enabled, so enable it in loader.conf.

root@freebsd13:~ # grep -E 'RACCT|RCTL' /usr/src/sys/amd64/conf/GENERIC
options         RACCT                   # Resource accounting framework
options         RACCT_DEFAULT_TO_DISABLED # Set kern.racct.enable=0 by default
options         RCTL                    # Resource limits

# echo "kern.racct.enable=1" >> /boot/loader.conf
# reboot

rctl Command

rctl -a Add rule
     -r Remove rule
     -u Display current limits
     -h Human-readable
     None List rules
     
     Deletion and listing can be filtered by user: or ::maxproc: etc.
     Example:
     # rctl user:
     user:admin:pcpu:deny=10

Scope of Limits

Limits can be applied on a per process, user, loginclass, or jail basis.

  • To limit by process

    # rctl -a process:<PID>:<resource>:<action>=<amount>
    
    • Limits are inherited by child processes but are applied on a per process basis.
  • To limit by user

    # rctl -a user:<USER NAME>:<resource>:<action>=<amount>
    # rctl -a user:<UID>:<resource>:<action>=<amount>
    
  • To limit per process for a user

    # rctl -a user:<USER NAME>:<resource>:<action>=<amount>/process
    # rctl -a user:<UID>:<resource>:<action>=<amount>/process
    

It seems that loginclass and jail can also be limited on their respective bases.

CPU

  • cputime

    • Use CPU time of the process as a rule
    • Actions can be log, devctl, sig, etc.
    • Log when the CPU time of the PID exceeds 100 seconds
      # rctl -a process:<PID>:cputime:log=100
      
  • pcpu

    • Specify as a percentage per CPU core
    • In top, it looks like the average value is restricted rather than a clean limitation.
    • Limit to 20% CPU per core (for 2 cores, you might set 200%)
      # rctl -a process:<PID>:pcpu:deny=20
      

Process Control

  • maxproc

    • Prevent the specified user from starting more than 5 processes (fork will fail)
      # rctl -a user:<USER NAME>:maxproc:deny=5
      
  • nthr

    • Prevent the specified user from running more than 5 threads
      # rctl -a user:<USER NAME>:nthr:deny=5
      

Other controls like memory management are also possible. The settings are lost upon reboot, so for persistence, write them in /etc/rctl.conf.