Homeβ€Ί DSAβ€Ί FCFS Scheduling β€” First Come First Served Algorithm

FCFS Scheduling β€” First Come First Served Algorithm

Where developers are forged. Β· Structured learning Β· Free forever.
πŸ“ Part of: Scheduling β†’ Topic 1 of 4
Learn FCFS (First Come First Served) CPU scheduling.
πŸ§‘β€πŸ’» Beginner-friendly β€” no prior DSA experience needed
In this tutorial, you'll learn:
  • FCFS: sort by arrival, execute in order β€” non-preemptive.
  • Waiting Time = Turnaround Time - Burst Time. Turnaround Time = Completion - Arrival.
  • Convoy effect: short processes wait behind long ones β†’ high average waiting time.
✦ Plain-English analogy ✦ Real code with output ✦ Interview questions
⚑ Quick Answer
FCFS is the simplest scheduling algorithm β€” processes run in the order they arrive, like a queue at a ticket counter. Whoever arrives first gets served first. Simple and fair in principle, but a long process can make everything behind it wait β€” the convoy effect.

FCFS is the algorithm you implement when you have a queue and zero information about job durations. It is fair in the sense that arrival order is respected β€” no process waits longer than all processes that arrived before it. But 'fair' does not mean 'efficient', and the convoy effect makes FCFS genuinely harmful for interactive workloads.

Understanding FCFS matters not for implementing it (it is trivially a FIFO queue) but for understanding what it optimises and what it sacrifices. Every scheduling algorithm trades off fairness, average waiting time, response time, and throughput differently. FCFS optimises arrival-order fairness at the cost of average waiting time. This trade-off analysis is the interview skill being tested.

Algorithm and Metrics

Key metrics: - Completion Time (CT): When the process finishes - Turnaround Time (TAT): CT - Arrival Time - Waiting Time (WT): TAT - Burst Time - Response Time: Time from arrival to first execution (= WT for non-preemptive)

fcfs.py Β· PYTHON
12345678910111213141516171819202122232425262728293031
def fcfs(processes: list[dict]) -> list[dict]:
    """
    processes: list of {pid, arrival, burst}
    Returns processes with ct, tat, wt added.
    """
    # Sort by arrival time
    procs = sorted(processes, key=lambda p: p['arrival'])
    current_time = 0
    results = []
    for p in procs:
        start = max(current_time, p['arrival'])
        ct  = start + p['burst']
        tat = ct - p['arrival']
        wt  = tat - p['burst']
        current_time = ct
        results.append({**p, 'start': start, 'ct': ct, 'tat': tat, 'wt': wt})
    return results

processes = [
    {'pid':'P1','arrival':0,'burst':24},
    {'pid':'P2','arrival':1,'burst':3},
    {'pid':'P3','arrival':2,'burst':3},
]
results = fcfs(processes)
print(f"{'PID':<4} {'AT':>3} {'BT':>3} {'ST':>3} {'CT':>3} {'TAT':>4} {'WT':>4}")
for r in results:
    print(f"{r['pid']:<4} {r['arrival']:>3} {r['burst']:>3} {r['start']:>3} {r['ct']:>3} {r['tat']:>4} {r['wt']:>4}")
avg_tat = sum(r['tat'] for r in results) / len(results)
avg_wt  = sum(r['wt']  for r in results) / len(results)
print(f"\nAverage TAT: {avg_tat:.2f}")
print(f"Average WT:  {avg_wt:.2f}")
β–Ά Output
PID AT BT ST CT TAT WT
P1 0 24 0 24 24 0
P2 1 3 24 27 26 23
P3 2 3 27 30 28 25

Average TAT: 26.00
Average WT: 16.00

The Convoy Effect

In the example above, P2 and P3 each take only 3ms but wait 23ms and 25ms because P1 (24ms) arrived first. This is the convoy effect β€” short processes form a convoy behind a long one.

If we ran P2, P3, P1 instead (SJF order): - P2: WT=0, P3: WT=2, P1: WT=5 - Average WT = 2.33ms vs 16ms for FCFS

This is why FCFS has poor average waiting time for mixed workloads.

⚠️
Convoy EffectFCFS is particularly bad when a CPU-bound process arrives before many I/O-bound processes. The CPU-bound process holds the CPU while I/O-bound processes (which could be doing I/O) wait idle.

Gantt Chart Representation

gantt.py Β· PYTHON
1234567891011
def print_gantt(results: list[dict]) -> None:
    print('Gantt Chart:')
    bar = '|'
    times = '0'
    for r in results:
        bar += f" {r['pid']:^5}|"
        times += f"{r['ct']:>7}"
    print(bar)
    print(times)

print_gantt(results)
β–Ά Output
Gantt Chart:
| P1 | P2 | P3 |
0 24 27 30

🎯 Key Takeaways

  • FCFS: sort by arrival, execute in order β€” non-preemptive.
  • Waiting Time = Turnaround Time - Burst Time. Turnaround Time = Completion - Arrival.
  • Convoy effect: short processes wait behind long ones β†’ high average waiting time.
  • Simple to implement (FIFO queue) but rarely optimal.
  • Best used when all processes have similar burst times or process order must be preserved.

Interview Questions on This Topic

  • QWhat is the convoy effect in FCFS scheduling?
  • QCalculate average waiting time for FCFS with processes P1(AT=0,BT=8), P2(AT=1,BT=4), P3(AT=2,BT=2).
  • QIs FCFS preemptive or non-preemptive? What does that mean?
  • QWhen would you choose FCFS over other scheduling algorithms?

Frequently Asked Questions

Does FCFS cause starvation?

No β€” every process eventually gets the CPU since there is no priority-based preemption. However, average waiting time can be very high (effectively long waits for short processes), which is sometimes confused with starvation.

πŸ”₯
Naren Founder & Author

Developer and founder of TheCodeForge. I built this site because I was tired of tutorials that explain what to type without explaining why it works. Every article here is written to make concepts actually click.

Next β†’SJF Scheduling β€” Shortest Job First
Forged with πŸ”₯ at TheCodeForge.io β€” Where Developers Are Forged