Shortest Remaining Time First (Preemptive SJF) Scheduling Algorithm

Last Updated : 5 Jan, 2026

The pre-emptive version of Shortest Job First (SJF) scheduling is called Shortest Remaining Time First (SRTF). In SRTF, the process with the least time left to finish is selected to run. The running process continues until it finishes or a new process with a shorter remaining time arrives, ensuring the fastest finishing process always gets priority.

Example of SJF Algorithm:

Scenario 1: Processes with Same Arrival Time

Example: Consider the following table of arrival time and burst time for three processes P1, P2 and P3.

ProcessBurst TimeArrival Time
 P1   6 ms0 ms
 P2 8 ms0 ms
 P3 5 ms0 ms

Step-by-Step Execution:

  1. Time 0-5 (P3): P3 runs for 5 ms (total time left: 0 ms) as it has shortest remaining time left.
  2. Time 5-11 (P1): P1 runs for 6 ms (total time left: 0 ms) as it has shortest remaining time left.
  3. Time 11-19 (P2): P2 runs for 8 ms (total time left: 0 ms) as it has shortest remaining time left.

Gantt chart :


Now, lets calculate average waiting time and turn around time:

As we know,

  • Turn Around time = Completion time - arrival time
  • Waiting Time = Turn around time - burst time
Try It Yourself
redirect icon
Process  

Arrival Time

(AT)

Burst Time

(BT)

Completion Time (CT)Turn Around Time (TAT)Waiting Time (WT)
 P1  

0

6

1111-0 = 1111-6 = 5
 P2

0

8

1919-0 = 1919-8 = 11
 P3

0

5

55-0 = 55-5 = 0

Now, 

  • Average Turn around time = (11 + 19 + 5)/3 = 11.6 ms
  • Average waiting time = (5 + 0 + 11 )/3 = 16/3 = 5.33 ms

Scenario 2: Processes with Different Arrival Times

Consider the following table of arrival time and burst time for three processes P1, P2 and P3.

ProcessBurst TimeArrival Time
 P1   6 ms0 ms
 P2 3 ms1 ms
 P3 7 ms2 ms

Step-by-Step Execution:

  1. Time 0-1 (P1): P1 runs for 1 ms (total time left: 5 ms) as it has shortest remaining time left.
  2. Time 1-4 (P2): P2 runs for 3 ms (total time left: 0 ms) as it has shortest remaining time left among P1 and P2.
  3. Time 4-9 (P1): P1 runs for 5 ms (total time left: 0 ms) as it has shortest remaining time left among P1 and P3.
  4. Time 9-16 (P3): P3 runs for 7 ms (total time left: 0 ms) as it has shortest remaining time left.

Gantt chart :

Now, lets calculate average waiting time and turn around time:

Process  

Arrival Time (AT)

Burst Time (BT)

Completion Time (CT)Turn Around Time (TAT)Waiting Time (WT)
 P1  

0

6

99-0 = 99-6 = 3
 P2

1

3

44-1 = 33-3 = 0
 P3

2

7

1616-2 = 1414-7 = 7
  • Average Turn around time = (9 + 14 + 3)/3 = 8.6 ms
  • Average waiting time = (3 + 0 + 7 )/3 = 10/3 = 3.33 ms

Implementation of SRTF Algorithm

Step 1: Input number of processes with arrival time and burst time.
Step 2: Initialize remaining times (burst times), current time = 0, and counters.
Step 3: At each time unit, add processes that have arrived into the ready queue.
Step 4: Select the process with the shortest remaining time (preempt if a shorter one arrives).
Step 5: Execute the selected process for 1 unit, reduce its remaining time, and increment current time.
Step 6: If a process completes:

  • Turnaround Time = Completion Time − Arrival Time
  • Waiting Time = Turnaround Time − Burst Time

Step 7: Repeat Steps 3–6 until all processes complete.
Step 8: Calculate average waiting time and turnaround time.
Step 9: Display completion, waiting, and turnaround times for each process, along with averages.

Code Implementation

Program to implement Shortest Remaining Time First is as follows:

C++
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

struct Process {
    int id, arrivalTime, burstTime, remainingTime, waitingTime, turnaroundTime, completionTime;
};

int main() {
    int n, currentTime = 0, completed = 0;
    cout << "Enter number of processes: ";
    cin >> n;
    vector<Process> p(n);
    
    for (int i = 0; i < n; i++) {
        p[i].id = i + 1;
        cin >> p[i].arrivalTime >> p[i].burstTime;
        p[i].remainingTime = p[i].burstTime;
    }

    while (completed < n) {
        int idx = -1;
        for (int i = 0; i < n; i++) {
            if (p[i].arrivalTime <= currentTime && p[i].remainingTime > 0 && (idx == -1 || p[i].remainingTime < p[idx].remainingTime)) {
                idx = i;
            }
        }
        if (idx != -1) {
            p[idx].remainingTime--;
            currentTime++;
            if (p[idx].remainingTime == 0) {
                p[idx].completionTime = currentTime;
                p[idx].turnaroundTime = currentTime - p[idx].arrivalTime;
                p[idx].waitingTime = p[idx].turnaroundTime - p[idx].burstTime;
                completed++;
            }
        } else {
            currentTime++;
        }
    }

    double totalWT = 0, totalTAT = 0;
    for (auto &proc : p) {
        totalWT += proc.waitingTime;
        totalTAT += proc.turnaroundTime;
        cout << "P" << proc.id << " CT: " << proc.completionTime << " WT: " << proc.waitingTime << " TAT: " << proc.turnaroundTime << endl;
    }
    cout << "Avg WT: " << totalWT / n << " Avg TAT: " << totalTAT / n << endl;
}
Java
import java.util.*;

class Process {
    int id, arrivalTime, burstTime, remainingTime, waitingTime, turnaroundTime, completionTime;

    public Process(int id, int arrivalTime, int burstTime) {
        this.id = id;
        this.arrivalTime = arrivalTime;
        this.burstTime = burstTime;
        this.remainingTime = burstTime;
    }
}

public class SRTF {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        int n = sc.nextInt();
        if (n <= 0) {
            System.out.println("Invalid number of processes.");
            return;
        }

        Process[] processes = new Process[n];

        for (int i = 0; i < n; i++) {
            int arrivalTime = sc.nextInt();
            int burstTime = sc.nextInt();

            if (arrivalTime < 0 || burstTime <= 0) {
                System.out.println("Invalid arrival or burst time for process " + (i + 1));
                return;
            }

            processes[i] = new Process(i + 1, arrivalTime, burstTime);
        }

        Arrays.sort(processes, Comparator.comparingInt(p -> p.arrivalTime));

        int currentTime = 0, completed = 0;

        while (completed < n) {
            int idx = -1;

            for (int i = 0; i < n; i++) {
                if (processes[i].arrivalTime <= currentTime &&
                    processes[i].remainingTime > 0 &&
                    (idx == -1 || processes[i].remainingTime < processes[idx].remainingTime)) {
                    idx = i;
                }
            }

            if (idx != -1) {
                processes[idx].remainingTime--;
                currentTime++;

                if (processes[idx].remainingTime == 0) {
                    processes[idx].completionTime = currentTime;
                    processes[idx].turnaroundTime = currentTime - processes[idx].arrivalTime;
                    processes[idx].waitingTime =
                            processes[idx].turnaroundTime - processes[idx].burstTime;
                    completed++;
                }
            } else {
                currentTime++;
            }
        }

        double totalWT = 0, totalTAT = 0;
        for (Process p : processes) {
            totalWT += p.waitingTime;
            totalTAT += p.turnaroundTime;
            System.out.println("P" + p.id +
                    " CT: " + p.completionTime +
                    " WT: " + p.waitingTime +
                    " TAT: " + p.turnaroundTime);
        }

        System.out.println("Avg WT: " + (totalWT / n));
        System.out.println("Avg TAT: " + (totalTAT / n));
    }
}
Python
class Process:
    def __init__(self, id, arrival_time, burst_time):
        self.id = id
        self.arrival_time = arrival_time
        self.burst_time = burst_time
        self.remaining_time = burst_time

def srtf(processes):
    current_time, completed = 0, 0
    while completed < len(processes):
        idx = -1
        for i, p in enumerate(processes):
            if p.arrival_time <= current_time and p.remaining_time > 0 and (idx == -1 or p.remaining_time < processes[idx].remaining_time):
                idx = i
        if idx != -1:
            processes[idx].remaining_time -= 1
            current_time += 1
            if processes[idx].remaining_time == 0:
                processes[idx].completion_time = current_time
                processes[idx].turnaround_time = current_time - processes[idx].arrival_time
                processes[idx].waiting_time = processes[idx].turnaround_time - processes[idx].burst_time
                completed += 1
        else:
            current_time += 1

def print_results(processes):
    total_wt, total_tat = 0, 0
    for p in processes:
        total_wt += p.waiting_time
        total_tat += p.turnaround_time
        print(f"P{p.id} CT: {p.completion_time} WT: {p.waiting_time} TAT: {p.turnaround_time}")
    print(f"Avg WT: {total_wt / len(processes)} Avg TAT: {total_tat / len(processes)}")

n = int(input("Enter number of processes: "))
processes = [Process(i + 1, *map(int, input(f"Enter arrival and burst time for P{i + 1}: ").split())) for i in range(n)]
srtf(processes)
print_results(processes)

Output
Enter number of processes: Avg WT: -nan Avg TAT: -nan

Advantages of SRTF Scheduling

  • Minimizes average waiting time by always selecting the process with the shortest remaining time.
  • Short processes finish quickly, improving system responsiveness and throughput.
  • Helps time-critical tasks get CPU attention earlier than longer jobs.

Disadvantages of SRTF Scheduling

  • Long processes may suffer starvation if short jobs keep arriving continuously.
  • Accurate prediction of CPU burst time is difficult and often unreliable.
  • Frequent context switching increases overhead and can reduce overall performance.
Comment