CPU scheduling simulator
An operating system's scheduler decides which process runs next. Edit the processes below, pick an algorithm, and get the Gantt chart and every process's waiting, turnaround and response time, worked out the way an exam expects. Further down: each algorithm explained, a worked example, and how Linux and Windows really schedule.
| Process | Arrival | Burst | Priority | Completion | Turnaround | Waiting | Response | Remove |
|---|---|---|---|---|---|---|---|---|
| P1 | 24 | 24 | 16 | 0 | ||||
| P2 | 14 | 13 | 9 | 1 | ||||
| P3 | 28 | 26 | 17 | 2 | ||||
| P4 | 25 | 22 | 17 | 5 | ||||
| P5 | 12 | 8 | 6 | 6 | ||||
| Average | 18.6 | 13 | 2.8 | |||||
| Algorithm | Waiting | Turnaround | Response | Switches |
|---|---|---|---|---|
| 11.4 | 17 | 11.4 | 4 | |
| 8.2 | 13.8 | 8.2 | 4 | |
| 6.6 | 12.2 | 4.4 | 5 | |
| 13 | 18.6 | 2.8 | 13 | |
| 10.6 | 16.2 | 10.6 | 4 | |
| 9.6 | 15.2 | 7.8 | 5 |
Averages in time units. Round robin uses quantum 2. Bold marks the lowest average waiting time.
How to use the simulator
Each row of the table is a process with an arrival time, a burst time (how many time units of CPU it needs) and a priority. Change any number and the schedule is recalculated. The Gantt chart shows which process holds the CPU in each time unit, and the table fills in each process's completion, turnaround, waiting and response time, with averages underneath. The panel on the right runs every algorithm on the same processes, so you can compare them directly.
Press Step from 0 to move through time one unit at a time and see the ready queue and the reason for each decision. Things to try:
- Load Convoy effect and compare FCFS with SJF: the same three jobs, average waiting time 17 against 3.
- With round robin, change the quantum from 1 to 5 and watch the number of context switches and the average response time.
- Load A long job keeps waiting and choose SRTF or preemptive priority: P1 is pushed back every time a short or important job arrives.
The simulation follows the usual textbook conventions, which the page states so you can match them to your course: a process that arrives at the same moment another is preempted joins the queue first; ties go to the earlier arrival and then the lower process number; a lower priority number means a higher priority; and context switches take no time. It reproduces the worked examples in Silberschatz, Galvin and Gagne's Operating System Concepts exactly.
What is CPU scheduling?
CPU scheduling is how an operating system decides which of the processes that are ready to run gets a CPU, and for how long. A machine usually has far more runnable threads than CPU cores, so the kernel's scheduler makes this choice many times a second: whenever a process finishes, blocks waiting for input or output, becomes ready, or uses up its time slice.
Processes alternate between CPU bursts, when they compute, and waits for I/O. A process waiting for a disk or the network is not in the ready queue; the scheduler only chooses among processes that could run right now. The algorithms on this page treat each process as one CPU burst, as textbooks do, which is enough to see how the choices differ.
Scheduling algorithms are judged on several measures that pull against each other: keeping the CPU busy, finishing as many jobs as possible per unit of time (throughput), finishing each job soon after it arrives (turnaround), starting interactive work quickly (response time), and not leaving any process waiting forever (fairness).
Turnaround time, waiting time and response time
For each process, using the Gantt chart:
- Completion time (CT): when the process finishes its burst.
- Turnaround time (TAT) = completion time − arrival time. The total time from arrival to finish.
- Waiting time (WT) = turnaround time − burst time. The time spent ready but not running.
- Response time (RT) = time of first run − arrival time. How long before the process got the CPU at all.
Average each one over all processes to compare algorithms. For non-preemptive algorithms the response time equals the waiting time, because a process that starts runs to the end. For preemptive ones it can be much lower, which is the point of round robin.
First come, first served (FCFS)
FCFS runs processes in the order they arrive, each to completion. It is the simplest algorithm, a plain queue, and is fair in the sense that no process is overtaken. Its weakness is the convoy effect: one long process at the front makes every short process behind it wait. In the convoy workload, three processes of 24, 3 and 3 units arrive together; FCFS gives an average waiting time of 17 units, and running the two short ones first gives 3.
FCFS is non-preemptive, so it is a poor fit for interactive systems, where a long computation would freeze everything else. It survives inside other schedulers, for example as the policy within one priority level.
Shortest job first (SJF) and shortest remaining time first (SRTF)
SJF picks the ready process with the shortest burst and runs it to completion. When all processes are available at the start, it gives the lowest possible average waiting time: moving a short job ahead of a long one reduces the short job's wait by more than it increases the long one's.
SRTF, also called preemptive SJF, applies the same rule whenever a process arrives: if the newcomer needs less time than the running process has left, it takes over. It does at least as well as SJF on average waiting time, with more context switches.
Both have two problems. The scheduler cannot know how long a burst will be; real systems estimate it from past bursts, typically with an exponential average, τn+1 = α·tn + (1 − α)·τn, where tn is the last burst and τn the previous estimate. And a long process can starve if short ones keep arriving.
Round robin (RR)
Round robin is FCFS with a timer. Each process runs for at most one time quantum (also called a time slice); if it has not finished, it goes to the back of the ready queue and the next process runs. Every ready process gets a turn within (n − 1) × quantum time units, so response time is good and no process starves.
The quantum decides how round robin behaves. A very large quantum turns it into FCFS. A very small one gives each process a sliver of CPU in turn but spends more and more time switching between them: each context switch saves and restores registers, and the next process starts with cold caches. A common rule of thumb is to make the quantum longer than most CPU bursts, so most processes finish or block within one. Real systems use slices of a few milliseconds, while a context switch costs on the order of microseconds.
Round robin usually has a worse average turnaround time than SJF, because every process is held back by everyone else's turns, but a much better average response time. The table in the simulator shows both.
Priority scheduling
Priority scheduling runs the ready process with the highest priority. In this simulator and most textbooks, a lower number means a higher priority (Linux nice values work the same way; some systems use the opposite). The non-preemptive version waits for the running process to finish; the preemptive version switches as soon as a higher-priority process arrives. SJF is a special case where the priority is the burst length.
The risk is starvation: low-priority processes can wait indefinitely while higher-priority work keeps arriving. The standard fix is aging, slowly raising the priority of processes that have waited a long time. A related problem, priority inversion, happens when a high-priority process waits for a lock held by a low-priority one that cannot run because medium-priority processes keep the CPU. The Mars Pathfinder lander hit this in 1997, and its VxWorks system was fixed by turning on priority inheritance.
CPU scheduling example, worked out
The simulator's default workload has five processes. Round robin uses a quantum of 2.
| Process | Arrival | Burst | Priority |
|---|---|---|---|
| P1 | 0 | 8 | 3 |
| P2 | 1 | 4 | 1 |
| P3 | 2 | 9 | 4 |
| P4 | 3 | 5 | 2 |
| P5 | 4 | 2 | 5 |
The Gantt chart for each algorithm, written out as process, start and end:
| Algorithm | Gantt chart | Avg waiting | Avg turnaround | Avg response |
|---|---|---|---|---|
| First come, first served | P1 0–8, P2 8–12, P3 12–21, P4 21–26, P5 26–28 | 11.4 | 17 | 11.4 |
| Shortest job first | P1 0–8, P5 8–10, P2 10–14, P4 14–19, P3 19–28 | 8.2 | 13.8 | 8.2 |
| Shortest remaining time first | P1 0–1, P2 1–5, P5 5–7, P4 7–12, P1 12–19, P3 19–28 | 6.6 | 12.2 | 4.4 |
| Round robin | P1 0–2, P2 2–4, P3 4–6, P1 6–8, P4 8–10, P5 10–12, P2 12–14, P3 14–16, P1 16–18, P4 18–20, P3 20–22, P1 22–24, P4 24–25, P3 25–28 | 13 | 18.6 | 2.8 |
| Priority (non-preemptive) | P1 0–8, P2 8–12, P4 12–17, P3 17–26, P5 26–28 | 10.6 | 16.2 | 10.6 |
| Priority (preemptive) | P1 0–1, P2 1–5, P4 5–10, P1 10–17, P3 17–26, P5 26–28 | 9.6 | 15.2 | 7.8 |
Shortest remaining time first has the lowest average waiting time here, 6.6 units, and round robin the lowest average response time, 2.8. The round robin schedule in detail, time unit by time unit, with the ready queue after each decision:
| Time | What happens | Runs | Ready queue |
|---|---|---|---|
| 0 | P1 arrives; P1 starts running | P1 | – |
| 1 | P2 arrives | P1 | P2 |
| 2 | P3 arrives; P1's quantum of 2 is used up; it goes to the back of the queue; P2 starts running | P2 | P3, P1 |
| 3 | P4 arrives | P2 | P3, P1, P4 |
| 4 | P5 arrives; P2's quantum of 2 is used up; it goes to the back of the queue; P3 starts running | P3 | P1, P4, P5, P2 |
| 6 | P3's quantum of 2 is used up; it goes to the back of the queue; P1 starts running | P1 | P4, P5, P2, P3 |
| 8 | P1's quantum of 2 is used up; it goes to the back of the queue; P4 starts running | P4 | P5, P2, P3, P1 |
| 10 | P4's quantum of 2 is used up; it goes to the back of the queue; P5 starts running | P5 | P2, P3, P1, P4 |
| 12 | P2 starts running | P2 | P3, P1, P4 |
| 14 | P3 starts running | P3 | P1, P4 |
| 16 | P3's quantum of 2 is used up; it goes to the back of the queue; P1 starts running | P1 | P4, P3 |
| 18 | P1's quantum of 2 is used up; it goes to the back of the queue; P4 starts running | P4 | P3, P1 |
| 20 | P4's quantum of 2 is used up; it goes to the back of the queue; P3 starts running | P3 | P1, P4 |
| 22 | P3's quantum of 2 is used up; it goes to the back of the queue; P1 starts running | P1 | P4, P3 |
| 24 | P4 starts running | P4 | P3 |
| 25 | P3 starts running | P3 | – |
| 27 | P3's quantum of 2 is used up; it goes to the back of the queue; P3 starts running | P3 | – |
And the per-process result for round robin:
| Process | Completion | Turnaround (CT − AT) | Waiting (TAT − BT) | Response |
|---|---|---|---|---|
| P1 | 24 | 24 − 0 = 24 | 24 − 8 = 16 | 0 |
| P2 | 14 | 14 − 1 = 13 | 13 − 4 = 9 | 1 |
| P3 | 28 | 28 − 2 = 26 | 26 − 9 = 17 | 2 |
| P4 | 25 | 25 − 3 = 22 | 22 − 5 = 17 | 5 |
| P5 | 12 | 12 − 4 = 8 | 8 − 2 = 6 | 6 |
| Average | 18.6 | 13 | 2.8 |
The algorithms compared
| Algorithm | Preemptive | Strength | Weakness |
|---|---|---|---|
| FCFS | No | Simple; no starvation | Convoy effect; poor response time |
| SJF | No | Lowest average waiting time when all jobs are present | Needs burst lengths; long jobs can starve |
| SRTF | Yes | Lowest average waiting time with arrivals | Needs burst lengths; starvation; more switches |
| Round robin | Yes | Good response time; fair | Higher turnaround; depends on the quantum |
| Priority | Either | Important work first | Starvation without aging; priority inversion |
Multilevel queues and multilevel feedback queues
Real workloads mix interactive programs, which run briefly and wait for input, with batch jobs that compute for a long time. A multilevel queue keeps a separate queue per class, each with its own algorithm, such as round robin for interactive processes and FCFS for batch jobs, and a fixed priority between the queues.
A multilevel feedback queue (MLFQ) lets processes move between queues based on how they behave. A process that uses its whole time slice is moved down to a lower-priority queue with a longer slice; one that gives up the CPU early, typically to wait for I/O, stays high. Short and interactive jobs therefore get quick service without the scheduler knowing burst lengths in advance, and periodically moving every process back to the top prevents starvation. Fernando Corbató's CTSS used this idea in 1962, and it shaped the schedulers of many later systems.
How Linux and Windows schedule
Linux has several scheduling classes. Real-time threads use SCHED_FIFO (priority-based, run until they block) or SCHED_RR (the same with a time slice), and always run before normal threads. Normal threads were scheduled by the O(1) scheduler in the early 2.6 kernels, then by the Completely Fair Scheduler (CFS), written by Ingo Molnar and merged in 2.6.23 in 2007. CFS tracks each thread's virtual runtime, the CPU time it has used scaled by its nice value, keeps runnable threads in a red-black tree ordered by it, and always runs the one with the least. In kernel 6.6, in 2023, CFS was replaced by EEVDF (earliest eligible virtual deadline first), based on a 1995 paper by Ion Stoica and Hussein Abdel-Wahab, which keeps the fairness and improves latency for threads that need the CPU soon.
Windows uses preemptive priority scheduling with 32 priority levels, round robin within each level, and temporary priority boosts for threads that were waiting on input or I/O, which keeps interactive programs responsive.
On multi-core machines each core has its own run queue, and the scheduler also balances load between cores while trying to keep a thread on the core whose caches already hold its data.
CPU scheduling in exams and interviews
Exam questions usually give a table of processes and ask for the Gantt chart and the average waiting and turnaround times under one or more algorithms. To get them right:
- Draw the time line and mark every arrival.
- At every arrival, completion and, for round robin, end of quantum, decide what runs next using the algorithm's rule. Write down the ready queue at each of these moments.
- Check the convention for ties, especially in round robin when an arrival and a preemption happen at the same time. This simulator puts the new arrival first, as most textbooks do.
- Fill in completion times from the chart, then compute TAT = CT − AT and WT = TAT − BT for each process, and average them.
Interview questions for systems roles are more practical: what a context switch costs, how Linux decides which thread runs, how nice values and CPU limits in containers (cgroups) affect a process, and why a busy-waiting thread hurts others on the same core.
CPU scheduling questions and answers
What is CPU scheduling?
CPU scheduling is how an operating system decides which ready process or thread runs on a CPU next, and for how long. The part of the kernel that makes this choice is the scheduler. A good scheduler keeps the CPU busy, finishes work quickly, responds fast to interactive programs, and treats processes fairly.
How do you calculate turnaround time and waiting time?
Turnaround time is completion time minus arrival time. Waiting time is turnaround time minus burst time, the time spent ready but not running. Response time is the time the process first runs minus its arrival time. Averages are taken over all processes.
Which CPU scheduling algorithm is the best?
None is best for everything. Shortest job first gives the lowest average waiting time when burst lengths are known, but they rarely are and long jobs can starve. Round robin gives good response time and fairness at the cost of more context switches. Real operating systems combine ideas, using priorities, time slices and feedback about how processes behave.
What is the difference between preemptive and non-preemptive scheduling?
In non-preemptive scheduling, a process keeps the CPU until it finishes or blocks. In preemptive scheduling, the operating system can take the CPU away, for example when a time slice runs out or a higher-priority process becomes ready. FCFS, SJF and non-preemptive priority are non-preemptive; SRTF, round robin and preemptive priority are preemptive.
What is the convoy effect?
Under first come, first served, one long process at the front of the queue makes every short process behind it wait, like cars stuck behind a slow truck. Average waiting time can be much higher than if the short processes ran first.
How do you choose the time quantum in round robin?
A quantum that is too long makes round robin behave like FCFS; one that is too short spends a large share of time on context switches. A common rule of thumb is to make it longer than most CPU bursts, so that most processes finish or block within one quantum. Real systems use slices of a few milliseconds.
What is starvation and how does aging prevent it?
Starvation is when a ready process never runs because others keep being chosen first, as can happen to long jobs under SJF or to low-priority processes under priority scheduling. Aging gradually raises the priority of processes that have waited a long time, so every process eventually runs.
What scheduler does Linux use?
Since kernel 6.6, released in 2023, Linux schedules normal tasks with EEVDF (earliest eligible virtual deadline first), which replaced the Completely Fair Scheduler used since 2.6.23 in 2007. Both keep runnable tasks in a red-black tree ordered by how much CPU time they have had, weighted by nice value. Real-time tasks use the separate SCHED_FIFO and SCHED_RR policies.
Further reading
- Arpaci-Dusseau, OSTEPScheduling: IntroductionFCFS, SJF, STCF and round robin from first principles; free online.
- Arpaci-Dusseau, OSTEPScheduling: The Multi-Level Feedback QueueHow MLFQ learns which jobs are interactive.
- Linux kernel documentationCFS SchedulerVirtual runtime and the red-black tree.
- Linux kernel documentationEEVDF SchedulerThe scheduler that replaced CFS in Linux 6.6.
- Microsoft documentationScheduling prioritiesWindows' 32 priority levels and how threads get them.
- SemicolonyGo scheduler simulatorScheduling goroutines onto threads, one level above the kernel.