Yes, we're now running our Black Friday Sale. All Access and Pro are 33% off until 2nd December, 2025:
How to Create a User With Limited RAM Usage
Last updated: October 9, 2024
1. Overview
Managing system resources is crucial, especially in multi-user environments such as Linux servers or shared systems. One example is regulating the amount of RAM that a user can utilize. It enables administrators to restrict a user from consuming excessive resources which can affect other users on the system.
In this tutorial, we discuss how to create a user with limited RAM usage.
2. Introduction to Limiting Resources in Linux
Linux enables system administrators to set limits on resources that users use such as RAM, CPU, and file descriptors. Now, excessive usage of a resource can cause the system to crash or slow down. However, Linux provides tools to control the consumption of resources.
2.1. Tools and Reasons for Limiting Memory Usage
First, let’s have a look at ulimit, a built-in command to limit user resources such as RAM. ulimit enables us to limit resources available to processes started by the shell. So, we can use it to set both soft limits and hard limits on various system resources like memory. To explain, a soft limit is a limit the user can exceed temporarily. Meanwhile, a hard limit is the maximum limit the user cannot exceed and can only be modified by a superuser. Additionally, users can modify soft limits to the value of the hard limit.
Next, let’s explore systemd, a system and service manager that utilizes slices to limit the memory usage for each user. We can use it to limit memory on a per-service basis. We can apply these limits to specific users or globally.
Further, we’ll edit /etc/security/limits.conf, a configuration file for defining resource limits for users.
Here are some reasons why we may need to limit a user’s memory usage:
- Shared hosting – prevents one user from exhausting all the available memory on shared servers since the available multiple users compete for the resources
- Security – limiting the RAM usage can help prevent DoS attacks that aim to system resources
- Ensuring fairness – helps to ensure that the system resources are fairly shared among the multiple users
- Preventing system overload – a single application can exhaust all the available memory and cause the system to become unresponsive
Now, let’s first create the new user we’ll use.
2.2. Creating the New User
At this point, let’s create a new user whose memory usage we’ll limit:
$ sudo useradd -m -s /bin/bash limiteduser
This is the breakdown:
- useradd – defines the command to create a new user
- -m – creates the home directory /home/limiteduser for the new user
- -s /bin/bash – sets the Bash shell /bin/bash as the default shell for the new user
- limiteduser – represents the username to create
After creating the new user, let’s set their password:
$ sudo passwd limiteduser
Now, let’s proceed to apply the memory limits for limiteduser.
3. Limiting RAM Usage Using ulimit
When we log into a Linux system, the shell environment is assigned resource limits. The ulimit command enables us to view and modify these limits. Now, the limits we set using ulimit only last during the active terminal session. That’s why we need to use the ulimit command in the user’s configuration file .bashrc. This ensures that the limits we set for limiteduser persist across multiple shell sessions.
Here, we limit the RAM usage by editing the user’s shell profile. We’ll focus on the -m and -v options to limit the maximum RAM the user can use.
3.1. Editing the User’s Shell Profile
So, let’s utilize the ulimit command in the user’s shell configuration file to limit their memory usage. This is meant to ensure that the memory limit for limiteduser persists across multiple sessions:
For example, in Bash, we can edit the .bashrc file:
$ sudo nano /home/limiteduser/.bashrc
Once the file is open, let’s utilize -m and add a line to set the maximum memory usage for limiteduser:
ulimit -m 1048576
ulimit -m limits the limiteduser‘s maximum physical memory in kilobytes. On the other hand, 1048576 represents the limit in kilobytes which is 2GB of RAM. We can change this limit depending on the limit we want to allocate the user. Alternatively, we can add a line with the -v option:
ulimit -v 2097152
This line limits the virtual memory which includes both RAM and swap space.
Thereafter, we’ll press Ctrl + X to exit the editor, Y to confirm the changes, and Enter to confirm. Let’s note that limiteduser needs to log out and then log back in for the changes to apply.
3.2. Verifying the Changes
As the system administrator, we can use the su command to log in as limiteduser from the terminal:
$ su - limiteduser
Once the user is logged back in, we can proceed to verify the ulimit settings have taken effect:
$ ulimit -a
...
max memory size (kbytes, -m) 1048576
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 15100
virtual memory (kbytes, -v) 2097152
file locks (-x) unlimited
When we use the -m option we modify the max memory size line. Meanwhile, we modify the virtual memory line when we use the -v option.
4. Limiting RAM Usage Using systemd
With systemd, we get resource management features through slices. These slices provide a way to manage and organize a group of processes in terms of resource allocation. Now, we can assign resource limits like memory to these slices. Additionally, every user and service can be assigned to a slice.
4.1. Creating the Slice
By default, users are assigned to user.slice. However, in this case, we need to create a specific slice for the user limiteduser to apply specific limits to the user:
$ sudo nano /etc/systemd/system/limiteduser.slice
When the file opens, let’s add the following configuration, save and exit:
[Slice]
MemoryMax=1G
This configuration specifies that all processes executed by limiteduser be restricted to a maximum of 1 GB of RAM. We can modify this limit depending on the requirements needed.
After we define the memory limit, we can reload the systemd daemon to apply the changes:
$ sudo systemctl daemon-reload
Now, we can start the limiteduser slice manually:
$ sudo systemctl start limiteduser.slice
However, manually starting this slice isn’t necessary since it only contains memory limits. This is because systemd uses this slice when the user logs in or starts new processes.
4.2. Monitoring the Slice
We can view the status of the slice to ensure the memory limits have taken effect:
$ sudo systemctl status limiteduser.slice
● limiteduser.slice - Slice /limiteduser
Loaded: loaded (/etc/systemd/system/limiteduser.slice; static)
Active: active since Tue 2024-10-01 14:04:20 EAT; 5h 28min ago
Tasks: 0
Memory: 0B (max: 1.0G available: 1.0G)
CPU: 0
CGroup: /limiteduser.slice
...
The command above shows that the slice is active and includes the resource limit applied, in this case, memory limits.
Alternatively, we can utilize systemd-cgtop to monitor the memory usage:
$ sudo systemd-cgtop
This command enables monitoring the usage of resources for slices and cgroups (control groups). It displays the number of tasks, CPU, memory, and I/O of each active slice for us to monitor how much memory limiteduser is utilizing.
Importantly, when we limit the RAM usage for the user limiteduser, this limit persists across all processes started by the user limiteduser.
5. Limiting RAM Usage Using /etc/security/limits.conf
PAM (Pluggable Authentication Modules) manages this file which we can use to set memory limits for a user. We can edit this file to restrict the virtual memory the user can allocate. As a result, this limits how much memory a user can use. Additionally, these limits take effect at login time and apply to user sessions.
5.1. Making Changes to /etc/security/limits.conf
To set limits for a specific user, we need to edit the /etc/security/limits.conf file:
$ sudo nano /etc/security/limits.conf
In this file, we’ll add a line with the specific format below:
<username> <limit_type> <resource> <value>
Let’s break down this syntax:
- <username> – name of the user
- <limit_type> – specifies whether the limit is soft or hard
- <resource> – specifies the resource to be limited such as memory, CPU
- <value> – value for the limit of the resource
Now, let’s add the line to the /etc/security/limits.conf file to limit the memory for limiteduser:
limiteduser hard as 1048576 # Limit address space to 1 GB (in KB)
Let’s discuss the line above:
- limiteduser – specifies the user
- hard – specifies the limit is a hard limit which means that the limit cannot be exceeded
- as – represents the address space the total memory of RAM and swap space
- 1048576 – 1GB limit in kilobytes
This limits the virtual memory (RAM and swap space) the user limiteduser can allocate.
Next, we need to ensure that PAM is configured correctly so that it can ensure that the memory limit we set applies during user login:
$ sudo nano /etc/pam.d/common-session
In this file, let’s ensure the line below exists:
session required pam_limits.so
If the line doesn’t exist, let’s add it to the file. This is because whenever a user logs in, this line informs PAM to enforce the limits in the /etc/security/limits.conf file.
5.2. Verifying the Limit Changes
Let’s first log in as limiteduser to verify that the limit is working:
$ su - limiteduser
Once we log in, let’s check the limits:
$ ulimit -a
...
virtual memory (kbytes, -v) 1048576
...
When we see the virtual memory is set to 1048576 KB (1GB), the setting works. This approach is ideal in cases where we need the control of resources without requiring the complexity of the kernel such as using cgroups or systemd slices.
6. Conclusion
In this article, we discuss how to create a user with limited RAM usage.
We explore several approaches that we can use to limit RAM usage for limiteduser whereby each approach has its strengths. First, we use ulimit which is easy to implement and works for shell sessions. Next, we utilize systemd which helps us to manage resource limits through a unified system. After that, we edit the /etc/security/limits.conf file which enables us to manage resources at the login session level.
Using these approaches we can improve resource management and also the system’s stability.