Configure Linux CPU and process scheduling with systemd and nice priorities for workload optimization

Intermediate 25 min Apr 03, 2026 61 views
Ubuntu 24.04 Ubuntu 22.04 Debian 12 AlmaLinux 9 Rocky Linux 9 Fedora 41

Learn to optimize Linux workloads by configuring CPU scheduling policies, setting process priorities with nice and ionice commands, and implementing systemd service limits for better resource allocation and performance.

Prerequisites

  • Root or sudo access
  • Basic understanding of Linux processes
  • Familiarity with systemd services

What this solves

Linux CPU scheduling determines which processes get processor time and in what order. By default, Linux uses the Completely Fair Scheduler (CFS) which gives equal CPU time to all processes, but production workloads often need fine-tuned resource allocation. This tutorial shows you how to prioritize critical services, limit resource-hungry applications, and optimize system performance through proper CPU scheduling configuration.

Understanding Linux process scheduling

Process priorities and nice values

Linux uses nice values ranging from -20 (highest priority) to +19 (lowest priority) to determine process scheduling priority. Lower nice values get more CPU time, while higher values get less. Regular users can only increase nice values (lower priority), while root can set any value.

The priority formula is: Priority = 20 + nice_value. A process with nice value -10 has priority 10, while nice value +10 gives priority 30. The kernel scheduler uses these priorities to allocate CPU time slices.

Scheduling policies

Linux supports multiple scheduling policies beyond the default CFS. Real-time policies like SCHED_FIFO and SCHED_RR provide deterministic scheduling for time-critical applications. SCHED_BATCH optimizes for throughput over latency, while SCHED_IDLE runs processes only when the system is otherwise idle.

PolicyUse casePriority range
SCHED_NORMAL (CFS)Default for most processesNice -20 to +19
SCHED_FIFOReal-time, first-in-first-outRT priority 1-99
SCHED_RRReal-time, round-robinRT priority 1-99
SCHED_BATCHCPU-intensive batch jobsNice -20 to +19
SCHED_IDLEBackground tasksNice +19 equivalent

Step-by-step configuration

Install scheduling tools

Install the utilities needed for process scheduling management and monitoring.

sudo apt update
sudo apt install -y util-linux schedutils htop iotop
sudo dnf install -y util-linux schedutils htop iotop

Check current process priorities

View current process priorities and scheduling information using standard Linux tools.

# View processes with priority information
ps -eo pid,ppid,ni,pri,psr,comm --sort=-ni | head -20

Check scheduling policy for a specific process

chrt -p 1234

View system load and process priorities

htop

Set process priorities with nice

Use nice to start processes with specific priority levels and renice to adjust running processes.

# Start a process with lower priority (higher nice value)
nice -n 10 find / -name "*.log" 2>/dev/null

Start a CPU-intensive task with lowest priority

nice -n 19 tar czf backup.tar.gz /home/user/documents/

As root, start a high-priority process

sudo nice -n -5 important-service

Adjust priority of running process (find the PID first)

ps aux | grep find sudo renice -10 -p 12345

Configure I/O scheduling with ionice

Set I/O scheduling classes and priorities to manage disk access priorities alongside CPU scheduling.

# Set I/O class to idle (only when system is idle)
ionice -c 3 -p 12345

Set best-effort I/O with priority 7 (lowest)

ionice -c 2 -n 7 dd if=/dev/zero of=/tmp/testfile bs=1M count=1000

Start process with real-time I/O priority (root only)

sudo ionice -c 1 -n 4 database-backup-script

Check current I/O scheduling

ionice -p 12345
Note: I/O scheduling classes are: 0=none, 1=real-time, 2=best-effort, 3=idle. Real-time I/O can starve other processes and should be used carefully.

Set scheduling policies with chrt

Use chrt to configure advanced scheduling policies for real-time and batch processing requirements.

# Set SCHED_BATCH policy for CPU-intensive tasks
chrt -b 0 cpu-intensive-calculation

Set SCHED_IDLE for background processes

chrt -i 0 background-maintenance-task

Set real-time FIFO scheduling (root only)

sudo chrt -f 50 time-critical-application

Set real-time round-robin scheduling

sudo chrt -r 30 -p 12345

Check scheduling policy and priority

chrt -p 12345
Warning: Real-time scheduling policies can lock up your system if used incorrectly. Always test in non-production environments first and ensure processes have proper exit conditions.

Configure systemd service CPU limits

Create systemd service configurations with CPU scheduling and resource limits for consistent service management.

[Unit]
Description=High Priority Application
After=network.target

[Service]
Type=simple
User=appuser
Group=appgroup
ExecStart=/opt/myapp/bin/myapp
Restart=always

CPU scheduling configuration

Nice=-10 CPUSchedulingPolicy=2 CPUSchedulingPriority=0 IOSchedulingClass=2 IOSchedulingPriority=2

CPU resource limits

CPUQuota=200% CPUWeight=200 [Install] WantedBy=multi-user.target

Create batch processing service

Configure a systemd service optimized for batch processing with appropriate scheduling policies.

[Unit]
Description=Batch Processing Service
After=network.target

[Service]
Type=simple
User=batchuser
Group=batchgroup
ExecStart=/opt/batch/processor
Restart=on-failure

Batch scheduling configuration

Nice=15 CPUSchedulingPolicy=3 IOSchedulingClass=3

Resource constraints

CPUQuota=50% CPUWeight=50 MemoryMax=2G [Install] WantedBy=multi-user.target

Configure CPU affinity and NUMA

Set CPU affinity to bind processes to specific CPU cores for improved performance and cache locality.

# Check system CPU topology
lscpu
numactl --hardware

Bind process to specific CPUs (cores 0-3)

taskset -c 0-3 cpu-bound-application

Bind process to CPU cores using hex mask (cores 0,2,4,6)

taskset 0x55 application

Check current CPU affinity

taskset -p 12345

Set CPU affinity for running process

sudo taskset -cp 0,2,4,6 12345

Configure systemd service with CPU affinity

Add CPU affinity settings to systemd service files for consistent CPU binding.

[Unit]
Description=CPU Bound Application
After=network.target

[Service]
Type=simple
User=appuser
ExecStart=/opt/app/cpu-intensive-app
Restart=always

CPU affinity and scheduling

CPUAffinity=0-3 Nice=0 CPUSchedulingPolicy=0

Resource limits

CPUQuota=400% CPUWeight=100 [Install] WantedBy=multi-user.target

Apply and verify systemd configurations

Reload systemd configuration and start services with the new scheduling settings.

# Reload systemd daemon
sudo systemctl daemon-reload

Start and enable services

sudo systemctl enable --now high-priority.service sudo systemctl enable --now batch-processor.service sudo systemctl enable --now cpu-bound.service

Check service status

sudo systemctl status high-priority.service sudo systemctl status batch-processor.service

Configure CPU scheduling limits globally

Set system-wide limits and default scheduling parameters for better resource management.

# Set nice limits for users and groups
@developers     soft    nice    -10
@developers     hard    nice    -5
batchuser       soft    nice    15
batchuser       hard    nice    19

Set real-time priority limits

@realtime soft rtprio 50 @realtime hard rtprio 80

Memory limits

@developers soft memlock unlimited @developers hard memlock unlimited

Configure kernel scheduler parameters

Tune kernel scheduler parameters for your workload requirements using sysctl.

# CFS scheduler tuning
kernel.sched_latency_ns = 6000000
kernel.sched_min_granularity_ns = 750000
kernel.sched_wakeup_granularity_ns = 1000000

Real-time throttling (percentage of CPU time for RT tasks)

kernel.sched_rt_runtime_us = 950000 kernel.sched_rt_period_us = 1000000

NUMA balancing

kernel.numa_balancing = 1

Process scheduling

kernel.sched_autogroup_enabled = 0

Apply kernel parameters

Load the new kernel parameters and verify they are applied correctly.

# Apply sysctl settings
sudo sysctl -p /etc/sysctl.d/99-scheduler.conf

Verify settings

sysctl kernel.sched_latency_ns sysctl kernel.sched_rt_runtime_us sysctl kernel.numa_balancing

View all scheduler-related parameters

sysctl -a | grep sched

Monitor and troubleshoot CPU scheduling

Monitor CPU scheduling with top and htop

Use system monitoring tools to observe CPU scheduling behavior and process priorities in real-time.

# Monitor with enhanced top output
top -c -o %CPU

Press 'f' to add fields, 'V' to show process hierarchy

Use htop for better visualization

htop

Press F6 to sort by CPU%, F4 to filter, F5 for tree view

Monitor specific processes

watch -n 1 'ps -eo pid,ppid,ni,pri,psr,pcpu,comm --sort=-pcpu | head -15'

Use systemd tools for monitoring

Leverage systemd's built-in monitoring capabilities to track service resource usage and scheduling.

# Show service CPU usage
systemctl show high-priority.service --property=CPUUsageNSec
systemctl show batch-processor.service --property=CPUUsageNSec

Monitor service resource usage

sudo systemd-cgtop

View detailed service status

systemctl status high-priority.service systemctl status batch-processor.service

Check service resource limits

systemctl show high-priority.service | grep -E '(CPU|Memory|IO)'

Use performance monitoring tools

Deploy advanced monitoring tools to analyze CPU scheduling performance and identify bottlenecks.

# Monitor system performance with SAR
sar -u 1 10
sar -q 1 10

Use iostat for I/O and CPU statistics

iostat -x 1 5

Monitor process scheduling with pidstat

pidstat -u -p ALL 1 5 pidstat -w -p ALL 1 5

Check CPU topology and usage

lscpu mpstat -P ALL 1 5

Verify your setup

# Check service status and resource usage
sudo systemctl status high-priority.service batch-processor.service cpu-bound.service

Verify process priorities and scheduling

ps -eo pid,ni,pri,psr,cls,comm --sort=-ni | head -20

Check CPU affinity settings

taskset -p $(pgrep cpu-intensive-app)

Monitor real-time CPU scheduling

htop

Verify kernel scheduler parameters

sysctl kernel.sched_latency_ns kernel.sched_rt_runtime_us

Check system load and CPU usage

uptime sar -u 1 3

Common issues

SymptomCauseFix
High-priority process not getting CPU timeReal-time throttling limitsAdjust kernel.sched_rt_runtime_us or use SCHED_NORMAL with low nice value
System becomes unresponsiveReal-time process consuming all CPUUse sudo pkill -STOP process_name then adjust scheduling policy
Permission denied setting priorityUser lacks privilegesConfigure limits in /etc/security/limits.conf or run as root
Batch jobs interfering with interactive tasksIncorrect scheduling policyUse SCHED_BATCH or SCHED_IDLE for background processes
Poor performance on NUMA systemsProcess migrating between NUMA nodesSet CPU affinity with taskset or CPUAffinity in systemd
Systemd service limits not appliedService configuration errorCheck syntax with systemd-analyze verify service.service

Next steps

Automated install script

Run this to automate the entire setup

#cpu-scheduling #systemd #process-priority #performance-tuning #resource-management

Need help?

Don't want to manage this yourself?

We handle infrastructure for businesses that depend on uptime. From initial setup to ongoing operations.

Talk to an engineer