AlgoMaster Logo

Priority Scheduling and Aging

36 min readUpdated August 7, 2026
Listen to this chapter
Unlock Audio

Not all runnable work is equally urgent. A server might be compressing old logs when a latency-sensitive request arrives. Treating both tasks equally is simple, but may delay the more important work.

Priority scheduling handles this by running the highest-priority process in the ready queue.

The trade-off is starvation: if higher-priority work keeps arriving, a low-priority process may wait indefinitely. Aging reduces this risk by gradually increasing the effective priority of processes that have been waiting.

Priority as an Ordering Rule

A priority value tells the scheduler which ready process should be preferred.

Suppose the ready population is:

If a smaller number means higher priority, the scheduler selects P2:

Priority says nothing by itself about how much CPU time a process needs. A high-priority process can have a short or long burst.

Priority scheduling also needs a tie-breaking rule. If P2 and P4 both have priority 1, the scheduler might choose the earlier arrival first. Other systems may rotate equal-priority tasks. For the numerical examples in this chapter, equal priorities are resolved by arrival order.

Explicit Priority Conventions

Priority numbers do not have a universal direction.

One system may define:

Another may define:

This chapter uses:

A smaller numeric value represents a higher scheduling priority.

Under this convention, priority 1 outranks priority 2.

Never infer the convention from the word higher. “Higher priority” describes stronger preference, not necessarily a numerically larger value. State the convention before constructing a timeline.

Base Priority and Effective Priority

A useful mental model separates two values.

The base priority represents the process's assigned importance. It may come from a user setting, a service policy, or the kind of work being performed.

The effective priority is the value the scheduler currently uses. It can include temporary adjustments such as aging.

The base priority is only one input. The value the scheduler actually compares is the one on the right, which is why a process can move up the queue without anyone changing its assigned importance.

In the simplest priority scheduler:

With aging, the effective priority improves while a runnable process waits. The base value remains the reference to which the system can later return.

Keeping the distinction explicit prevents a common confusion: aging does not have to permanently rewrite the process's assigned importance.

Static and Dynamic Priorities

A static priority remains fixed unless a user, administrator, or program explicitly changes it.

A dynamic priority can change automatically as the process runs or waits.

Static priorities are predictable, but a poorly chosen value can cause persistent starvation. Dynamic priorities let the scheduler react to observed behavior, although the rules become more complex.

Aging is one kind of dynamic adjustment:

The terms static and dynamic describe whether the scheduling value changes automatically. They do not determine whether the scheduler is preemptive.

Non-Preemptive Priority Scheduling

In non-preemptive priority scheduling, the scheduler selects the highest-priority ready process when the CPU becomes free.

Once selected, the process continues until its current CPU burst finishes, it blocks, or it exits. A higher-priority arrival does not interrupt it.

The algorithm is:

This form limits priority-based preemption, but urgent work can still wait behind a long lower-priority burst that has already started.

Preemptive Priority Scheduling

In preemptive priority scheduling, a newly runnable process can take the CPU from the current process if its effective priority is higher.

P1 holds the CPU at priority 4 when P2 becomes ready at priority 1. The scheduler preempts P1 and dispatches P2.

The interrupted process remains runnable and returns to the appropriate ready queue with its remaining CPU burst preserved.

An equal-priority arrival does not automatically preempt under the convention used here. The tie rule determines the ordering among equal-priority work.

Preemption improves the response of urgent tasks. It also increases the potential number of context switches and can delay lower-priority work more aggressively.

The Workload

We will compare both forms using one CPU and these processes:

ProcessArrival timeCPU burstPriority
P1083
P2141
P3224
P4312

Remember that smaller numbers mean higher priority:

Assume:

  • One CPU
  • No blocking
  • Zero context-switch cost
  • Arrival order breaks equal-priority ties

The total CPU demand is 15 time units.

Non-Preemptive Priority: Step by Step

At time 0, only P1 is ready. It starts immediately.

P2, P3, and P4 arrive while P1 runs. Although all three priorities differ, non-preemptive scheduling does not reconsider the current choice:

P1 completes at time 8. The scheduler then chooses the highest-priority ready process:

P2 runs to time 12, P4 runs to time 13, and P3 runs to time 15:

Because every process runs in one uninterrupted interval, response and waiting time are equal:

The averages are:

P2 has the highest priority, but it still waits seven units because P1 began first and cannot be preempted.

Preemptive Priority: Step by Step

At time 0, P1 starts at priority 3.

Time 1: P2 arrives

P1 has seven CPU units remaining. P2 arrives at priority 1:

P2 preempts P1 and begins immediately.

Times 2 and 3: P3 and P4 arrive

P3 arrives at priority 4 and P4 at priority 2. Neither outranks the running P2 at priority 1, so P2 continues.

P2 finishes at time 5.

Time 5: choose from the ready processes

The ready population is:

P4 runs from time 5 to 6. P1 then outranks P3 and runs its remaining seven units from time 6 to 13. P3 runs last.

The complete timeline is:

Verify CPU service:

Preemptive Priority Metrics

P1 starts immediately, is preempted at time 1, and resumes at time 6:

P2 starts as soon as it arrives:

P3 has the lowest priority and runs last:

P4 waits while higher-priority P2 runs:

The averages are:

Preemption sharply improves P2's response and completion, but it delays P1. P3 is unaffected because it remains the lowest-priority choice in both schedules.

Comparing Both Forms

PolicyAverage responseAverage waitingAverage turnaroundTask-to-task switches
Non-preemptive priority6.756.7510.503
Preemptive priority3.254.508.254

The preemptive schedule improves all three averages for this workload by allowing P2 to run at arrival rather than waiting behind P1.

That result is workload-specific. Preemption does not guarantee lower averages for every possible set of arrivals and priorities, especially when switching has a nonzero cost.

The table also hides the distribution. P2 benefits greatly, P1 completes later, and P3 remains delayed. Priority scheduling is intentionally unequal: its goal is to prefer work according to assigned importance, not to minimize every process's delay equally.

Starvation

Priority scheduling can cause starvation, also called indefinite postponement.

Suppose low-priority process L is ready with priority 6. Higher-priority work keeps arriving before the CPU becomes available:

At each decision the ready set is L at priority 6 plus a fresh priority-1 arrival, so the scheduler runs H1, then H2, then H3, and so on.

L is capable of running. It is not blocked for I/O and has not been stopped. The scheduler repeatedly bypasses it because another ready process has a more favorable priority.

If the stream of higher-priority work continues without a protection mechanism, L's waiting time has no fixed upper bound.

Starvation can occur in both forms:

  • In non-preemptive priority scheduling, L loses each time the CPU becomes free.
  • In preemptive priority scheduling, L may also be interrupted after it finally begins.

A strong average response time for high-priority work does not prove that all work makes progress.

Why Simple Priority Assignment Is Not Enough

One response to starvation is to assign priorities more carefully. That helps, but it cannot fully solve a dynamic overload.

Even sensible priorities can create starvation when:

  • High-priority arrivals are more frequent than expected
  • A high-priority task consumes much more CPU than expected
  • Many tasks are assigned the same high priority
  • A low-priority maintenance task must eventually run despite constant foreground load

The system needs a way for waiting itself to influence the scheduling decision.

That mechanism is aging.

Aging

Aging gradually improves a process's effective priority while it remains ready but does not run.

Using our smaller-number-is-higher convention, aging decreases the numeric effective priority:

Eventually, a long-waiting process reaches the priority of newer favored work and can be selected.

The key idea is:

The longer a runnable process is denied CPU service, the stronger its scheduling claim becomes.

Aging converts unbounded starvation risk into a policy with progress, provided that promotion eventually reaches a sufficiently favorable priority and ties are handled fairly.

A Concrete Aging Rule

Assume:

  • Smaller values mean higher priority.
  • Priority 0 is the highest allowed value.
  • A process gains one priority level for every four time units spent ready but not running.

One possible formula is:

For process L with base priority 6:

Ready waiting timeEffective priority
0 through 36
4 through 75
8 through 114
12 through 153
16 through 192
20 through 231
24 or more0

Suppose new priority-2 tasks keep arriving. Without aging, L at priority 6 always loses.

At waiting time 16, L's effective priority becomes 2. If equal priorities use arrival order, L is older than the newly arriving priority-2 tasks and is selected at the next eligible decision.

The exact numbers are design choices. A different system could promote by one level every ten milliseconds, use continuous rather than stepwise adjustment, or cap the boost at a configured level.

Aging Timeline

The promotion of L can be visualized as a state change over time:

Ready wait0481216
L's effective priority65432

New foreground work stays at priority 2 throughout. By the time L reaches 2 it can compete on equal terms.

Before time 16, every priority-2 process outranks L. At time 16, L ties them. The oldest-arrival tie rule prevents later priority-2 arrivals from passing L forever.

If the current process is executing under a non-preemptive policy, L still waits for that burst to end. Aging changes the next selection; it does not retroactively make a non-preemptive scheduler interrupt the current process.

Under a preemptive policy, a promotion may create a reason to reconsider the current owner, depending on when the system updates effective priorities.

Loading simulation...

What Time Should Count Toward Aging?

Aging is intended to compensate for denial of CPU service. The relevant time is usually:

Time blocked for network data or storage normally should not count in the same way. A blocked process is not being denied a CPU; it cannot make progress until its event occurs.

Consider:

The policy must define what happens to any previous aging bonus when P runs, blocks, or wakes. Common design choices include:

  • Reset the effective priority to the base value after receiving service
  • Reduce the bonus gradually rather than removing it at once
  • Preserve part of the bonus across short execution intervals

There is no universal rule. The important requirement is consistency with the intended progress guarantee.

Choosing an Aging Rate

The aging interval controls how quickly waiting work catches higher-priority work.

If promotion is too slow, starvation may be technically avoidable but still operationally unacceptable. A backup task that finally runs after six hours may miss its maintenance window.

If promotion is too fast, base priorities lose much of their meaning. Nearly every waiting process quickly reaches the top level, and the scheduler behaves more like an arrival-ordered system.

Aggressive promotion can also increase preemption if effective priorities change frequently.

A useful aging policy balances:

  • The maximum acceptable delay for low-priority work
  • The response required by genuinely urgent work
  • The range of available priority levels
  • The current runnable population and CPU capacity
  • The cost of additional scheduling decisions

Aging is not merely “add one occasionally.” Its rate defines how the system trades strict priority against guaranteed progress.

Bounding Wait with Aging

Aging can provide a rough waiting bound in a simplified model.

Suppose:

  • L starts at priority 6.
  • Priority 2 is sufficient to compete with the high-priority arrivals.
  • L improves by one level every four waiting units.

L needs four promotions:

The promotion delay is:

After that, L still waits for:

  • The currently running non-preemptive burst, if any
  • Equal-priority work already ahead under the tie rule
  • Dispatch and context-switch overhead

The 16 units are therefore the time to become competitive, not necessarily an exact completion or response bound.

This calculation is useful because it exposes the policy's guarantee. If 16 time units are too long, the aging interval or target priority must change.

Priority Scheduling Pseudocode

A shared selection function can support either preemptive or non-preemptive priority scheduling:

Non-preemptive behavior:

Preemptive behavior:

One form of aging:

A real implementation does not need to scan every process on every clock tick. It can organize priority queues and calculate promotion events efficiently. The pseudocode expresses policy, not a required data structure.

A Reliable Calculation Method

Begin by writing down the priority convention and tie rule.

For non-preemptive scheduling:

  1. At time 0, identify the processes that have arrived.
  2. Choose the ready process with the highest priority.
  3. Run it until completion or blocking.
  4. Add all arrivals that occurred during that interval.
  5. Choose again from the current ready population.

For preemptive scheduling, stop at every arrival:

  1. Subtract the CPU time the current process just received.
  2. Add the arriving process.
  3. Compare its priority with the current process's effective priority.
  4. Preempt only if the policy and tie rule require it.

With aging, also identify every timestamp at which a waiting process changes effective priority. Such a promotion can change the next selection and, under a preemptive policy, may change the current selection.

After the timeline is complete:

The waiting shortcut assumes one CPU burst and no blocking.

Finally, verify that every execution segment adds to the process's original burst and that no lower-priority process runs while a higher-priority ready process is being ignored under the selected policy.

Observing Niceness on Linux

Linux provides a nice value that influences how ordinary time-sharing tasks receive CPU service.

Inspect the current shell:

A typical result is:

NI is the nice value. On Linux it ranges from -20, which is most favorable to the process, through 19, which is least favorable. The displayed PRI value is a tool-level view of scheduler priority and should not be mixed directly with the classroom convention used earlier.

Start a command with a niceness adjustment:

This increases the inherited nice value by 10, making the command less favored than it would otherwise be.

An unprivileged user can normally make an owned process nicer by increasing its nice value. Decreasing the nice value to gain more favorable service requires appropriate privilege or a configured resource limit.

A Small Linux Experiment

On a Linux test machine, run two CPU-bound processes on one allowed CPU. Do not run this experiment on a shared production host.

First inspect the CPUs available to the shell:

Choose one CPU from the result. The commands below use CPU 0; replace 0 if necessary.

Start one process at the inherited nice value and one with niceness increased by 10:

Install cleanup immediately:

Observe several samples:

Both processes should continue making progress, but the process with the less favorable nice value should receive a smaller CPU share over a sufficiently long observation. Short samples can fluctuate.

Change the normal process to nice value 15:

The process now at nice value 15 is less favored than the process at nice value 10, so their relative CPU shares should move in the opposite direction over time.

Observe again:

Finally, clean up:

This experiment demonstrates priority influence, not the strict priority algorithm from the numerical examples. Ordinary Linux niceness changes relative scheduling weight; it does not mean “run every nice-0 task to completion before any nice-10 task.” Both runnable processes can receive CPU service.

Priority in Backend Systems

Backend systems often have work with different operational importance:

  • User-facing requests versus offline report generation
  • Health checks versus cache compaction
  • Replication traffic versus best-effort cleanup
  • Deadline-sensitive control work versus background maintenance

Marking everything high priority defeats the purpose. If every task receives the most favorable value, priority no longer distinguishes urgent work.

Priority also does not create CPU capacity. Favoring one class under overload necessarily delays another. A system needs explicit expectations for how long deferred work may wait and an aging or capacity policy that lets necessary background work eventually run.

Application-level priority queues have the same starvation risk as CPU priority scheduling. A worker that always removes urgent jobs first can neglect ordinary jobs forever if urgent arrivals never stop.

Priority vs. Permission

Scheduling priority controls preference for CPU service. It does not grant authority to access memory, files, devices, or other processes.

A high-priority process still obeys the operating system's protection rules. Conversely, a privileged administrative process does not necessarily run at the highest scheduling priority.

Keeping these ideas separate avoids a dangerous interpretation:

They solve different operating-system problems.

Summary

Priority scheduling selects the ready process with the most favorable effective priority. A non-preemptive scheduler waits for the current burst to end, while a preemptive scheduler can interrupt lower-priority work when a higher-priority process becomes runnable.

Strict priority can starve low-priority processes. Aging prevents indefinite bypass by improving a process's effective priority as its ready-queue waiting time grows. The aging rate and tie rule determine how quickly that process becomes competitive.

Priority values require an explicit numeric convention, and real systems must distinguish assigned base priority from dynamically adjusted effective priority. Linux niceness demonstrates priority influence through relative CPU weighting, but it is not identical to the classical strict-priority algorithm.

Quiz

Priority Scheduling and Aging Quiz

5 quizzes