Frontend Labs
⋯

Chapter 5 — Process states and the process lifecycle

In one sentence

At any moment, every process is in exactly one of a handful of states — running, ready to run, waiting on something, stopped, or dead-but-unclaimed — and reading those states off ps/top is the single fastest way to diagnose "what is this process actually doing right now."

Why this matters

"The process is using 0% CPU but the request is hanging" and "the process shows 100% CPU and won't respond" are DIFFERENT problems with different causes, and the process state tells you which one you're looking at before you dig any deeper.

How it actually works

   THE CORE STATES (Linux ps/top codes in parentheses):
     RUNNING (R)          actually executing on a CPU right now, OR
                          ready and waiting for the scheduler to give it
                          a turn (both are shown as "R" -- "runnable").
     SLEEPING /
     INTERRUPTIBLE (S)     waiting for something (input, a timer, a lock)
                          and CAN be woken early by a signal. This is
                          the state of almost every idle, well-behaved
                          process on your machine right now.
     UNINTERRUPTIBLE
     SLEEP (D)             waiting for something -- usually disk or
                          network I/O -- and CANNOT be interrupted, not
                          even by SIGKILL, until the I/O completes or
                          times out. A process stuck here for a long
                          time is one of the most frustrating real
                          production problems (see below).
     STOPPED (T)           paused deliberately (Ctrl-Z, or SIGSTOP) --
                          not running, not scheduled, just frozen until
                          resumed (SIGCONT).
     ZOMBIE (Z)            finished running; just waiting for its parent
                          to collect its exit status (Chapter 3).

   THE TRANSITIONS, roughly:
     new process -> RUNNING (well, "runnable" -- waiting its turn)
     RUNNING -> SLEEPING     (it asked for I/O, or called sleep())
     SLEEPING -> RUNNING     (the thing it was waiting for happened)
     RUNNING -> STOPPED      (a stop signal arrived)
     STOPPED -> RUNNING      (a continue signal arrived)
     RUNNING -> ZOMBIE       (it exited)
     ZOMBIE -> gone          (the parent called wait())

Real-world example

   Uninterruptible sleep (D state) is a well-known, recurring real
   operations headache, especially with NETWORK-ATTACHED STORAGE (NFS
   being the classic case, but any slow/unresponsive block storage can
   trigger it). If an NFS server becomes unreachable while a process is
   mid-read, that process can enter D state waiting for the I/O to
   complete -- and by design, the kernel won't interrupt an in-flight I/O
   operation for signal delivery, INCLUDING SIGKILL. The process becomes
   completely unkillable until the I/O either completes or the mount
   itself times out. This is documented extensively in sysadmin/SRE
   folklore and vendor knowledge bases (NetApp, Red Hat, and others all
   have support articles specifically about "D state process won't die")
   precisely because it's such a common, confusing real incident: `kill
   -9` visibly does nothing, and the only real fixes are waiting out the
   storage timeout or, in the worst case, rebooting the box.

Try it yourself

# Watch a process sleep (S) vs run (R)
sleep 30 &                 # background it
ps -o pid,stat,cmd -p $!   # STAT column shows S

yes > /dev/null &
ps -o pid,stat,cmd -p $!   # STAT column shows R
kill %1 %2                 # clean up both background jobs

# Watch STOPPED and CONT in real time
sleep 100 &
kill -STOP %1; ps -o pid,stat,cmd -p $!   # T
kill -CONT %1; ps -o pid,stat,cmd -p $!   # back to S
kill %1

Common mistakes

  • "0% CPU means it's not doing anything." It might be doing plenty of work — just work that involves WAITING (on disk, network, a lock), not crunching numbers. Check the state, not just the CPU percentage.
  • Panicking at a D-state process immediately. Brief D states are completely normal (any disk read passes through it briefly). It's only a problem when a process is STUCK there for an extended period.
  • Trying kill -9 repeatedly on a D-state process. It won't work, by design — SIGKILL cannot interrupt uninterruptible sleep. Find and fix the underlying I/O problem instead.

Check yourself

  1. List the core process states and what each one means.
  2. Why can't kill -9 stop a process stuck in D state?
  3. Given "the process shows 0% CPU and the request is hanging," what's your first diagnostic step?

Further reading

  • Reference: man 1 ps (the "PROCESS STATE CODES" section) — the authoritative list for your system.
  • Book (free): OSTEP, "Process API" and "Scheduling" chapters.
  • Article: search "linux D state process troubleshooting" for current, practical writeups — this remains one of the most commonly searched real ops problems.

Generated from real-life-os-guide.md · 8 Oct 2026 16:36