The Big Picture: Who Goes First?

At an airport, a passenger with a flight in 20 minutes may skip the queue. Everyone else waits in order. Priority works the same way for threads: a more important thread gets a core before a less important one.

Windows gives every thread a priority number from 0 to 31. A bigger number means more important.

 31 ┐
 .. │  REAL-TIME range  (16–31)   ← very rare; can starve the whole PC
 16 ┘
 15 ┐
 .. │  DYNAMIC range    (1–15)    ← all normal programs live here
  1 ┘
  0    Zero-page thread (one special system thread; nothing else)

The scheduler's rule: the highest-priority ready thread runs. A priority-8 thread never runs while a priority-9 thread is ready and a core is needed.

5.1 Priority Levels (Windows Priority Classes)

A program does not usually pick a raw number. It picks two things:

  1. A priority class for the whole process (a "base level").
  2. A relative thread priority for each thread (a small step up or down from the base).

Process priority classes:

Priority classBase priority numberWhere you see it
Idle (Low)4Background tools that should never slow you down
Below Normal6Lower than usual
Normal8Almost every program
Above Normal10Slightly more important
High13Important tools; use carefully
Realtime24Dangerous; needs special rights (Section 5.3)

Task Manager shows "Low" for Idle. Windows 11 also has a "Background" mode for some system tasks (memory and I/O priority are lowered too).

Relative thread priority (the step inside the class):

Thread priorityMeaning
IdleLowest in the class
LowestTwo below normal
Below NormalOne below
NormalSame as the process's base
Above NormalOne above
HighestTwo above
Time CriticalTop of the class (for dynamic classes this is 15; for Realtime it is 31)

The final number = process class base + the thread's step. For example, a Normal-class process (base 8) with a thread set to Above Normal gives priority 9. A thread in a Normal-class process set to Time Critical gets 15.

 Process class Normal (base 8)
   Idle           → special low value
   Lowest         → 6
   Below Normal   → 7
   Normal         → 8     ← default for most threads
   Above Normal   → 9
   Highest        → 10
   Time Critical  → 15

Changing priority:

HowNotes
Task Manager → Details → right-click process → Set priorityChanges the process class. Reverts when the process ends
PowerShell: (Get-Process notepad).PriorityClass = 'BelowNormal'Same idea
start /belownormal program.exe in Command PromptStarts at that class
SetPriorityClass, SetThreadPriorityThe calls programs use

Good habit: If a long job (a video render, a big backup) makes your PC feel slow, run it at Below Normal or Idle. It will still finish, but the mouse and windows stay lively.

5.2 Priority Boosting

What it is: Windows can temporarily raise a thread's priority above its base to help it respond faster or avoid being stuck. This dynamic boost only happens for threads in the dynamic range (1–15), never for real-time ones.

Common boosts:

EventWhy the boost
Thread finishes waiting for I/O (disk, network, keyboard, mouse)So it can react quickly. The size depends on the device; for example keyboard or mouse input gives a bigger boost than a disk
Thread of the foreground windowMakes the app you use feel snappier. Its quantum can also be longer
GUI thread wakes up because of a window messageKeeps the interface responsive
Thread has been waiting in Ready for too longAnti-starvation (see below)
Thread released a lock that others wait forHelps threads work through shared locks

How the boost fades: Each time the boosted thread uses up a full quantum, its priority drops by one level, until it is back at its base. A boost never raises a thread above 15.

 Priority
   11 │        ●         (boost after waiting for the keyboard)
   10 │         ●
    9 │          ●
    8 │ ───●─────────●─────●────●  ← base priority 8
      └──────────────────────────► time (each ● = one quantum used)

Anti-starvation: the "balance set manager". A low-priority thread might never get a core if busier threads always win. Windows has a helper that checks about once per second for threads that have been Ready for around 4 seconds or more. It gives them a short, big boost (to priority 15) and a double quantum so they can finish a bit of work. After that, they return to normal. This keeps even low-priority threads moving.

You can turn dynamic boost off per process with the SetProcessPriorityBoost call. It is rarely needed.

5.3 Real-Time Priority

What it is: Priorities 16 to 31 are the real-time range. Threads here are not boosted or lowered by Windows. They stay at a fixed priority.

Real-time does NOT mean "faster". In computing, "real-time" means a task must respond within a guaranteed time limit, such as an audio buffer, a robot arm or a medical device. Windows is not a true real-time operating system, but this range gets as close as it can.

Dangers: A real-time thread can beat everything that Windows itself needs to run, including threads that handle your keyboard, mouse and disk. If a real-time thread loops forever, the PC can freeze solid. Because of this:

  • Setting the Realtime priority class needs special user rights (the "Increase scheduling priority" right; administrators have it).
  • Without that right, Windows quietly lowers the request to High.
  • Task Manager and the OS warn you.

Who uses real-time priority: some audio software and drivers, certain industrial or lab software, and parts of Windows itself (for example, some critical system threads). Normal desktop software should never use it.

Rule: Use High at most, and only for short, well-behaved work. Leave Realtime to specialists.

Also: MMCSS. For multimedia such as audio and video, Windows has a helper called MMCSS (Multimedia Class Scheduler Service). A program registers its thread, and MMCSS gives it a boosted priority for a few milliseconds each cycle in a controlled way. This is safer than choosing real-time yourself.

5.4 Priority Inversion Problem

What it is: Priority inversion is a bug-like situation where a high-priority thread is stuck waiting for a low-priority thread, and a medium-priority thread keeps stealing the CPU. So the high-priority thread is effectively slowed by someone less important.

Here is the story with three threads:

ThreadPriorityWhat it does
HHighNeeds a lock (mutex)
MMediumJust busy calculating, does not need the lock
LLowHolds the lock right now
 time ──►

 L (low)    ██ takes lock ██ ─preempted─                        ── ██ releases lock
 H (high)                       ▒▒▒▒ wants lock → BLOCKED ▒▒▒▒▒▒▒▒▒▒▒▒▒▒ ██ finally runs
 M (medium)                     ████████████████████████████
                                 ▲
        M runs instead of L, so L cannot finish and cannot release the lock.
        H waits for L. L waits for M. The ranking is turned upside down.

Why it hurts: H should be the most important. But M, which is less important, delays H without ever touching the lock.

Famous case: In 1997 the Mars Pathfinder probe kept resetting itself because of exactly this bug. The fix was to turn on priority inheritance.

How it is solved:

MethodIdea
Priority inheritanceWhile H waits for a lock held by L, L temporarily gets H's priority. Now M cannot push L aside, L finishes and releases the lock
Priority ceilingThe lock has a ceiling; any thread that holds it runs at that high priority
Avoid long locksKeep locks short and do not hold them while doing slow things

What Windows does: Windows has no general priority inheritance for ordinary locks (such as a mutex or critical section). Instead it uses a cheaper trick to break the starvation. As seen in Section 5.2, the balance-set helper boosts any thread that has been Ready for several seconds. L eventually gets a boost, finishes, and frees the lock. It is slow (seconds) but it breaks the deadlock-like stall. You should still design to avoid inversion: keep high- and low-priority threads from sharing locks where possible.

Summary

TermPlain meaning
Priority 0–31Bigger number runs first
Dynamic range 1–15Normal programs; Windows may boost and drop
Real-time range 16–31Fixed; can starve the OS; needs special rights
Priority classA process-level base (Idle 4, Below Normal 6, Normal 8, Above Normal 10, High 13, Realtime 24)
Relative thread priorityA step up or down from the class base
BoostA temporary lift (after I/O, for the foreground window, or against starvation)
Balance-set managerBoosts long-starved ready threads about once a second
MMCSSSafe way for audio/video threads to get priority
Priority inversionHigh waits on low while medium runs
Priority inheritanceLow borrows high's priority to finish quickly