Adjust Process
Scheduling

Adjust process scheduling

CIS126RH | RHEL System Administration 1
Mesa Community College

When multiple processes compete for the CPU, the Linux kernel decides how much time each receives based on its scheduling policy and priority. Administrators can influence these decisions — running background tasks at lower priority so they do not disrupt production workloads, or boosting a critical process to ensure it gets the CPU time it needs. This module covers the Linux CPU scheduling model, the nice and renice commands, and the real-time scheduling policies available on RHEL. These concepts are tested on the RHCSA exam.

Learning Objectives

  1. Explain the Linux CPU scheduling model — Describe how the kernel scheduler allocates CPU time using scheduling policies and priority values
  2. Use nice to set priority at launch — Start a process with a specified nice value using the nice command
  3. Use renice to adjust priority of running processes — Change the nice value of an already-running process using renice by PID, user, or process group
  4. Interpret scheduling information in ps and top — Read and understand the PR, NI, and scheduling class columns in process monitoring output

How the Linux Scheduler Works

The Linux kernel scheduler decides which runnable process gets the CPU next. On RHEL 9, the default scheduler is the Completely Fair Scheduler (CFS).

  • CFS aims to give every process a fair share of CPU time proportional to its weight
  • A process's weight is determined by its nice value
  • Processes with the same nice value share CPU equally
  • A lower nice value gives a process more weight — it receives more CPU time
  • A higher nice value gives a process less weight — it yields to others
  • The scheduler runs in O(log N) time — it scales efficiently with many processes
Scheduling vs. priority classes

RHEL supports multiple scheduling classes: normal (CFS, affected by nice), real-time FIFO, and real-time round-robin. The vast majority of processes use the normal class. Real-time classes bypass CFS entirely and are used for latency-sensitive kernel and hardware management tasks.

The Nice Value Scale

The nice value (NI) is an integer from -20 to 19 that biases the CPU scheduler toward or away from a process.

Nice value Scheduling weight Relative CPU time Typical use
-20HighestMost — ~4× more than nice 0Critical real-time kernel threads
-10HighMore than defaultImportant interactive processes
0DefaultEqual shareAll new processes start here
10LowLess than defaultBackground compilation, updates
19LowestLeast — runs only when nothing else wants CPUBatch jobs, backups, idle-time tasks
Remember: lower nice = higher priority

"Nice" means the process is being nice to others by yielding CPU time. A nice 19 process is very polite — it yields to everyone. A nice -20 process is demanding — it takes as much CPU as it can get. The number and the priority are inversely related.

nice: Starting a Process with a Priority

The nice command launches a new process with a specified nice value. Without arguments it reports the current nice value of the shell.

# View the current shell's nice value (usually 0)
$ nice
0

# Start a command with nice value 10 (lower priority)
$ nice -n 10 tar -czvf /tmp/backup.tar.gz /home

# Start with the highest reduction — nice 19
$ nice -n 19 ./long-batch-job.sh

# Only root can set negative values (raise priority)
$ sudo nice -n -10 ./critical-monitor.sh

# Run a background job with low priority
$ nice -n 15 find / -name "*.log" -mtime +30 &

# Shorthand — older syntax still widely used
$ nice -15 command   # equivalent to nice -n 15
Nice value is inherited by child processes

When a process is started with nice -n 10, all child processes it spawns also run at nice 10 unless they explicitly change their own nice value.

renice: Adjusting a Running Process

renice changes the nice value of a process that is already running. It can target a single process, all processes of a user, or a process group.

# Raise the nice value (lower priority) of a specific PID
$ renice -n 10 -p 4251
4251 (process ID) old priority 0, new priority 10

# Lower the nice value (raise priority) — requires root
$ sudo renice -n -5 -p 4251

# Renice all processes owned by a user
$ sudo renice -n 15 -u maria

# Renice a process group (all processes with same PGID)
$ sudo renice -n 10 -g 4251

# Verify the change with ps
$ ps -o pid,ni,comm -p 4251
  PID  NI COMMAND
 4251  10 python3
Regular users can only increase nice

A regular user can only change a process's nice value to a higher number (lower priority). Decreasing nice (raising priority) always requires root. This prevents users from giving their processes unfair CPU advantage over others.

Reading Priority in top and ps

Process monitoring tools display two priority-related columns: PR (kernel priority) and NI (nice value). They are related but different.

# top output — PR and NI columns
  PID USER  PR  NI   VIRT   RES   SHR S %CPU %MEM  TIME+  COMMAND
 4251 maria 30  10  58912 98304 12288 S  0.3  1.2  0:01.23 python3
  872 root  20   0  92548 16384  4096 S  0.1  0.2  0:00.34 sshd
 9999 root  rt   0      0     0     0 S  0.0  0.0  0:00.01 migration/0

# ps showing NI column (-o flag for custom format)
$ ps -eo pid,ni,pri,comm | head -5
  PID  NI PRI COMMAND
    1   0  19 systemd
  872   0  19 sshd
 4251  10   9 python3
Column Source Range Formula
NIUser-set nice value-20 to 19Set by nice/renice
PR (top)Kernel internal priority0 to 39 for normal; rt for real-timePR = 20 + NI
PRI (ps)Kernel internal priority39 to 0 (reversed)PRI = 19 - NI

Interactive Priority Adjustment in top

top allows interactive renice without leaving the monitoring session.

  • Press r inside top to renice a process interactively
  • top prompts: PID to renice [default pid = N]: — enter the PID
  • top prompts: Renice PID N to value: — enter the new nice value
  • The process list immediately updates to show the new NI value
# Inside top — press r, then enter PID and new nice value
PID to renice [default pid = 4251]: 4251
Renice PID 4251 to value: 10
Reniced PID 4251 from priority 0 to 10
top keyboard shortcuts for scheduling

r — renice (change NI value of a process)
k — kill a process (send a signal)
F — select which columns to display (add NI, PR, etc.)
fs on NI column — sort by nice value

Scheduling Policies Overview

RHEL supports multiple CPU scheduling policies. Nice and renice affect only the SCHED_OTHER (normal) policy. Real-time policies bypass CFS entirely.

Policy Class Priority range Description
SCHED_OTHER Normal Nice -20 to 19 CFS — the default for all user processes; fair share based on nice value
SCHED_BATCH Normal Nice -20 to 19 Optimised for throughput; assumes non-interactive batch workloads
SCHED_IDLE Normal Below nice 19 Extremely low priority — runs only when the CPU is completely idle
SCHED_FIFO Real-time 1 (lowest) to 99 (highest) First-in-first-out; runs until it yields or is preempted by a higher-priority RT process
SCHED_RR Real-time 1 to 99 Round-robin; shares CPU among equal-priority RT processes in time slices

chrt: Viewing and Setting Scheduling Policy

chrt displays and changes the scheduling policy and real-time priority of a running process or of a command to be launched.

# View the scheduling policy of a running process
$ chrt -p 4251
pid 4251's current scheduling policy: SCHED_OTHER
pid 4251's current scheduling priority: 0

# View scheduling policy of PID 1 (systemd)
$ chrt -p 1
pid 1's current scheduling policy: SCHED_OTHER
pid 1's current scheduling priority: 0

# List all available scheduling policies
$ chrt --max
SCHED_OTHER min/max priority: 0/0
SCHED_FIFO  min/max priority: 1/99
SCHED_RR    min/max priority: 1/99
SCHED_BATCH min/max priority: 0/0
SCHED_IDLE  min/max priority: 0/0

# Start a command with SCHED_BATCH policy (requires root)
$ sudo chrt --batch 0 ./batch-job.sh

Practical Scheduling Scenarios

Run a nightly backup without impacting production

# In a cron job — start at lowest CPU priority
nice -n 19 tar -czvf /backup/$(date +%F).tar.gz /var/www/html

Temporarily throttle a runaway user process

# Lower the priority of maria's CPU-heavy job without killing it
$ sudo renice -n 15 -p 4251
4251 (process ID) old priority 0, new priority 15

Lower priority for all of a user's processes

$ sudo renice -n 10 -u student

Compile a large application without degrading the server

# Lower both CPU and I/O priority
$ nice -n 15 make -j4 &
# Or combine with ionice for disk I/O as well
$ ionice -c 3 nice -n 15 make -j4 &

Scheduling in cron and systemd

Scheduled jobs often need automatic priority management so they don't interfere with the system when they run unattended.

nice in a cron job

# /etc/crontab or user crontab entry
0 2 * * *  root  nice -n 15 /usr/local/bin/nightly-report.sh

CPUWeight in a systemd service unit

# /etc/systemd/system/my-batch.service
[Service]
# CPUWeight controls relative CPU scheduling weight
# Default is 100; lower values reduce priority
CPUWeight=50
Nice=10
ExecStart=/usr/local/bin/batch-job.sh
systemd CPUWeight vs Nice

systemd services can set both Nice= (maps to the nice value) and CPUWeight= (a cgroup weight from 1–10000, default 100) in their unit files. These provide two independent levers for controlling a service's CPU share.

Verifying Scheduling Changes

After adjusting priority, confirm the change took effect using multiple tools.

# Verify with ps — custom output format showing NI
$ ps -o pid,ni,pri,%cpu,comm -p 4251
  PID  NI PRI %CPU COMMAND
 4251  10   9  2.3 python3

# Verify with top — NI column in the process list
$ top -p 4251   # monitor only PID 4251

# Verify with chrt — confirms the scheduling policy
$ chrt -p 4251
pid 4251's current scheduling policy: SCHED_OTHER
pid 4251's current scheduling priority: 0

# Check all processes with non-zero nice values
$ ps -eo pid,ni,comm | awk '$2 != 0 {print}'

# In top — sort by NI to see all priority-adjusted processes
# Press Shift+F, highlight NI, press s to sort, then q

Limits on Nice Adjustments

The kernel enforces rules about who can adjust nice values and in which direction.

User Can increase NI (lower priority)? Can decrease NI (raise priority)? Can renice other users' processes?
Regular user Yes — up to nice 19 No — cannot go below current nice value No
root Yes Yes — down to nice -20 Yes
# Regular user attempting to raise priority — fails
$ renice -n -5 -p 4251
renice: failed to set priority for 4251 (process ID): Permission denied

# Regular user can lower their own priority — succeeds
$ renice -n 10 -p $$   # $$ = PID of current shell
27842 (process ID) old priority 0, new priority 10

# Root can set any value
$ sudo renice -n -10 -p 4251
One-way ratchet for regular users

A regular user who lowers their process priority cannot raise it back — even to the original value. Only root can restore a lowered priority.

Scheduling Adjustment Quick Reference

Task Command
Check current shell's nice valuenice
Start a command at reduced prioritynice -n 10 command
Start a command at minimum prioritynice -n 19 command
Start a background batch job at low prioritynice -n 19 command &
Start a command at elevated priority (root)sudo nice -n -10 command
Renice a running process by PIDrenice -n 15 -p PID
Renice all processes for a usersudo renice -n 10 -u username
Renice interactively in topPress r in top, enter PID and new value
View scheduling policy of a processchrt -p PID
Verify NI column for a processps -o pid,ni,comm -p PID
List all non-zero NI processesps -eo pid,ni,comm | awk '$2 != 0'
Set nice in a systemd unitNice=10 in [Service] section

Common Mistakes

Mistake What goes wrong Correct approach
Confusing NI direction — setting nice 15 to raise priority Process gets lower CPU priority — the opposite of the intention Remember: lower nice = higher priority. Use sudo nice -n -5 to raise
Regular user attempting to decrease NI value Permission denied — kernel rejects the request Use sudo renice to decrease NI; regular users can only increase
Using renice without -p, -u, or -g Some versions interpret the argument as a process group or produce an error Always specify the target type: renice -n 10 -p 4251
Expecting nice to affect I/O scheduling Nice controls CPU priority only — disk I/O is not affected Use ionice alongside nice for jobs that are both CPU and I/O intensive
Applying nice after process is already running Nice only works at launch — does nothing if the process is already started Use renice for processes that are already running
Setting negative nice without sudo Permission denied even for the user's own processes Negative nice (higher priority) always requires sudo nice -n -N

Knowledge Check

Answer these before moving to the next slide.

  1. What is the nice value range in Linux, and which end gives the highest CPU priority?
  2. Write the command to start a database backup script /usr/local/bin/db-backup.sh with the lowest possible CPU priority.
  3. A process with PID 8823 is consuming too much CPU. You cannot stop it but want to reduce its CPU impact. Write the command to lower its priority to nice 12.
  4. A regular user runs renice -n 5 -p 1234 to lower their process's priority. Then they try renice -n 0 -p 1234 to restore the default. What happens and why?
  5. In top output, a process shows PR=30 and NI=10. What does the PR value mean, and is this consistent with the NI value?
  6. What is the difference between nice and renice? When must you use each one?

Knowledge Check — Answers

  1. The nice value ranges from -20 to 19. -20 gives the highest CPU priority — lower numbers mean higher priority.
  2. nice -n 19 /usr/local/bin/db-backup.sh — nice 19 is the lowest possible priority; the process runs only when nothing else needs the CPU.
  3. sudo renice -n 12 -p 8823renice changes the nice value of a running process. sudo is needed if PID 8823 is owned by another user.
  4. The second command fails with "Permission denied". A regular user can only increase the nice value (lower priority). Once set to 5, the user cannot restore it to 0 because that would be decreasing the nice value (raising priority). Only root can decrease a process's nice value.
  5. In top, PR = 20 + NI. With NI = 10: PR = 20 + 10 = 30. This is consistent — the PR value of 30 correctly reflects a nice-10 process using the top PR formula.
  6. nice sets the priority at launch — it wraps a command and starts it with the specified nice value. renice changes the nice value of a process that is already running — it targets a PID, user, or process group. Use nice when starting a new command; use renice for processes already running.

Key Takeaways

  1. Lower nice = higher priority; higher nice = lower priority. The range is -20 (most favoured) to 19 (least favoured). New processes start at 0. "Nice" means yielding to others — a nice 19 process is very polite about CPU use.
  2. Use nice -n VALUE command to set priority at launch. Nice only affects processes being started — it has no effect on already-running processes. For background batch jobs, nice -n 19 command & is the standard pattern.
  3. Use renice -n VALUE -p PID to adjust a running process. Renice can also target by user (-u) or process group (-g). Regular users can only increase nice (lower priority). Only root can decrease nice or renice other users' processes.
  4. Verify with ps -o pid,ni,comm -p PID or in top. The NI column shows the current nice value. In top, PR = 20 + NI for normal processes. Use chrt -p PID to confirm the scheduling policy class.

Graded Lab

  • Run nice with no arguments to display the current shell's nice value. Then run nice -n 5 bash to open a subshell at nice 5. Inside the subshell, run nice again to confirm the new value is inherited.
  • Start a background process at nice 15: nice -n 15 sleep 300 &. Use ps -o pid,ni,comm -p $(pgrep sleep) to confirm the NI column shows 15.
  • Use renice -n 10 -p PID (using the PID from the previous step) to change the sleep process's nice value to 10. Verify the change.
  • As a regular user, attempt renice -n 0 -p PID to restore it to default. Observe the permission error. Then use sudo renice -n 0 -p PID to confirm root can restore it.
  • Open top, identify a process to renice, and press r. Enter the PID and set its nice value to 5. Confirm the NI column updates. Press r again and restore it to 0.
  • Run chrt -p 1 to view systemd's scheduling policy. Run chrt --max to list available policies on this system.
RHCSA Objective

"Adjust process scheduling." Know nice -n VALUE command for new processes and renice -n VALUE -p PID for running processes. Remember: lower nice = higher priority.