When investigating memory usage on a Linux server, it's common to look at processes using tools such as top, htop, or ps. However, when applications are managed by systemd, it is often more useful to inspect memory usage at the service level rather than at the individual process level.
This is especially important for services that spawn multiple worker processes.
Using systemctl
The easiest way to see the memory usage of a systemd unit is:
systemctl status my-service.service
Example output:
Memory: 423.1M
CPU: 12min 34.567s
This value represents the total memory usage of the service's cgroup, including all child processes managed by the unit.
Using systemctl show
For scripting and automation, use:
systemctl show my-service.service --property=MemoryCurrent
Example:
MemoryCurrent=443662336
The value is returned in bytes.
To convert it to megabytes:
systemctl show my-service.service --property=MemoryCurrent --value \
| awk '{ printf "%.2f MB\n", $1 / 1024 / 1024 }'
Inspecting the cgroup directly
Systemd tracks resource usage through Linux cgroups.
You can inspect the memory consumption directly:
cat /sys/fs/cgroup/system.slice/my-service.service/memory.current
Or locate the cgroup first:
systemctl show my-service.service --property=ControlGroup
Example:
ControlGroup=/system.slice/my-service.service
Then inspect the corresponding cgroup files.
Finding the processes behind a service
To see which processes belong to a unit:
systemctl status my-service.service
or
systemctl show my-service.service --property=MainPID
You can then inspect individual processes:
ps -o pid,rss,vsz,cmd -p <PID>
Keep in mind that summing RSS values from multiple processes can overestimate actual memory usage because shared memory pages may be counted multiple times.
Monitoring memory usage over time
For live monitoring:
watch -n 1 \
'systemctl show my-service.service --property=MemoryCurrent --value'
Or use:
systemd-cgtop
This tool displays CPU, memory, and I/O usage per cgroup and is often the most convenient way to identify memory-hungry services on a system.
Configuring memory limits
Systemd can also enforce memory limits.
Example:
[Service]
MemoryMax=1G
After updating the unit file:
sudo systemctl daemon-reload
sudo systemctl restart my-service.service
To verify the configured limit:
systemctl show my-service.service --property=MemoryMax
Conclusion
For services managed by systemd, MemoryCurrent is usually the most accurate representation of how much memory the service is actually consuming. Unlike process-level tools, it accounts for the entire cgroup, making it ideal for monitoring applications that use worker pools, background jobs, or multiple child processes.
Useful commands to remember:
systemctl status my-service.service
systemctl show my-service.service --property=MemoryCurrent
systemd-cgtop
These provide a much clearer picture of service-level memory usage than inspecting individual processes alone.
If this post was enjoyable or useful for you, please share it! If you have comments, questions, or feedback, you can email my personal email. To get new posts, subscribe use the RSS feed.