Operating Systems
📂 Scheduling Algorithm
· 1 of 5
34 min read
FCFS Scheduling — Step-Wise Animated Numericals
Master First-Come-First-Served CPU scheduling with four fully-worked numericals, each accompanied by a step-wise animated Gantt chart. Watch the chart get built block-by-block while a live narrator explains every dispatch decision. Covers the algorithm, all four metrics (CT, TAT, WT, RT), the notorious convoy effect, CPU idle handling, a Python implementation, plus advantages, disadvantages, and where FCFS still makes sense today.
Section 01
The Story That Explains FCFS
📖 Real World Analogy
The Bank Teller Queue
Walk into any bank. There is one teller and a rope-line snaking in front of the counter. The rule is simple, ancient, and fair: whoever joins the line first gets served first. No skipping, no priority, no shortcuts. If the person at the front is depositing 500 coins one by one, everyone behind them waits — even the customer with a 30-second cheque deposit.
That is First-Come, First-Served (FCFS). The CPU is the teller. Processes are customers. Arrival time is the moment they joined the rope-line. And nobody — nobody — jumps the queue.
FCFS is the oldest and simplest CPU scheduling algorithm. Galvin introduces it first because it is easy to understand, easy to implement, and provides a clear baseline for comparing every other algorithm. Its logic fits in one line: dispatch processes in the order they arrived at the ready queue.
🎯
The Core Insight
FCFS is non-preemptive: once a process gets the CPU, it keeps it until it voluntarily releases it (by finishing or issuing I/O). No timer interrupt, no priority steal — just pure "you arrived first, you go first".
Section 02
How FCFS Works — The Algorithm
🔄 FCFS Algorithm — Six Simple Steps
Step 1
Maintain the ready queue as a FIFO queue (first-in-first-out) — a simple linked list.
Step 2
When a new process arrives, append its PCB to the tail of the ready queue.
Step 3
When the CPU becomes free, remove the process at the head of the ready queue.
Step 4
Dispatch that process — it runs until it finishes or blocks on I/O. No preemption.
Step 5
If the process finishes, go back to Step 3 and pick the next one.
Step 6
If the process blocks on I/O, put it in the waiting queue. When I/O completes, it re-enters the tail of the ready queue.
Characteristics of FCFS
🔒
Non-Preemptive
No interrupts
Once dispatched, a process holds the CPU until it voluntarily releases it. Even higher-priority arrivals must wait.
⚖️
Fair
FIFO order
Every process runs in arrival order. No process starves — you will eventually get the CPU.
🛠️
Trivial to Implement
One linked list
A single FIFO queue is all the data structure you need. Enqueue and dequeue are O(1).
Section 03
The Metrics — What We Compute
Before touching numericals, memorise these four formulas. Every FCFS problem in Galvin asks for these.
Completion Time
CT = start + burst
The instant a process finishes running on the CPU.
Turnaround Time
TAT = CT − AT
Total time from arrival to completion.
Waiting Time
WT = TAT − BT
Time spent sitting in the ready queue (not running, not doing I/O).
Response Time
RT = start − AT
Time from arrival until first execution on CPU. For non-preemptive FCFS, RT == WT.
🔑
FCFS Shortcut
In FCFS, once a process starts, it runs to completion. So Response Time equals Waiting Time — a process starts running the moment its wait ends.
Section 04
Numerical 1 — Basic FCFS (All Arrive At t=0)
Problem: Three processes arrive at time 0. Compute completion time, turnaround time, waiting time, response time, and averages.
Process
Arrival Time (AT)
Burst Time (BT)
P1
0
10
P2
0
5
P3
0
8
Step-Wise Animated Gantt Chart Construction
Watch The Gantt Chart Get Built Block by Block
The Gantt chart builds live, block by block, with a step-by-step narrator explaining each dispatch decision.
Solution Table
Process
AT
BT
Start
CT
TAT = CT−AT
WT = TAT−BT
RT = Start−AT
P1
0
10
0
10
10
0
0
P2
0
5
10
15
15
10
10
P3
0
8
15
23
23
15
15
Averages
16.00
8.33
8.33
FINAL ANSWERS
Average Turnaround Time = 16.00 ms
Average Waiting Time = 8.33 ms
Average Response Time = 8.33 ms
CPU Utilization = 100% (no idle time)
Throughput = 3 / 23 = 0.130 processes / ms
Section 05
Numerical 2 — Different Arrival Times
Problem: Four processes arrive at different times. Compute all metrics.
Process
Arrival Time (AT)
Burst Time (BT)
P1
0
6
P2
2
4
P3
4
2
P4
6
3
Step-Wise Reasoning
01
t=0 — P1 arrives, CPU free
Ready queue: [P1]. Dispatch P1. It will run 0 → 6 (burst = 6).
Watch each block appear in real time as its process is dispatched. The narrator explains each step.
Solution Table
Process
AT
BT
Start
CT
TAT
WT
RT
P1
0
6
0
6
6
0
0
P2
2
4
6
10
8
4
4
P3
4
2
10
12
8
6
6
P4
6
3
12
15
9
6
6
Averages
7.75
4.00
4.00
FINAL ANSWERS
Average Turnaround Time = 7.75 ms
Average Waiting Time = 4.00 ms
Average Response Time = 4.00 ms
CPU Utilization = 15/15 = 100%
Throughput = 4 / 15 = 0.267 jobs / ms
Section 06
Numerical 3 — The Convoy Effect
Now watch FCFS's fatal flaw in action. When one long CPU-bound process arrives just before many short I/O-bound ones, everyone piles up behind it — like cars stuck behind a slow truck.
Process
AT
BT
Type
P1
0
100
CPU-bound (long)
P2
1
1
I/O-bound (short)
P3
2
1
I/O-bound (short)
P4
3
1
I/O-bound (short)
Animated Convoy Effect
Watch The Convoy Form Behind P1
P1 hogs the CPU. Three tiny jobs, each finishable in 1 ms, pile up behind — that is the convoy effect.
🚙
The Convoy Effect Explained
One long process at the head of the queue makes many short processes wait far longer than their own execution time. Total system throughput crashes and average waiting time explodes. This is FCFS's biggest weakness — and the whole motivation for algorithms like SJF and Round Robin.
Section 07
Advantages & Disadvantages
👍 Advantages
Simplest scheduling algorithm — one FIFO queue
Fair in the strict FIFO sense — no starvation
Very low scheduling overhead (O(1) per dispatch)
Easy to reason about — predictable order
Great baseline for comparing other algorithms
👎 Disadvantages
Convoy effect — short jobs wait behind long ones
Poor average waiting time on mixed workloads
Terrible for interactive users — no priority
Non-preemptive — cannot respond to urgency
CPU and I/O device utilization drop when convoys form
Section 08
Python Implementation
from dataclasses import dataclass
from typing import List
@dataclass
class Process:
pid: str
arrival: int
burst: int
start: int = -1
completion: int = -1deffcfs(procs: List[Process]) -> List[Process]:
# Sort by arrival time to enforce FIFO order
procs = sorted(procs, key=lambda p: p.arrival)
clock = 0for p in procs:
# If CPU idle, jump clock forward to next arrival
clock = max(clock, p.arrival)
p.start = clock
p.completion = clock + p.burst
clock = p.completion
return procs
defreport(procs: List[Process]) -> None:
print(f"{'PID':<4} {'AT':>4} {'BT':>4} {'CT':>4} {'TAT':>4} {'WT':>4} {'RT':>4}")
tat_total = wt_total = rt_total = 0for p in procs:
tat = p.completion - p.arrival
wt = tat - p.burst
rt = p.start - p.arrival
tat_total += tat; wt_total += wt; rt_total += rt
print(f"{p.pid:<4} {p.arrival:>4} {p.burst:>4} {p.completion:>4} {tat:>4} {wt:>4} {rt:>4}")
n = len(procs)
print(f"\nAvg TAT = {tat_total/n:.2f}")
print(f"Avg WT = {wt_total/n:.2f}")
print(f"Avg RT = {rt_total/n:.2f}")
# --- Run Numerical 2 ---
workload = [
Process("P1", 0, 6),
Process("P2", 2, 4),
Process("P3", 4, 2),
Process("P4", 6, 3),
]
report(fcfs(workload))
Numbers match our hand-calculation from Numerical 2 exactly. This tiny function is the entire FCFS algorithm — a stark reminder of how simple it really is.
Section 09
Numerical 4 — With CPU Idle Time
Watch out: if all processes have not yet arrived when the CPU is free, it sits idle. This affects CPU utilization.
Process
AT
BT
P1
0
3
P2
5
4
P3
10
2
Step-Wise Solution
📌 Timeline
t=0-3
P1 runs. CT(P1)=3, WT(P1)=0.
t=3-5
CPU IDLE! No process is ready. 2 ms of wasted time.
t=5-9
P2 arrives at t=5, dispatched immediately. CT(P2)=9, WT(P2)=0.
t=9-10
CPU IDLE again! P3 hasn't arrived. 1 ms wasted.
t=10-12
P3 arrives and runs. CT(P3)=12, WT(P3)=0.
Gantt Chart With Idle Gaps
Grey dashed blocks are CPU idle time. FCFS cannot fill them — it must wait for the next arrival.
Process
AT
BT
CT
TAT
WT
P1
0
3
3
3
0
P2
5
4
9
4
0
P3
10
2
12
2
0
Averages
3.00 ms
0.00 ms
—
FINAL ANSWERS
Avg TAT = 3.00 ms
Avg WT = 0.00 ms (best case!)
CPU Utilization = 9 / 12 = 75%
Throughput = 3 / 12 = 0.25 jobs / ms
Total Idle Time = 3 ms (t=3-5 and t=9-10)
Section 10
When Is FCFS a Good Choice?
✅
Batch Systems
Overnight billing, payroll, scientific number-crunching. Nobody is watching interactively; fairness by arrival is fine.
Legacy mainframes
✅
Uniform Workloads
All jobs have roughly similar burst times. No convoy can form because no job is dramatically longer than the rest.
Homogeneous workers
✅
Simple Embedded Devices
Microcontrollers running a few known tasks in a fixed order. FCFS is dead simple and needs almost no code.
Low-memory MCUs
❌
Interactive Systems
Desktops, phones, laptops — one long job at the queue head freezes the UI. Never use pure FCFS here.
Bad UX guaranteed
❌
Time-Sharing Systems
Many users, mixed workloads. FCFS's convoy effect turns quick jobs into slow jobs. Use Round Robin instead.
Convoy effect kills
❌
Real-Time Systems
Safety-critical deadlines. FCFS gives no priority guarantee — a long low-priority job can miss a critical deadline.
Deadline unsafe
Section 11
Golden Rules
📚 FCFS Scheduling — Non-Negotiable Rules
1
Order is arrival time. If two processes arrive at the exact same time, break ties by PID (or by problem statement). Never re-order for any other reason.
2
FCFS is non-preemptive. Once a process starts, it holds the CPU until it finishes or blocks. New arrivals — however urgent — wait their turn.
3
Response Time equals Waiting Time in FCFS, because a process runs to completion the moment it starts. No preemption means no gap between start and continuous execution.
4
Compute in this order: CT → TAT → WT → RT. Draw the Gantt chart first, then the table. Mistakes come from doing table arithmetic before the chart.
5
Watch for idle CPU time. If the next process's arrival time is greater than the current clock, jump the clock forward — the CPU sat idle. This lowers CPU utilization but keeps WT at 0 for that process.
6
Beware the convoy effect. One long process at the head blows up average waiting time for everyone else. If your Gantt chart shows a huge first block followed by tiny slivers, expect terrible average WT.
7
FCFS never starves — every process eventually runs. This alone makes it a valid baseline algorithm. When Galvin asks "which algorithm never starves?", FCFS is one of the safe answers.