AlgoMaster Logo

Scheduling Metrics

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

Two CPU schedules can keep the processor equally busy while producing very different experiences.

In one schedule, a terminal command starts immediately while a background computation finishes slightly later. In another, the background computation finishes first while the terminal appears frozen. Both schedules may complete the same amount of work, but they optimize different outcomes.

To compare them precisely, we need scheduling metrics.

A scheduling metric turns some property of a schedule—such as delay, completion rate, or CPU usage—into a measurable value.

Metrics let us replace vague claims such as “this schedule feels faster” with exact statements about response time, waiting time, turnaround time, throughput, and utilization.

The Basic Measurement Model

Classical scheduling problems describe each process using a small set of timestamps and durations. The word process is conventional in these problems, although an operating-system scheduler normally schedules threads.

For a process P, the most important starting values are:

  • Arrival time (AT): when P first becomes available for scheduling in the workload
  • Burst time (BT): how much CPU execution P requires in the simplified single-burst model
  • Start time (ST): when P first receives the CPU
  • Completion time (CT): when P finishes the modeled work

Consider a process that arrives at time 2, first runs at time 5, and completes at time 9 after receiving four units of CPU time:

TimeEventSymbol
2P arrivesAT = 2
5P first runs, after waiting 3 unitsST = 5
5 to 9P uses 4 CPU unitsBT = 4
9P completesCT = 9

The time values can represent milliseconds, clock ticks, or abstract time units. Every value in one problem must use the same unit.

Arrival time does not necessarily mean operating-system process creation time. A process may be created earlier but admitted to the modeled workload later. If the same process blocks and subsequently wakes, that wakeup makes it runnable again but is not normally treated as a new arrival for the same job.

Burst time means time actually executing on a CPU. It does not include time spent ready but waiting for a turn. When a problem models several CPU bursts separated by I/O, each burst has its own duration and the process's total CPU time is the sum of those durations.

Reading Timeline Boundaries, Not Box Counts

Scheduling timelines are commonly drawn as Gantt charts:

Time rangeRunning
0 to 3P1
3 to 7P2

P1 runs from time 0 up to, but not including, time 3. Its execution duration is:

P2 runs from time 3 to time 7, so its duration is:

The labels under the boundaries are timestamps, not numbered CPU slots. Counting both endpoints would incorrectly give P1 four units and P2 five.

The reliable rule is:

Duration equals ending timestamp minus starting timestamp.

This convention also makes adjacent intervals unambiguous. One process stops at time 3 and the next begins at time 3; no extra unit appears between them.

Turnaround Time

Turnaround time measures the total elapsed time from arrival until completion.

If a process arrives at time 2 and completes at time 9:

Turnaround time includes every kind of time that passes after arrival:

  • Time executing on the CPU
  • Time ready but waiting for the CPU
  • Time blocked for I/O or another event, if the model includes such waits
  • Scheduling and execution overhead included in the timeline

From a batch-job perspective, turnaround answers:

How long did the entire job take from becoming available until finishing?

A short job can have poor turnaround if it waits behind other work. A long job can have a large turnaround even if it starts immediately, simply because it needs substantial CPU time.

Response Time

Response time measures how long a process waits before it receives the CPU for the first time.

For the process that arrives at time 2 and first runs at time 5:

Only the first dispatch matters. If the process is later preempted and waits again, those later waits do not change its response time.

P arrives and waits, runs for the first time, is preempted and waits again, runs a second time, and completes. Response time covers only the first of those waits.

Response time is especially important for interactive work. A command that begins producing visible progress quickly can feel responsive even if its final completion occurs later.

The term can be confusing in backend engineering. Application dashboards often define request response time as the entire request latency until a response completes. In CPU-scheduling terminology, response time has the narrower meaning of delay until first execution.

Waiting Time

Waiting time measures how much time a process spends ready to run but not executing.

A process can accumulate waiting time in several separate intervals:

P is ready for 3 units, runs, is ready again for 2 units, and runs once more. Its total waiting time is 3 + 2 = 5.

Preemption does not reset the value. Waiting time is the sum of every interval during which the process is eligible for the CPU but another process owns it.

For the simplified model in which a process has one CPU burst and never blocks:

This works because the process's turnaround contains only two categories:

If turnaround is 7 units and CPU burst time is 4 units:

Waiting time and response time are equal only when the process runs once without later preemption. Once a process can run, be preempted, and wait again, its total waiting time can be larger than its response time.

Completion Time

Completion time is the timestamp at which a process finishes its required work.

It is not a duration by itself. A completion time of 20 does not mean the process ran for 20 units. The process may have arrived at time 12, executed for 3 units, and waited for 5:

Completion time is useful because the other latency metrics can be derived from it. It also reveals the order in which jobs finish.

When every process arrives at time 0, its completion time and turnaround time happen to be equal. That equality disappears as soon as arrival times differ.

One Complete Worked Example

Suppose three processes have the following arrival and CPU-burst times:

ProcessArrival time (AT)Burst time (BT)
A05
B13
C21

Assume a single CPU and no context-switch cost. The operating system produces this schedule:

Time rangeRunning
0 to 2A
2 to 3C
3 to 6B
6 to 9A

First, verify the CPU time received by each process:

Every value matches the required burst time.

Now read the first start and final completion from the timeline:

ProcessATBTSTCTRT = ST - ATTAT = CT - ATWT = TAT - BT
A0509094
B1336252
C2123010

For process A:

A's four waiting units are visible from time 2 through time 6. It responded immediately, but it did not run continuously to completion.

For process B:

B runs in one uninterrupted interval, so all of its waiting occurs before its first response.

For process C:

C starts as soon as it arrives.

Loading simulation...

Computing Averages

When comparing schedules for the same workload, per-process values are often summarized using an arithmetic mean.

For n processes:

For the worked example:

Do not round individual process values before computing the average. Add the exact values first, divide once, and round only the final result if necessary.

Averages are meaningful only when calculated over the same workload and under the same assumptions. Comparing one schedule tested with three short jobs against another tested with ten long jobs says little about the schedulers themselves.

Limits of the Waiting-Time Shortcut

The formula:

assumes that the only non-executing time inside turnaround is ready-queue waiting. Real programs often block.

Consider process X:

Time rangeState of X
0 to 2Using the CPU
2 to 7Blocked for I/O
7 to 9Ready, waiting for a CPU
9 to 10Using the CPU

That gives CPU time of 2 + 1 = 3, blocked time of 5, ready waiting of 2, and a turnaround of 10.

Using TAT - CPU time would produce:

But X did not wait seven units for a CPU. Five of those units were spent blocked and unable to run. Its actual ready-queue waiting time is two units.

For a model that explicitly includes blocking:

For X:

This distinction matters in production. A request may take 200 milliseconds while consuming only 5 milliseconds of CPU, but the remaining 195 milliseconds are not necessarily scheduling delay. The request might be waiting for a database, a network response, a lock, or storage.

CPU Utilization

CPU utilization measures the fraction of an observation interval during which a CPU is busy.

In a simplified one-CPU timeline:

Suppose the CPU executes work from time 0 to 2, remains idle from 2 to 5, and executes again from 5 to 6:

Time rangeCPU
0 to 2Running P
2 to 5Idle
5 to 6Running Q

Busy time is 2 + 1 = 3 units over a 6-unit interval:

The idle interval is not automatically a scheduler failure. No runnable work may have existed from time 2 to time 5.

Utilization also needs a clear definition of busy. Operating-system tools commonly count both user-mode execution and kernel work as busy CPU time. From an application's perspective, time spent on scheduler overhead is busy but not productive application service.

High utilization is not the same as good performance. A CPU can be 100% busy while important runnable work experiences unacceptable delay.

On a multicore machine, utilization must identify its denominator. Using one of four CPUs fully is 100% utilization of that CPU but 25% of the machine's total CPU capacity.

Throughput

Throughput measures how much work completes per unit of time.

The worked example completes three processes between time 0 and time 9:

If the time unit is one second, the throughput is approximately 0.33 processes per second.

Throughput counts completions, not starts. Five jobs may start during an interval while only two finish, producing a throughput of two completed jobs for that interval.

The definition of a job must remain consistent. Completing 1,000 tiny requests is not directly comparable with completing 1,000 large analytical tasks. Production systems therefore report throughput in workload-specific units such as requests per second, records processed per second, or builds per hour.

Short measurement windows can also mislead. Work completed during the interval may have started before measurement began, while work started during the interval may finish later. Stable comparisons use clearly defined windows and similar workload conditions.

Makespan

The makespan is the elapsed time required to complete an entire set of jobs.

If measurement begins at the earliest arrival:

For the worked example:

Makespan is useful for finite batch workloads: completing a build, processing a fixed collection of files, or running a known set of tasks.

It does not describe how individual jobs experienced the schedule. Two schedules can have the same makespan while one gives every short job an early response and the other makes those jobs wait.

Service Time, Elapsed Time, and Scheduling Delay

Three kinds of time are often confused:

CPU time, also called service time in a simple model, is the time a task actually executes on a CPU.

Elapsed time is wall-clock time from a chosen start event to an end event. Turnaround and response are elapsed-time measurements.

Scheduling delay is elapsed time spent runnable but not executing. It is the real-system counterpart of ready-queue waiting time.

For a single CPU burst with no blocking:

For a real task that blocks:

This decomposition is more useful than treating every gap between CPU time and elapsed time as a scheduler problem.

For a multithreaded process, total CPU time can exceed elapsed time. If four threads each execute for one second in parallel, the process consumes about four CPU-seconds during roughly one second of wall-clock time.

Tail Behavior Hidden by Averages

An average compresses many observations into one number. It does not show how widely the values differ.

Suppose five response times are:

Their average is:

No individual request experienced a 10-millisecond response. Four responded much faster, while one waited far longer.

Useful summaries can therefore include:

  • The maximum, which reveals the worst observation in the set
  • A percentile such as p95 or p99, which exposes the slower tail at scale
  • The distribution or histogram, which shows whether results cluster or vary widely
  • Variance or standard deviation, which quantifies unpredictability

Tail measurements require enough samples. A p99 calculated from a handful of processes is not informative because the dataset does not contain enough observations to characterize the slowest one percent reliably.

For interactive and backend workloads, an acceptable average can coexist with visible stalls or severe tail latency. A complete evaluation should ask both how the typical task performs and whether any runnable task waits unreasonably long.

Progress and Fairness

Fairness is harder to express than turnaround or response time because it depends on what each task is supposed to receive.

Equal CPU time is not always fair. A low-importance batch task and a latency-sensitive system task may deliberately receive different service. Two tasks with different configured weights may be considered fairly treated when their CPU shares are proportional rather than equal.

Useful observations include:

  • CPU service received by each continuously runnable task
  • The longest time any eligible task waits
  • Whether every runnable task continues to make progress
  • How actual CPU shares compare with intended shares

A task that remains runnable indefinitely but never receives CPU time experiences starvation. Its waiting time grows without bound while other work continues.

An average can hide starvation. Nine tasks may complete quickly while a tenth receives no service at all. The completed jobs produce attractive averages, but the schedule fails to provide progress for every eligible task.

Fairness is therefore not one universal formula. It is a contract about how CPU service should be distributed, followed by measurements that test that contract.

Tradeoffs Among Scheduling Metrics

Scheduling metrics are not independent scores that can all be improved without limit.

Running a long job without interruption can reduce switching overhead and help it complete sooner. Interrupting it to start a short interactive task may improve that task's response time while slightly increasing the long job's turnaround.

Keeping a queue of work available can produce high utilization and throughput, but sustained queueing also means new work may wait longer before running.

Giving every runnable task extremely frequent turns can limit long pauses, but excessive switching consumes CPU time and disrupts hardware locality.

The intended workload determines which trade-off matters:

  • An interactive application values prompt initial response.
  • A batch processor often values throughput and makespan.
  • A backend service cares about completion latency, especially at the tail.
  • A shared machine needs a defensible distribution of progress.

Metrics describe these outcomes. They do not choose the scheduling policy by themselves.

Observing Time on Linux

The Linux time utility separates elapsed wall-clock time from CPU time. Use the external command explicitly because some shells provide a different built-in command:

A typical result is:

real is elapsed time. user is CPU time spent executing application code, and sys is CPU time the kernel spent working on behalf of the process.

The sleep process exists for about one second but consumes almost no CPU time. Most of its elapsed time is blocked time, not ready-queue waiting.

A CPU-intensive command produces a different relationship. For example:

On an otherwise idle machine, user + sys should be much closer to real. Exact values depend on the hardware, current load, and command implementation.

These measurements do not directly reveal scheduling delay. A large gap between elapsed time and CPU time can come from blocking, ready-queue waiting, or both.

Observing Run-Queue Waiting on Linux

On Linux systems that expose scheduler statistics, /proc/<pid>/schedstat contains three cumulative values for a task:

  1. Time spent executing on a CPU, in nanoseconds
  2. Time spent waiting on a run queue, in nanoseconds
  3. Number of timeslices in which the task has run

Inspect the current shell:

Convert the first two fields to seconds:

These are lifetime counters for the task, not one request. To measure an interval, read the counters before and after the workload and subtract the earlier values.

For an individual thread in a multithreaded process, use:

Run-queue waiting is narrower than elapsed time. It counts time during which the task could run but waited for CPU service; it does not count time asleep waiting for network data or another event.

Availability and accounting details depend on the kernel configuration. Application-level response and turnaround still require timestamps around the actual request or job being measured.

A Reliable Calculation Workflow

For a scheduling timeline, use the same sequence every time.

First, record each process's arrival and required CPU burst. Then draw the complete CPU timeline and label every boundary timestamp.

From the timeline, identify each process's first start and final completion. Compute:

Use the waiting-time shortcut only if the problem has no blocked intervals. Otherwise, add the ready-queue waiting intervals directly or subtract blocked time as well.

Finally, perform sanity checks:

  • Every process receives exactly its required CPU burst.
  • Completion time is no earlier than first start time.
  • Response, waiting, and turnaround times are nonnegative.
  • Response time is no greater than turnaround time.
  • In the single-burst model, turnaround equals waiting plus burst time.
  • If the CPU is idle, no eligible process should be shown waiting to run unless the problem states an additional constraint.

These checks catch most arithmetic and timeline mistakes before averages are calculated.

Summary

Arrival, first start, and completion timestamps define the central per-process metrics:

For a single CPU burst with no blocking, waiting time = turnaround time - burst time. Real tasks may also spend time blocked, so elapsed time minus CPU time is not automatically scheduling delay.

Utilization measures how much CPU capacity is busy, throughput measures completed work per unit time, and makespan measures how long a finite workload takes to finish. Averages are useful but can hide tail delays and starvation, so scheduling should be evaluated with the workload's actual responsiveness, progress, and predictability needs in mind.

Quiz

Scheduling Metrics Quiz

5 quizzes