Process Priority (nice, renice)

Every process on a Linux system is competing for a limited resource: CPU time. Many times per second the kernel’s scheduler has to decide which of the runnable processes gets the CPU next, and for how long. Process priority — expressed as a “niceness” value — is how you influence that decision without writing a single line of scheduler code. The nice command sets that value when you start a new process, and renice changes it on a process that is already running.

Overview: How Process Priority Works in Linux

Modern Linux uses the Completely Fair Scheduler (CFS) for ordinary processes. Instead of giving every process a literal fixed-length timeslice, CFS tracks how much “virtual runtime” each runnable process has accumulated and always picks the process that has run the least (in virtual-time terms) to run next. That keeps CPU time shared roughly evenly among competing processes — hence “completely fair.”

Niceness is how you tilt that fairness. Every process has a nice value ranging from -20 (highest priority, least “nice” to everyone else) to 19 (lowest priority, most “nice” to everyone else). New processes start at 0 by default. The scale is intentionally counterintuitive: a lower number means higher priority. Internally, the kernel converts the nice value into a scheduling weight — each step away from 0 roughly multiplies or divides the process’s share of CPU time by about 1.25, so the gap between -20 and 19 is enormous, not linear.

Niceness is a hint about CPU scheduling, not a hard guarantee and not an exclusion mechanism. A process with nice 19 still runs — it just gets a much smaller slice of CPU time whenever there is contention. If the CPU is idle, a nice 19 process runs exactly as fast as a nice -20 one, because there is nothing to be fair about. Niceness also only affects CPU scheduling, not disk I/O priority (that is a separate mechanism controlled by ionice) or memory.

Permissions matter here. Any user can raise their own process’s nice value (make it “nicer,” i.e. lower priority) — you’re allowed to be generous with your own CPU time. But lowering a nice value (asking for higher priority) requires the CAP_SYS_NICE capability, which in practice means you need sudo/root. This prevents a regular user from starving everyone else’s processes by granting themselves top priority. A process’s nice value is inherited by any children it forks, so if you nice a shell, everything launched from that shell inherits the same starting niceness.

Syntax

nice launches a brand-new command with an adjusted niceness:

nice [-n adjustment] command [arguments]

renice changes the niceness of one or more processes that are already running:

renice -n priority -p pid [pid ...]
renice -n priority -u user [user ...]
renice -n priority -g pgrp [pgrp ...]
Option Applies to Meaning
-n adjustment (nice) nice Adjustment added to the shell’s current nice value (usually 0); default adjustment is 10 if omitted
-n priority (renice) renice The new, absolute nice value to set — not an offset
-p pid renice Target one or more process IDs
-u user renice Target all processes owned by a user
-g pgrp renice Target a process group

You can see a process’s current niceness in the NI column of ps -o pid,ni,cmd or top, and its raw scheduling priority (which factors in nice) in the PR column of top.

Examples

Example 1: Start a background job at a lower priority

Suppose you’re kicking off a log-compression script that will run for a while and you don’t want it competing with your interactive shell for CPU:

nice -n 10 ./compress-logs.sh &

Output:

[1] 4821

nice -n 10 starts compress-logs.sh with a nice value of 10 instead of the default 0, and the trailing & runs it in the background so your shell prompt returns immediately, printing the job number and PID.

Example 2: Confirm the niceness with ps

ps -o pid,ni,comm -C compress-logs.sh

Output:

 PID  NI COMMAND
4821  10 compress-logs.sh

The NI column confirms the process is running at nice 10, so under CPU contention it will yield to processes with lower (more favorable) nice values.

Example 3: Raise the priority of a slow, already-running process

Say a database backup (PID 4821) is taking too long and you decide it should get more CPU time than it currently has:

sudo renice -n -5 -p 4821

Output:

4821 (process ID) old priority 10, new priority -5

sudo is required here because -5 is a lower (higher-priority) value than the process currently has, and only root can grant a process more CPU priority than it started with.

Example 4: Lower the priority of everything a user runs

renice -n 5 -u deploy

Output:

1001 (user deploy) old priority 0, new priority 5

This adjusts the niceness for every process owned by the deploy user in one call — useful when a service account is running batch work that shouldn’t crowd out interactive users on a shared box.

How It Works Step by Step

  1. When you run nice -n 10 ./compress-logs.sh, the shell forks a child process; before that child execs the script, its nice value is set to the parent’s current nice (normally 0) plus the adjustment (10), giving a starting nice of 10.
  2. The kernel converts that nice value into an internal scheduling weight used by CFS’s fairness math — larger nice values get proportionally smaller weights.
  3. Whenever the CPU becomes free, CFS looks at all runnable processes and picks the one with the least accumulated virtual runtime; a process’s weight controls how fast its virtual runtime grows, so lower-weight (higher nice) processes appear to “use up” runtime slower and get skipped more often under contention.
  4. When you later run renice -n -5 -p 4821, the kernel looks up the process by PID and updates its nice value and weight in place — no restart needed, and any threads/children already running keep their own independently-adjusted values from that point forward.
  5. Every subsequent scheduling decision for that PID now uses the new weight, so the effect is immediate.

Common Mistakes

Mistake 1: Trying to raise priority without sudo

renice -n -10 -p 4821
renice: failed to set priority for 4821 (process ID): Permission denied

Lowering the nice value (asking for more CPU priority) needs elevated privileges. Fix it by running the command with sudo:

sudo renice -n -10 -p 4821

Mistake 2: Targeting a command name instead of a PID

renice -n 10 compress-logs.sh
renice: compress-logs.sh: bad value

renice operates on process IDs, users, or process groups — never a bare command name. Find the PID first (with ps or pgrep) and pass it explicitly:

renice -n 10 -p "$(pgrep -f compress-logs.sh)"

Mistake 3: Forgetting that nice’s adjustment is additive

nice -n 10 command only produces a final nice value of 10 if it’s run from a shell whose own nice value is 0. If you’re already inside a niced shell (nice 5, say) and run nice -n 10 command again, the child ends up at nice 15, not 10 — the adjustment stacks on top of the current value. Check your current niceness with ps -o pid,ni -p $$ before assuming what a nested nice call will produce.

Mistake 4: Assuming a nice 19 process never runs

A heavily-niced process is still fully scheduled — it just loses out whenever other processes want the CPU too. On an otherwise-idle system, a nice 19 process runs at full speed. Don’t mistake niceness for a pause or a queue.

Best Practices

  • Use nice for CPU-heavy, non-interactive batch jobs (backups, compression, builds) so they don’t starve your interactive shell or other services.
  • Prefer moderate adjustments (510) over extreme ones (19 or -20) unless you have a specific reason — extreme values make a process’s behavior harder to reason about under load.
  • Reserve negative nice values (higher priority) for genuinely latency-sensitive work, and always require sudo for them explicitly — don’t run whole shells as root just to get one nice adjustment.
  • Pair nice with ionice when a job is disk-I/O heavy as well as CPU heavy — CPU niceness alone won’t stop it from saturating disk bandwidth.
  • Check current niceness with ps -o pid,ni,cmd or top (press r in top to renice interactively) before changing it, so you know the baseline.
  • Document why a service’s priority was changed (in a comment, systemd unit, or runbook) — an unexplained renice is a trap for the next person debugging slow performance.

Practice Exercises

  • Start a long-running command such as find / -type f in the background with a nice value of 15, then use ps -o pid,ni,cmd -C find to confirm the value took effect.
  • Pick an existing process you own (use pgrep or ps aux to find its PID) and raise its nice value by 5 using renice, without sudo. Confirm it works, then try lowering it back below its original value and observe the permission error.
  • Using a spare terminal, launch two CPU-bound loops (e.g. yes > /dev/null) — one at the default niceness and one started with nice -n 19. Watch top and compare their %CPU columns under contention.

Summary

  • Niceness ranges from -20 (highest priority) to 19 (lowest priority); new processes default to 0.
  • nice -n adjustment command starts a new process with an adjusted nice value; the adjustment is added to the current shell’s nice value, not set as an absolute.
  • renice -n priority -p pid changes the nice value of an already-running process, and -u/-g can target a user’s or group’s processes instead of a single PID.
  • Raising priority (lower nice value) requires sudo/root; any user can lower their own process’s priority.
  • Niceness only affects CPU scheduling weight under contention — it never stops a process from running on an otherwise-idle system, and it has no effect on disk I/O priority.