Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minutePC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
Need a server to try this on? Antihost offers Linux VPS plans with NVMe storage, full root access and a 14-day free trial.
Use cgroups (control groups) to place processes in a hierarchy and enforce CPU, memory, I/O, and process-count policies. On a systemd host, the safest method is usually a transient scope or service-unit settings such as CPUQuota= and MemoryMax=. When systemd is not managing the workload, create a cgroup v2 directory, enable controllers, write the process ID to cgroup.procs, and configure files including cpu.max, memory.max, io.max, and pids.max.
What a Linux cgroup does
A control group, or cgroup, is a hierarchical group of processes with policies for distributing and limiting system resources. Every process belongs to a cgroup hierarchy. A parent cgroup can constrain all of its descendants, so a child cannot use more than the effective limits imposed by its ancestors.
The Linux kernel documentation describes a cgroup as “a mechanism to organize processes hierarchically and distribute system resources along the hierarchy in a controlled and configurable manner.” In cgroup v2, a single unified hierarchy exposes controller files for CPU, memory, I/O, process counts, and other resources. The kernel man-pages project identifies cgroup v2 as official beginning with Linux 4.5 (2025 edition).
Cgroups are not a process scheduler, virtual machine, or security boundary by themselves. They control accounting and resource distribution. Permissions, namespaces, service supervision, and container isolation are separate concerns.
#1 Best Overall
Choose the management layer first
| Approach | Best scope | Typical controls | Important trade-off |
|---|---|---|---|
| Transient systemd scope | One command or short-lived workload | CPUQuota=, MemoryMax=, TasksMax= |
Easy to start and clean up; the scope ends when its processes exit. |
| systemd service unit | Long-running daemon | CPUQuota=, CPUWeight=, MemoryMax=, I/O limits, TasksMax= |
Persistent configuration and systemd ownership; changes require a daemon reload. |
| Direct cgroup v2 files | Hosts without systemd, custom supervisors, or low-level tooling | cpu.max, memory.max, memory.high, io.max, pids.max |
Maximum control, but you must handle hierarchy, delegation, permissions, cleanup, and race conditions. |
| Container or orchestrator settings | Containers and pods | Runtime or pod CPU and memory requests/limits translated to cgroup settings | The runtime and kubelet are the writers; host cgroup mode and driver affect observed behavior. |
Do not have multiple managers write the same cgroup. The systemd cgroup v2 interface requires each individual cgroup to have a single writer. If systemd owns a service cgroup, configure the unit rather than editing that directory behind systemd’s back.
Check whether the host uses cgroup v2
Run these commands before setting a limit:
stat -fc %T /sys/fs/cgroup
cat /sys/fs/cgroup/cgroup.controllers
systemctl --version
A cgroup v2 host reports cgroup2fs from the stat command. The cgroup.controllers file lists controllers available at the root of the mounted hierarchy, such as cpu, memory, io, and pids. Availability depends on kernel configuration, boot parameters, and delegation. A controller must be enabled in a parent before its interface files appear in a child.
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →To see where a shell or service currently belongs, inspect its status and cgroup path:
cat /proc/$$/cgroup
systemctl status example.service
systemd-cgls
On a systemd host, systemd-cgls displays the service and slice hierarchy. systemd-cgtop provides a live view of cgroup CPU, memory, and task activity when the relevant accounting is available.
Limit a one-off command with a transient systemd scope
A scope lets systemd manage a command without requiring a permanent unit file. This is generally the least error-prone method for an interactive or batch job on a systemd host.
- Start the command with the desired properties:
systemd-run --scope -p CPUQuota=50% -p MemoryMax=1G -- ./workload
CPUQuota=50%requests no more than half of one CPU over time. A value of200%permits up to two CPUs’ worth of aggregate CPU time, subject to available CPUs and ancestor limits.MemoryMax=1Gmaps to a hard cgroup memory limit. If memory cannot be reclaimed, the cgroup OOM path can terminate a process in the group.
- In another terminal, identify the transient unit and inspect it:
systemctl list-units --type=scope
systemctl status workload.scope
systemd-cgtop
- After the command exits, confirm that the scope is gone or no longer contains tasks. If the workload forks children, they remain controlled because systemd tracks the entire scope cgroup.
A scope is appropriate when the limit should follow one invocation. For a daemon that must be restarted or enabled at boot, use a service unit instead.
Apply persistent limits to a systemd service
Create a drop-in rather than editing a vendor unit directly. For a unit named example.service:
sudo systemctl edit example.service
Add:
[Service]
CPUQuota=50%
CPUWeight=200
MemoryMax=1G
IOReadBandwidthMax=/dev/nvme0n1 20M
TasksMax=256
Save the drop-in, then load and restart the service:
sudo systemctl daemon-reload
sudo systemctl restart example.service
systemctl status example.service
The properties have different purposes:
| Property | Resource model | What it means |
|---|---|---|
CPUQuota=50% |
Hard bandwidth cap | Caps aggregate CPU time over scheduling periods at half of one CPU. It does not pin a process to a core, set CPU frequency, or guarantee latency. |
CPUWeight=200 |
Proportional weight | Sets relative CPU priority when competing cgroups are runnable. It is not an absolute ceiling; a group can use more CPU when spare capacity exists. |
MemoryMax=1G |
Hard memory ceiling | Maps to the cgroup’s maximum memory boundary. Reclaim and the cgroup OOM mechanism apply when usage cannot be reduced. |
IOReadBandwidthMax=/dev/nvme0n1 20M |
I/O bandwidth cap | Limits reads from the specified block device to the stated rate. Use the device node that actually serves the workload. |
TasksMax=256 |
Process-count ceiling | Limits the number of tasks in the service cgroup, including threads where applicable. A process that cannot create another task will receive a resource error. |
Choose either a hard cap or proportional priority according to the goal. A CPU-intensive batch job that must never consume more than a fraction of a machine needs CPUQuota=. A group that should receive a larger share only during contention is better served by CPUWeight=. The two settings can be combined when you need both a priority relationship and an upper bound.
Inspect the effective settings and recent failures:
Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Repair Windows errors before they cause bigger problemsFix Now →Scan for outdated or missing drivers - takes under a minuteDriver Scan →systemctl show example.service -p CPUQuotaPerSecUSec -p CPUWeight -p MemoryMax -p TasksMax
journalctl -u example.service --since today
systemd-cgtop
If a drop-in appears correct but behavior has not changed, check that the service was restarted after daemon-reload, that the process is in the expected unit, and that an ancestor slice is not imposing a lower limit.
Configure cgroup v2 directly
Direct file operations are useful when systemd is not the manager or when a purpose-built supervisor owns a delegated subtree. The example below assumes that /sys/fs/cgroup is a writable cgroup v2 mount and that you have the required privileges.
1. Create a child cgroup
sudo mkdir /sys/fs/cgroup/my-workload
2. Enable controllers in the parent
Controllers are enabled for descendants through the parent’s cgroup.subtree_control. Enable only controllers exposed by cgroup.controllers:
cat /sys/fs/cgroup/cgroup.controllers
sudo sh -c 'printf "+cpu +memory +io +pids" > /sys/fs/cgroup/cgroup.subtree_control'
If a controller is unavailable, delegated, or blocked by the hierarchy, the write fails. Do not assume every kernel exposes every controller.
Recommended Free Tools
3. Set the child’s policies
sudo sh -c 'printf "50000 100000" > /sys/fs/cgroup/my-workload/cpu.max'
sudo sh -c 'printf "1G" > /sys/fs/cgroup/my-workload/memory.max'
sudo sh -c 'printf "256" > /sys/fs/cgroup/my-workload/pids.max'
cpu.max contains a quota and period in microseconds. The example allows 50,000 microseconds of CPU time in each 100,000-microsecond period, equivalent to 50% of one CPU. A value of max in the quota position removes the quota, subject to parent constraints.
4. Place the process in the cgroup
sudo sh -c 'printf "%s" 12345 > /sys/fs/cgroup/my-workload/cgroup.procs'
Replace 12345 with the workload PID. Writing to cgroup.procs moves the process and its subsequently created descendants according to cgroup rules. Put the process in the target group before it allocates significant resources when possible; a process can otherwise consume resources in its original group first.
5. Apply an I/O rule when needed
cat /sys/fs/cgroup/my-workload/io.controllers
sudo sh -c 'printf "8:0 rbps=20971520" > /sys/fs/cgroup/my-workload/io.max'
The device identifier must match the block device’s major and minor numbers. Obtain them with lsblk or stat; do not copy 8:0 blindly to a different machine. The exact io.max syntax supports per-device limits such as read or write bytes per second, IOPS, and latency controls depending on the kernel interface.
6. Verify that the process is controlled
cat /sys/fs/cgroup/my-workload/cgroup.procs
cat /sys/fs/cgroup/my-workload/cpu.max
cat /sys/fs/cgroup/my-workload/cpu.stat
cat /sys/fs/cgroup/my-workload/memory.current
cat /sys/fs/cgroup/my-workload/memory.events
cat /sys/fs/cgroup/my-workload/io.stat
cat /sys/fs/cgroup/my-workload/pids.current
Remove the directory only after it contains no processes:
sudo rmdir /sys/fs/cgroup/my-workload
Manual changes under a system-managed hierarchy are not persistent across reboot and may be overwritten. For repeatable service policy, encode the settings in the manager that owns the cgroup.
Understand CPU controls
CPU quota is a time-bandwidth limit. It regulates aggregate CPU time over scheduler periods; it does not lock a process to a particular CPU, choose a frequency, or promise a response-time bound. A quota can therefore protect overall capacity while still allowing short bursts within a period.
Weights are different. A weight expresses a relative share among competing cgroups. If a sibling is idle, a weighted group may use most of the machine. If several siblings are busy, their effective shares depend on weights and all ancestor limits. Use quota for “never exceed this amount” and weight for “prefer this group when there is contention.”
Rank #4
Inspect cpu.stat for usage and throttling counters. A rising throttled-time counter indicates that the quota, rather than lack of runnable work, is limiting execution. If a service is slow despite a generous local quota, inspect parent slices and system-wide CPU pressure.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Understand memory.max and memory.high
| File or property | Behavior | When to use it |
|---|---|---|
memory.high |
Reclaim and throttling boundary. The kernel applies pressure to the cgroup and slows it while reclaiming; it does not directly invoke the cgroup OOM killer. | Shape memory growth and create an early-warning boundary before a hard failure. |
memory.max / MemoryMax= |
Hard maximum. When usage cannot be reduced, the cgroup OOM path may kill a process in the group. | Enforce a firm ceiling for a service or workload that can tolerate an OOM failure mode. |
memory.current |
Current accounted usage for the cgroup. | Observe consumption and compare it with configured boundaries. |
memory.events |
Event counters for high, max, OOM, and related conditions. | Detect reclaim pressure, limit hits, and OOM activity. |
Memory accounting includes major user-space allocations, page cache, and several kernel structures. Coverage can expand as kernel accounting gains support for additional memory types. A cgroup’s configured maximum is not an unconditional byte-for-byte instantaneous cutoff: it can be exceeded temporarily in some circumstances, and not every allocation path invokes the OOM killer. Treat it as a control boundary with an observable failure mode.
Set memory.high below memory.max when you want reclaim pressure before a hard stop. Monitor memory.events and application latency; a high boundary that is too low can cause sustained reclaim and make a service appear hung even though it has not reached the maximum.
Use hierarchy deliberately
Limits are cumulative. If a service has MemoryMax=1G but its parent slice allows only 512 MiB, the effective ceiling is constrained by the parent. The same rule applies to CPU quota, I/O controls, and task counts. A child cannot escape an ancestor’s limit by writing a larger value locally.
Conversely, a parent policy can unintentionally throttle unrelated services if they share the same slice. Inspect the hierarchy with systemd-cgls or by walking cgroup.procs and cgroup.subtree_control before moving processes. Design slices so that workloads with different service-level objectives do not inherit a constraint meant for another group.
Observe limits, pressure, and failures
Configuration alone does not prove that a limit is active. Pair each policy with an observable signal:
- CPU:
cpu.statfor usage and throttling;systemd-cgtopfor a live view. - Memory:
memory.currentagainstmemory.maxandmemory.high;memory.eventsfor reclaim, max, and OOM counters. - I/O:
io.statfor per-device activity and throttling information. - Tasks:
pids.currentagainstpids.max; service logs for failed thread or process creation. - Service state:
systemctl status,systemctl show, and the journal for restart, timeout, or OOM symptoms.
Linux pressure-stall information can explain why a limit causes user-visible delay even before a hard ceiling is reached. Compare pressure and cgroup event counters with application metrics rather than judging success only by a single instantaneous reading.
Best Value
- New
- Mint Condition
- Dispatch same day for order received before 12 noon
- Guaranteed packaging
- No quibbles returns
Common failure modes and fixes
The controller file is missing
The controller may not be enabled in the parent, may not be compiled into the kernel, or may not be delegated to your user. Check cgroup.controllers at each level and enable the controller in the parent’s cgroup.subtree_control where you have permission.
The write is rejected with a busy or invalid-operation error
Some cgroup operations require the parent’s process-placement rules to be satisfied. In particular, a domain cgroup generally must have no member processes before enabling controllers for its descendants. Move processes to an appropriate child or manager-owned unit, then retry.
The limit appears ignored
Confirm cgroup v2 is mounted, verify the process PID in the target cgroup.procs, inspect ancestor limits, and check that another manager has not moved the process. For systemd, use systemctl show to inspect the effective unit properties and restart after reloading the configuration.
A service is killed near its memory limit
Read memory.events and service logs. A rising oom or oom_kill counter indicates the hard path, while rising high events indicate reclaim and throttling. Raise memory.max, reduce the workload’s footprint, or introduce a higher memory.high threshold if the failure is premature for the application.
CPU latency worsens after setting a quota
Quota controls time over a period, not latency. Check throttling in cpu.stat. If the goal is fair sharing rather than an absolute cap, replace or supplement the quota with CPUWeight=; if the workload is latency-sensitive, size the quota and period with the application’s burst pattern in mind.
Manual settings disappear
Files under /sys/fs/cgroup represent live kernel state. Reboots, service restarts, and systemd reconciliation can remove manual settings. Put persistent policy in a service drop-in or the configuration system that owns the delegated subtree.
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Fix the driver behind crashes, sound loss and screen glitches3Clear out junk files and repair common Windows errorsContainers and Kubernetes
Container runtimes and Kubernetes use cgroups to enforce pod and container CPU and memory limits. The runtime or kubelet translates resource settings into cgroup configuration, so a container’s behavior depends on the host’s cgroup mode, kernel controllers, and runtime driver.
When a pod does not behave as expected, inspect the node’s cgroup filesystem and the runtime’s driver before changing application settings. A pod limit can be correct while an ancestor slice, node-level reservation, or unavailable controller changes the effective result. Avoid manually editing a container’s manager-owned cgroup; use the container runtime or Kubernetes specification so that reconciliation does not undo the change.
A practical decision checklist
- Use a transient systemd scope for one command on a systemd host.
- Use a service-unit drop-in for a daemon that must retain its limits across restarts.
- Use direct cgroup v2 files only when you own a delegated subtree or systemd is not the manager.
- Use
CPUQuota=orcpu.maxfor an absolute CPU ceiling; useCPUWeight=for relative priority. - Use
memory.highfor throttling and reclaim pressure; usememory.maxfor a hard boundary with a possible OOM failure. - Enable controllers before using their files and verify that ancestors do not impose tighter limits.
- Record baseline usage, then verify with controller statistics and event counters.
- Leave ownership to one manager per cgroup.
Minimal worked example
For a service that should use at most half a CPU, no more than 1 GiB of accounted memory, and 256 tasks, create a drop-in containing:
[Service]
CPUQuota=50%
MemoryMax=1G
TasksMax=256
Apply it with:
sudo systemctl daemon-reload
sudo systemctl restart example.service
systemctl show example.service -p CPUQuotaPerSecUSec -p MemoryMax -p TasksMax
systemctl status example.service
Then monitor systemd-cgtop, the service journal, and the cgroup’s CPU, memory, and task counters. This confirms both the configured policy and its runtime effect without bypassing systemd’s ownership of the service cgroup.
Free tools Windows power users keep installed
One-click scans. No signup required.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

