The Story That Explains Round-Robin
No child is favoured. No child is starved. Everyone gets a fair, predictable slice. Yes, it's slower than letting one child ride until they're done — but nobody cries, and the system feels responsive to every child.
That, in one image, is Round-Robin Scheduling. Swap "children" for "processes" and "2 minutes on the swing" for a time quantum, and you have the algorithm that powers every timesharing operating system on Earth.
Round-Robin (RR) is the CPU scheduling algorithm designed specifically for time-sharing systems. It is essentially preemptive FCFS with a time limit. Each process gets a fixed slice of CPU time called the time quantum (or time slice). When the quantum expires, the process is preempted and moved to the tail of the ready queue, and the next process is dispatched.
Round-Robin Scheduling allocates CPU to each ready process in circular order for a fixed time quantum q. If a process's CPU burst ≤ q, it finishes and leaves. Otherwise, after q units it is preempted by a timer interrupt and placed at the tail of the ready queue. No priorities. No favouritism. Pure fair-share.
Why Round-Robin Exists — The Timesharing Problem
Before RR, systems used FCFS (First-Come-First-Served). A single long-running job could hog the CPU for hours while everyone else waited. As soon as multiple users had to share one computer interactively, this became unbearable. RR was invented to make every user feel like they had the computer to themselves.
| Time | What User Sees |
|---|---|
| 0 s | Job A starts a 10-min computation |
| 1 s | User B types a command → ignored |
| 2 s | User C tries to save a file → frozen |
| ... | Everyone waits 10 minutes for A |
| 600 s | Finally A finishes, B runs, then C |
| Time | What User Sees |
|---|---|
| 0 ms | Job A gets 100ms |
| 100 ms | User B's command runs in 100ms |
| 200 ms | User C's save runs in 100ms |
| 300 ms | Back to A, then rotate again |
| ... | Every user feels <0.3s response |
Round-Robin trades throughput for responsiveness. No single process finishes faster than in FCFS, but every process gets to start quickly. This is why RR is the foundation of every interactive operating system since UNIX.
Key Terms & The Time Quantum
The Ready Queue — A Circular FIFO
The ready queue in Round-Robin is a FIFO circular queue. The scheduler picks from the head, and preempted or newly-arrived processes go to the tail. Understanding this ordering is the single most common source of exam mistakes.
If a running process's quantum ends at the same time a new process arrives, most textbooks (Galvin included) treat the new arrival as entering the queue first, then the preempted process is appended after it. Get this rule wrong and your entire Gantt chart shifts. State the assumption in exam solutions.
Numerical 1 — Basic Round-Robin, Same Arrival
We'll start with the simplest case: all processes arrive at t=0. Time quantum q = 2.
| Process | Arrival Time | Burst Time |
|---|---|---|
| P1 | 0 | 5 |
| P2 | 0 | 3 |
| P3 | 0 | 8 |
| P4 | 0 | 6 |
Step-by-Step Queue Evolution (q = 2)
Animated Gantt Chart (q = 2)
Final Metrics Table
| Process | AT | BT | CT | TAT = CT − AT | WT = TAT − BT |
|---|---|---|---|---|---|
| P1 | 0 | 5 | 16 | 16 | 11 |
| P2 | 0 | 3 | 11 | 11 | 8 |
| P3 | 0 | 8 | 22 | 22 | 14 |
| P4 | 0 | 6 | 20 | 20 | 14 |
Avg TAT = (16 + 11 + 22 + 20) / 4 = 69 / 4 = 17.25 ms
Avg WT = (11 + 8 + 14 + 14) / 4 = 47 / 4 = 11.75 ms
Numerical 2 — Different Arrival Times (q = 2)
Now the tricky case that trips up students: processes arrive at different times. We must decide whether new arrivals or preempted processes go into the queue first. Rule: new arrival is enqueued before the preempted process at the same instant.
| Process | Arrival Time | Burst Time |
|---|---|---|
| P1 | 0 | 4 |
| P2 | 1 | 5 |
| P3 | 2 | 2 |
| P4 | 4 | 1 |
| P5 | 6 | 2 |
Animated Gantt Chart with Arrival Markers
Final Table
| Process | AT | BT | CT | TAT | WT |
|---|---|---|---|---|---|
| P1 | 0 | 4 | 8 | 8 | 4 |
| P2 | 1 | 5 | 14 | 13 | 8 |
| P3 | 2 | 2 | 6 | 4 | 2 |
| P4 | 4 | 1 | 9 | 5 | 4 |
| P5 | 6 | 2 | 13 | 7 | 5 |
Avg TAT = (8 + 13 + 4 + 5 + 7) / 5 = 37 / 5 = 7.4 ms
Avg WT = (4 + 8 + 2 + 4 + 5) / 5 = 23 / 5 = 4.6 ms
The Time Quantum — Small vs Large
The single most important design decision in Round-Robin is the value of the time quantum q. Get it wrong and RR degenerates into something worse than what it replaced.
Numerical 3 — Same Workload, Two Different Quanta
Let's see the effect of quantum choice on the same workload. Processes: P1 (AT=0, BT=6), P2 (AT=0, BT=3), P3 (AT=0, BT=1), P4 (AT=0, BT=7).
| Process | CT | TAT | WT |
|---|---|---|---|
| P1 | 15 | 15 | 9 |
| P2 | 9 | 9 | 6 |
| P3 | 3 | 3 | 2 |
| P4 | 17 | 17 | 10 |
| Avg | — | 11.0 | 6.75 |
| Process | CT | TAT | WT |
|---|---|---|---|
| P1 | 15 | 15 | 9 |
| P2 | 7 | 7 | 4 |
| P3 | 8 | 8 | 7 |
| P4 | 17 | 17 | 10 |
| Avg | — | 11.75 | 7.5 |
Same processes, same total work — but average waiting time changed. Small q gives better response time for short processes (P3 finished at t=3 with q=1 versus t=8 with q=4). But small q means more context switches — the overhead in real systems can dominate. This is why real operating systems tune q carefully, typically matching it to typical burst distribution.
Context Switch Overhead — The Hidden Cost
Textbook numericals usually ignore context switching. Real systems can't. A context switch requires saving all CPU registers, program counter, memory map pointers, and cache invalidation. On modern hardware this costs roughly 1–10 microseconds per switch.
If context switch takes s time units and quantum is q units, then useful CPU utilisation is U = q / (q + s). For q=1, s=1 → U = 50%. For q=10, s=1 → U = 91%. For q=100, s=1 → U = 99%. This is why real quanta are ~100× the context-switch cost.
Turnaround Time vs Quantum — The Rule of 80%
Python Implementation
Complete Round-Robin Simulator
# Round-Robin Scheduling — event-driven simulator
# Convention: new arrival enqueued BEFORE the preempted process at the same instant
from collections import deque
def round_robin(processes, quantum):
# processes: list of dicts { 'pid', 'at', 'bt' }
n = len(processes)
remaining = {p['pid']: p['bt'] for p in processes}
completed = {}
ready = deque()
# Sort processes by arrival time
procs = sorted(processes, key=lambda p: p['at'])
i = 0
t = procs[0]['at']
# Enqueue processes that have arrived at time t
while i < n and procs[i]['at'] <= t:
ready.append(procs[i])
i += 1
while ready:
curr = ready.popleft()
run = min(quantum, remaining[curr['pid']])
start_t = t
t += run
remaining[curr['pid']] -= run
# CRITICAL ORDERING:
# First, enqueue all NEW arrivals that came in during (start_t, t]
while i < n and procs[i]['at'] <= t:
ready.append(procs[i])
i += 1
# Then, if the current process still has work, put it at the tail
if remaining[curr['pid']] > 0:
ready.append(curr)
else:
completed[curr['pid']] = {
'ct': t,
'tat': t - curr['at'],
'wt': (t - curr['at']) - curr['bt'],
}
# If queue is empty but processes remain, jump to next arrival
if not ready and i < n:
t = procs[i]['at']
while i < n and procs[i]['at'] <= t:
ready.append(procs[i])
i += 1
return completed
# Example — Numerical 2
procs = [
{'pid': 'P1', 'at': 0, 'bt': 4},
{'pid': 'P2', 'at': 1, 'bt': 5},
{'pid': 'P3', 'at': 2, 'bt': 2},
{'pid': 'P4', 'at': 4, 'bt': 1},
{'pid': 'P5', 'at': 6, 'bt': 2},
]
result = round_robin(procs, quantum=2)
print("PID CT TAT WT")
for pid in sorted(result):
m = result[pid]
print(f"{pid:3} {m['ct']:3} {m['tat']:4} {m['wt']:3}")
avg_tat = sum(m['tat'] for m in result.values()) / len(result)
avg_wt = sum(m['wt'] for m in result.values()) / len(result)
print(f"\nAvg TAT = {avg_tat:.2f}, Avg WT = {avg_wt:.2f}")
Round-Robin vs Other Scheduling Algorithms
| Feature | Round Robin | FCFS | SJF | Priority |
|---|---|---|---|---|
| Selection Rule | Head of FIFO queue | First arrived | Shortest burst | Highest priority |
| Preemption | Yes (timer) | No | Either variant | Either variant |
| Starvation | Never | Never | Yes (long jobs) | Yes (fix with aging) |
| Response Time | Best (with small q) | Worst | Good for short | Good for high-priority |
| Throughput | Reduced by switches | Highest | High | Depends |
| Fairness | Maximum (equal share) | Only in arrival order | Unfair to long jobs | Unfair to low priority |
| Ideal Use Case | Timesharing / interactive | Batch processing | Batch with known bursts | Real-time systems |
When quantum q → ∞, Round-Robin becomes FCFS. When quantum q → 0, RR approaches the theoretical "processor-sharing" model where all n processes appear to run at 1/n speed simultaneously. Every real system chooses q somewhere between these two extremes.
Advantages & Disadvantages
Real-World Applications
Common Exam Traps & Pitfalls
When a process's quantum expires at the same instant another arrives, put the new arrival first, then the preempted process. Always state this convention explicitly. Different textbooks sometimes flip it.
If a process's remaining burst is less than q, it runs only for that remaining time and completes — the CPU is not idle for the rest of the quantum. The next process starts immediately.
If the ready queue is empty and no process has arrived yet, the CPU sits idle. Fast-forward time to the next arrival — do not include this idle time in any process's waiting time.
Round-Robin does not care about burst length. Do not "optimise" by picking shorter jobs first — that would be SJF. RR is strictly FIFO in the queue.