Optimizing AlmaLinux for specific workloads: choosing tuning profiles with tuned-adm, creating custom profiles, limiting service resources using cgroups v2 with MemoryMax and CPUQuota, and reading boot and service results with systemd-analyze.

In the previous episode, Episode 16, we secured the system and ensured standard compliance. Now we turn to the other side of a good system: performance. A secure but slow server is just as problematic — and so is a server that lets one service wastefully consume all resources while other services starve.
This episode covers three main tools: tuned for matching system profiles to workloads, cgroups v2 for limiting resources per service, and systemd-analyze for reading boot and startup conditions.
tuned is a daemon that adjusts system parameters (sysctl, scheduler, and others) according to a chosen profile. Instead of manually tuning one parameter at a time, you pick a profile matching the workload.
sudo dnf5 install -y tuned
sudo systemctl enable --now tunedtuned-adm active
tuned-adm listtuned-adm active shows the running profile; list shows all available profiles. For an automatic recommendation:
tuned-adm recommend| Profile | Best For |
|---|---|
virtual-guest | VMs (default on VMs); optimizes for the guest |
throughput-performance | Maximum throughput; friendly for busy servers |
latency-performance | Minimal latency; for real-time workloads |
balanced | A compromise between power saving and performance (default) |
powersave | Power saving for laptops and idle systems |
sudo tuned-adm profile throughput-performance
tuned-adm activeThe throughput-performance profile enables the performance governor, increases network buffers, and adjusts several parameters to maximize output — a common choice for database and application servers.
Tip
On VMs, the virtual-guest profile is a wise choice — tuned detects the hypervisor and adjusts parameters so there's no conflict with the host. Use special profiles like throughput-performance only when there's a clear, measured reason.
For specific needs, create your own profile in /etc/tuned/:
[main]
summary=My web server tuning
[cpu]
governor=performance
[sysctl]
vm.swappiness=10
net.core.somaxconn=1024The file structure: a [main] section, then sections managing components (cpu, sysctl, vm, and others). Activate the custom profile:
sudo tuned-adm profile mywebtuned-adm active will show myweb. A custom profile can also inherit another profile by adding include= in the [main] section.
In episode 7 we touched on MemoryMax and CPUQuota. Now we dive into how cgroups v2 is the mechanism behind them — the kernel divides processes into groups with resource limits.
All limits are defined in the systemd unit override:
sudo systemctl edit myapp[Service]
MemoryMax=1G
MemoryHigh=768M
CPUQuota=100%
TasksMax=512Explanation of each line:
MemoryMax=1G — the hard limit; the process is killed if it exceeds it.MemoryHigh=768M — the soft limit; throttling happens before the hard limit.CPUQuota=100% — equivalent to one full core; 200% means two cores.TasksMax=512 — limits the number of tasks (threads/processes) that can be created.sudo systemctl daemon-reload
sudo systemctl restart myapp
systemd-cgtopsystemd-cgtop is the cgroup equivalent of top — showing real-time resource usage per unit. It's the best tool for seeing whether limits work and who the biggest resource consumers are.
systemctl show myapp -p MemoryMax -p CPUQuota
systemctl status myappsystemctl show displays unit properties — verify that limits are actually applied as expected.
Warning
Setting MemoryMax too low is a fast way to shoot yourself in the foot — the service can be killed in the middle of a load spike. Start with a generous value, monitor with systemd-cgtop, then lower it gradually. Remember, tuning is a process of measurement, not guessing.
Systemd provides analysis commands that turn boot data into insight.
systemd-analyzesystemd-analyze blameblame sorts services by initialization time — from slowest first. Focus on services taking a disproportionate amount of time:
systemd-analyze critical-chaincritical-chain shows the unit chain that most determines boot time — services on the critical path are the first optimization candidates.
systemd-analyze blame --reverseBy comparing across boots, you can measure whether tuning changes actually speed up startup — data is more reliable than feeling.
throughput-performance on a VM. The virtual-guest profile is more appropriate — avoid conflicts with the host.MemoryMax too low. Start big, monitor, lower gradually.systemd-cgtop. Real-time usage data is the only way to verify limits are working.In this episode 17 you've mastered AlmaLinux performance optimization: selecting tuning profiles with tuned-adm, creating custom profiles, limiting service resources with cgroups v2 via MemoryMax and CPUQuota, and boot and startup analysis with systemd-analyze.
Key takeaways:
tuned-adm selects a profile by workload: virtual-guest, throughput-performance, latency-performance./etc/tuned/ with [cpu] and [sysctl] sections.MemoryMax, MemoryHigh, CPUQuota, TasksMax.systemd-cgtop and systemctl show for verification.systemd-analyze blame and critical-chain find startup bottlenecks.With performance under control, you're ready to manage modern workloads. In the next episode, Episode 18, we'll cover Containers & Virtualization (Podman, KVM) — rootless containers with Podman, Buildah, and Skopeo, Quadlet for systemd integration, podman-compose, and KVM virtualization with virt-install, virsh, and bridge networking. See you there!