Process priority in Linux is the value the kernel scheduler uses to decide which runnable task receives the CPU next and how large a share of CPU time it gets when several tasks compete. Among Linux processes, priority is not a single number but a combination of the scheduling policy, the nice value for ordinary tasks and the real-time priority for time-critical tasks.
Priority only matters under contention. On an idle core, a task with the lowest possible priority runs at full speed; the setting decides who yields when demand exceeds the available CPU capacity. Closely related controls such as nice, CPU affinity and cgroups shape the same decision from different angles.
How the Linux scheduler uses process priority
The kernel keeps one unified priority scale from 0 to 139, where a lower internal number means a more important task. Values 0 to 99 belong to real-time tasks, and values 100 to 139 belong to normal tasks, which map directly to nice values from -20 to 19 (internal priority = 120 + nice).
The two halves of the scale behave very differently. A runnable real-time task always preempts every normal task on the same CPU, regardless of nice values. Among normal tasks there is no strict ordering: the fair scheduler (CFS, replaced by EEVDF in kernel 6.6) gives every task a weight derived from its nice value and divides CPU time in proportion to those weights.
The following table shows how one task’s priority appears in the kernel, in the tools administrators use and in the scheduling class it implies.
| Task type | User-facing value | Kernel internal priority | Value in top (PR) |
|---|---|---|---|
| Real-time, highest | rtprio 99 | 0 | rt |
| Real-time, lowest | rtprio 1 | 98 | -2 |
| Normal, highest | nice -20 | 100 | 0 |
| Normal, default | nice 0 | 120 | 20 |
| Normal, lowest | nice 19 | 139 | 39 |
The opposite directions confuse many administrators: for real-time priority a higher number wins, while for nice a lower number wins. The internal scale reconciles both by inverting the real-time value (internal = 99 – rtprio).
Scheduling policies and their priority models
The scheduling policy determines which kind of priority a task has and how the scheduler interprets it. Every Linux thread has exactly one policy, and policies are set per thread, not per process.
| Policy | Priority parameter | Behavior | Typical use |
|---|---|---|---|
| SCHED_DEADLINE | Runtime, deadline, period | Earliest deadline first, above all real-time tasks | Periodic control loops |
| SCHED_FIFO | rtprio 1-99 | Runs until it blocks or yields | Audio, industrial I/O |
| SCHED_RR | rtprio 1-99 | Like FIFO, with time slices among equal priorities | Several equal real-time workers |
| SCHED_OTHER | Nice -20 to 19 | Weighted fair sharing | Almost all processes |
| SCHED_BATCH | Nice -20 to 19 | Fair sharing, treated as CPU-bound | Compilation, batch jobs |
| SCHED_IDLE | None (very low weight) | Runs only on otherwise idle CPU | Background indexing |
Real-time policies carry real risk. A SCHED_FIFO loop that never blocks can starve every normal task on its CPU, so the kernel reserves time through real-time throttling: by default sched_rt_runtime_us is 950000 of a 1000000 microsecond period, leaving 5% of each second for normal tasks.
How nice values translate into CPU share
Each nice step changes a task’s weight by a factor of about 1.25, which the kernel designers chose so that one step shifts roughly 10% of CPU time between two competing tasks. The weight of nice 0 is 1024, and the full table runs from 88761 at nice -20 down to 15 at nice 19.
The table below shows the resulting CPU split when exactly two CPU-bound tasks share one core, one of them at the default nice 0. The share is computed as the task’s weight divided by the sum of both weights.
| Nice of second task | Weight of second task | Share of nice 0 task | Share of second task |
|---|---|---|---|
| -5 | 3121 | 24.7% | 75.3% |
| 0 | 1024 | 50.0% | 50.0% |
| 1 | 820 | 55.5% | 44.5% |
| 5 | 335 | 75.3% | 24.7% |
| 10 | 110 | 90.3% | 9.7% |
| 19 | 15 | 98.6% | 1.4% |
The key point is that nice is relative, not absolute. A nice 19 task alone on a core still receives 100% of it, and two nice 10 tasks split a core evenly, exactly like two nice 0 tasks. Only the ratio between competing weights matters.
Setting and inspecting process priority
Administrators change priority with a small set of standard tools, and unprivileged users can only lower priority. Raising it, meaning a lower nice value or any real-time policy, requires CAP_SYS_NICE or an appropriate RLIMIT_NICE or RLIMIT_RTPRIO resource limit.
| Tool or setting | What it controls | Example |
|---|---|---|
| nice | Nice value at start | nice -n 10 make -j8 |
| renice | Nice value of a running process | renice -n 5 -p 4321 |
| chrt | Policy and real-time priority | chrt -f -p 50 4321 |
| ionice | Disk I/O class and level | ionice -c 3 -p 4321 |
| systemd unit | Persistent service priority | Nice=, CPUSchedulingPolicy= |
| ps and top | Inspection | ps -eo pid,cls,ni,rtprio,comm |
I/O priority is a separate dimension. The ionice best-effort class has levels 0 to 7, and when none is set the kernel derives it from the nice value as (nice + 20) / 5, so nice 0 maps to level 4. Whether the setting has any effect depends on the block I/O scheduler: BFQ honors it fully, while none ignores it.
Limitations and common mistakes
Most priority problems come from expecting priority to fix a bottleneck that is not CPU time. Nice does not limit memory, disk or network usage, and it cannot make a task faster than an idle CPU already allows.
- Autogroup scheduling on many desktop kernels groups tasks by session, so renicing a process only affects it relative to its own session, not to other terminals.
- Cgroup CPU weights (
cpu.weight, default 100) apply between groups first; a nice -20 task inside a low-weight container can still lose to a nice 0 task elsewhere. - Priority inversion occurs when a high-priority task waits on a lock held by a low-priority one; Linux mitigates it with priority inheritance on PI-aware mutexes.
- Assigning rtprio 99 to application threads is a common error, because it competes with kernel threads such as migration and watchdog tasks.
- Because nice is a per-thread attribute in Linux, renicing a PID can change only the main thread while existing worker threads keep their old value.
Put simply
A computer usually has more programs wanting the processor than it has processor cores. Process priority is the rule that decides who goes first and who gets a bigger slice of time when everyone is waiting.
Think of a busy kitchen with one stove. Ordinary dishes take turns, and a dish marked as more important simply gets longer turns. A few emergency orders skip the line entirely. In Linux, the nice value sets the turn length for ordinary programs, and real-time priority marks the emergency orders. When the stove is free, every dish cooks at full speed regardless of its label.
In practice
A build server with 16 cores runs a web dashboard for developers and nightly compilation jobs that use every core for about two hours. During the build, the dashboard becomes slow because its few request threads compete equally with dozens of compiler processes.
The administrator starts the build through a systemd unit with Nice=15 and IOSchedulingClass=idle. At nice 15 each compiler process has a weight of 36 against 1024 for the dashboard threads, so on a contested core a dashboard thread receives about 97% of the time it asks for. The dashboard’s response time returns to normal, while the build still finishes in almost the same time, because the dashboard uses only a small fraction of total CPU capacity.