nice Command in Linux: Complete Guide to Process Priority Adjustment and Parameters

nice command in Linux and it perimeters

Every process on a Linux system is competing for the same limited CPU time, and the kernel’s scheduler has to decide who goes first. Most of the time you don’t need to think about this — the default scheduling does a perfectly good job. But every so often I need to run something CPU-heavy (a backup, a big compile, a batch data job) without it stealing responsiveness from everything else on the box, and that’s exactly what nice is for. Here’s everything I know about controlling process priority on Linux.

What is the nice Command?

nice launches a new process with a modified scheduling priority — informally called its “niceness.” The name comes from the idea that a process with a higher niceness value is being “nicer” to other processes, voluntarily yielding more CPU time to them. A lower niceness value means the process is less willing to share, and gets scheduled more aggressively.

Niceness values range from -20 (highest priority, least “nice”) to 19 (lowest priority, most “nice”). The default niceness for any newly launched process is 0.

Basic Syntax

nice [OPTION] [COMMAND [ARGUMENT...]]

Run with no arguments, nice just prints the current niceness (usually 0):

nice

Output:

0

Common Parameters

OptionDescription
-n <adjustment>Set the niceness adjustment relative to the current value (default adjustment is 10 if -n is omitted but a command is given)
--adjustment=<n>Long-form equivalent of -n
--helpShow usage information
--versionShow version information

Practical Examples

Run a command with default niceness increase

nice mycommand

If you run nice with a command but no explicit -n, it applies a default adjustment of +10, making the process notably less CPU-aggressive than a normal process.

Run a command with a specific niceness

nice -n 15 tar -czf backup.tar.gz /data

I use this constantly for backup jobs — compression and archiving are CPU-heavy but not time-critical, so I want them to yield to anything more important running at the same time.

Run a command with maximum niceness (lowest priority)

nice -n 19 ./long-running-batch-job.sh

Attempt to increase priority (requires root)

sudo nice -n -10 ./latency-sensitive-process

Only root (or a user granted the CAP_SYS_NICE capability, or permitted via /etc/security/limits.conf) can set a negative niceness — i.e., raise a process’s priority above the default. Regular users can only make a process nicer (increase its value), never the reverse, which makes sense from a security standpoint: you don’t want any user able to starve other users’ processes of CPU time.

Check the exact confirmed niceness of a process

ps -o pid,ni,cmd -p <pid>

Or from within top, the NI column shows exactly this value for every running process.

Changing the Priority of an Already-Running Process: renice

nice only sets priority at launch time. To change the priority of a process that’s already running, use renice:

renice -n 10 -p 4521

This is a close cousin worth knowing well:

renice [-n] priority [-p pid] [-u user] [-g pgrp]

Example — deprioritize every process owned by a specific user:

sudo renice -n 15 -u backupuser

Understanding Niceness vs. Priority (PR) in top/ps

This distinction confuses people constantly, so let me clarify it directly. In top‘s output:

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
  • NI is the niceness value you (or the process itself) set — the user-facing “-20 to 19” scale.
  • PR is the actual kernel scheduling priority the kernel computes, which for normal processes is 20 + NI. So a niceness of 0 corresponds to a PR of 20; a niceness of -10 corresponds to PR of 10; a niceness of 10 corresponds to PR of 30. Lower PR numbers mean higher actual scheduling priority.

Some processes show PR as rt — meaning they’re running under a real-time scheduling policy entirely separate from the standard niceness scale, and niceness doesn’t apply to them at all.

How nice Works Internally

nice is a thin wrapper around the setpriority() system call (or, historically, the older nice() syscall), which adjusts a value the Linux kernel’s Completely Fair Scheduler (CFS) — the default scheduler on modern Linux — uses when calculating how much CPU time each process should receive relative to others.

Internally, CFS doesn’t literally give a process at niceness -20 twenty times more CPU than one at niceness 0; niceness values are converted into scheduling weights, and CFS uses those weights to proportionally divide available CPU time among all runnable processes. A process with a lower niceness gets a larger weight and, correspondingly, a larger share of CPU time whenever there’s contention — but it’s not a hard, absolute priority order like some older scheduling models. If the CPU isn’t contended at all, niceness has essentially no observable effect, since every process gets as much CPU as it needs regardless.

This is an important, often-missed point: nice only matters when there’s CPU contention. On an idle or lightly loaded system, a process at niceness 19 runs exactly as fast as one at niceness -20, because there’s no competition for CPU time to arbitrate.

Real-World Use Cases

Background compression/archival jobs:

nice -n 19 tar -czf /backups/full-backup-$(date +%F).tar.gz /var/www

Compiling large codebases without freezing your desktop:

nice -n 10 make -j$(nproc)

Batch data processing scripts that shouldn’t compete with a live application:

nice -n 15 python3 nightly_report_generator.py

Combining nice with ionice for I/O-heavy background tasks: CPU niceness alone doesn’t help if the real bottleneck is disk I/O. ionice is the analogous tool for I/O scheduling priority:

nice -n 15 ionice -c2 -n7 rsync -av /data /backup/

This tells the process to yield both CPU time and disk I/O bandwidth to everything else on the system — exactly what I want for a background sync job running alongside a production database.

Real-World Shell Scripting Example

#!/bin/bash
# nightly-batch.sh — run heavy batch jobs at low priority during off-hours

LOGFILE="/var/log/nightly-batch.log"

echo "Starting nightly batch at $(date)" >> "$LOGFILE"

nice -n 19 ionice -c2 -n7 /opt/scripts/generate-reports.sh >> "$LOGFILE" 2>&1
nice -n 19 ionice -c2 -n7 /opt/scripts/cleanup-old-logs.sh >> "$LOGFILE" 2>&1

echo "Nightly batch completed at $(date)" >> "$LOGFILE"

Troubleshooting Common Issues

“nice: cannot set niceness: Permission denied” — You’re trying to set a negative value (increase priority) without root privileges. Either run with sudo or accept a positive (lower-priority) value instead.

A niced process still seems to be slowing everything down — Remember that niceness only affects CPU scheduling, not I/O or memory pressure. A memory-heavy process at niceness 19 can still cause swapping and slow down the whole system; that’s a memory problem, not a CPU scheduling problem — nice won’t help. Check ionice for I/O contention instead.

Niced process doesn’t seem to run any slower on an idle system — This is expected behavior, not a bug. Niceness only has a visible effect under CPU contention.

Child processes not inheriting the nice value as expected — Child processes generally do inherit their parent’s niceness by default via fork(), but any wrapper script or process manager that explicitly resets priority (some systemd unit files set an explicit Nice= value, for instance) can override this.

Performance Optimization Best Practices

  • Use nice for CPU-bound background jobs (compression, batch processing, video encoding) that don’t need to complete quickly and shouldn’t compete with foreground/interactive work.
  • Pair with ionice whenever the job is also I/O-heavy — CPU niceness alone won’t help disk-bound tasks.
  • On multi-core systems, remember niceness affects how contested CPU cores are shared — a niced process on an otherwise-idle core sees no penalty at all.
  • Avoid setting negative niceness casually; boosting a process’s priority can genuinely starve other important system processes if overused.

Security Implications

Since only root (or users with the CAP_SYS_NICE capability) can lower niceness values (raise priority), this is a deliberate safeguard against unprivileged users starving the system by hogging CPU priority. On multi-tenant systems, I always check /etc/security/limits.conf for nice entries to understand exactly what priority range each user or group is permitted, since misconfigured limits can either be overly restrictive (annoying) or overly permissive (a resource-abuse risk).

nice vs. Related Commands

CommandDifference
reniceChanges the niceness of an already-running process, rather than at launch time
ioniceControls I/O scheduling priority rather than CPU scheduling priority
chrtManages real-time scheduling policies (SCHED_FIFO, SCHED_RR) entirely outside the standard niceness scale
cpulimitCaps a process’s CPU usage to an absolute percentage, rather than a relative scheduling weight like nice
cgroups (via systemd-run --scope or cgcreate)A more powerful, modern mechanism for limiting CPU, memory, and I/O for a group of processes together, often preferred over nice alone in containerized/production environments

Compatibility Across Distributions

nice and renice are part of GNU coreutils/util-linux and are present on every mainstream Linux distribution — Debian, Ubuntu, RHEL, CentOS, Fedora, Arch, openSUSE. The niceness scale (-20 to 19) and its interaction with the CFS scheduler are consistent across any modern Linux kernel. On BusyBox-based minimal systems, a simplified nice is typically provided with the core -n functionality intact.

Nice Values and systemd Services

For long-running services rather than one-off commands, setting niceness through a systemd unit file is generally cleaner and more maintainable than wrapping the ExecStart line in nice:

[Service]
ExecStart=/opt/myapp/bin/worker
Nice=10
IOSchedulingClass=best-effort
IOSchedulingPriority=7

This achieves the same CPU deprioritization as nice -n 10, but ties it directly to the service definition, so it persists correctly across restarts and is visible to anyone inspecting the unit file later — much easier to audit than a nice prefix buried inside a wrapper script that someone might eventually “simplify” away by accident.

systemctl show myservice -p Nice

This confirms the effective niceness systemd is applying to a given service, which I check whenever a background service seems to be competing too aggressively with foreground, latency-sensitive workloads on the same host.

The Interaction Between nice and Multi-Core Scheduling

A subtlety that trips people up: niceness affects how CPU time is shared when there’s contention on the same core(s), but on a multi-core system, the kernel’s scheduler is also making load-balancing decisions about which core each process actually runs on. A heavily niced process might still get its own dedicated core if the system has more cores than actively competing processes, in which case it runs at full speed regardless of its niceness value. This is different from cgroup-based CPU quotas, which impose a hard ceiling on CPU consumption regardless of contention — if you need a guaranteed maximum rather than a relative priority, nice alone isn’t the right tool; look at systemd-run --scope -p CPUQuota=20% or direct cgroup manipulation instead.

Practical Comparison: nice vs. cgroup CPU Limits

# nice: relative priority, only matters under contention
nice -n 19 ./batch-job.sh

# cgroup-based hard limit: guaranteed ceiling regardless of contention
systemd-run --scope -p CPUQuota=25% ./batch-job.sh

I reach for plain nice for quick, one-off background tasks where “please yield to everything else” is good enough. I reach for cgroup-based limits when I need a hard, predictable ceiling — for example, capping a noisy background analytics job at exactly 25% of a shared CPU core so it can never accidentally starve a co-located production service, even during a moment when nothing else happens to be running.

Checking Effective Niceness Across a Whole System

When investigating why a server “feels slow” under load, I often want a quick overview of every process’s niceness at once, sorted so the highest-priority (lowest niceness) processes are easy to spot:

ps -eo pid,ni,pri,cmd --sort=ni | head -20

This immediately shows me if something unexpected has been given elevated priority (a negative niceness), which is worth investigating — legitimate high-priority processes are usually well-known system services, and an unfamiliar process running with negative niceness is worth a closer look.

Summary

nice is a small, elegant tool for a problem that comes up constantly in real system administration: how do I run something CPU-intensive without stepping on everything else running at the same time? Understanding that niceness only matters under contention, that it’s a relative weight rather than an absolute guarantee, and that it needs to be paired with ionice for I/O-bound work, is what turns nice from a command you occasionally type into a real tool for managing shared system resources responsibly.

References

  • Linux man-pages project, nice(1): https://man7.org/linux/man-pages/man1/nice.1.html
  • Linux man-pages project, renice(1): https://man7.org/linux/man-pages/man1/renice.1.html
  • Linux man-pages project, setpriority(2): https://man7.org/linux/man-pages/man2/setpriority.2.html
  • Linux Kernel CFS Scheduler documentation: https://www.kernel.org/doc/html/latest/scheduler/sched-design-CFS.html
  • GNU Coreutils manual: https://www.gnu.org/software/coreutils/manual/html_node/nice-invocation.html
Total
0
Shares

Leave a Reply

Previous Post
ldd command in Linux and it perimeters

ldd Command in Linux: Complete Guide to Shared Library Dependencies and Parameters

Next Post
ps command in Linux and it perimeters

ps Command in Linux: Complete Guide to Process Status Reporting and Parameters

Related Posts