Module 03 · Processes and threads · Lesson 1 of 7
Processes
A process is a running program plus everything the kernel tracks for it: an address space, open files, credentials and at least one thread. What the kernel stores per process, how processes are created and isolated, and what they cost.
Why it matters
Every service you deploy is one or more processes. When a container is "out of memory", when a server hits "too many open files", when a crash in one worker does not take down the others, or when a fork bomb takes down a machine, the explanation is in what a process is and what the kernel keeps for each one. It is also the unit of isolation that every higher-level idea, from containers to multi-tenant hosting, builds on.
The idea
A process is a program in execution, together with the resources the operating system has given it. The program is a file on disk; the process is a live instance of it, and you can run many processes from the same program at once, each with its own state. The kernel identifies each by a process ID (PID) and keeps a record of it, often called the process control block.
What a process owns
| Resource | What it is | Where it bites in production |
|---|---|---|
| Virtual address space | A private map of memory: code, data, heap, one stack per thread, shared libraries | Out-of-memory kills, memory leaks, the resident set size you are billed for |
| Threads | At least one; each has its own registers, program counter and stack | Thread count limits, stack memory per thread |
| File descriptors | Small integers naming open files, sockets and pipes | 'Too many open files' when connections or files leak; the per-process limit (often 1,024 by default) |
| Credentials | User and group IDs, capabilities | Permission errors; why services should not run as root |
| Parent and children | Every process has a parent; the kernel keeps the tree | Zombie processes, orphaned workers, process supervisors |
| Limits and accounting | CPU, memory and file limits; CPU time used | ulimit settings, cgroup limits in containers |
Isolation
The defining property of a process is that it cannot directly see or change another process's memory. Each one runs in user mode, where the hardware forbids touching kernel memory or devices, and its addresses are translated through its own page tables, so the same address in two processes points at different physical memory. To do anything beyond computing on its own memory (read a file, send a packet, start another process) it must ask the kernel through a system call, which switches the CPU into kernel mode, checks permissions and does the work. A crash in one process, a bad pointer or an uncaught exception, therefore ends that process and nothing else.
Creating processes
On Unix-like systems, a new process starts as a copy of its parent (fork) and then usually replaces its program with a new one (exec). Copying sounds expensive, but the kernel uses copy-on-write: parent and child share the same physical pages until one of them writes, at which point only that page is copied. Windows creates a process and loads the program in one call. Either way, creating a process costs on the order of a millisecond or less, plus whatever startup the program does, which is why servers create worker processes once at startup rather than per request.
Processes as a design tool
Separate processes give fault isolation (a worker crash does not take down the server), security isolation (a sandboxed renderer cannot read the browser's passwords), and resource accounting (limits and metrics per process). Chrome runs each site in its own process; nginx and Postgres run a pool of worker processes; Kubernetes runs each container as one or more processes. The price is that processes cannot share memory freely, so they communicate through the kernel, which is slower than threads sharing memory, the trade-off explored in the next lesson.
Trade-offs
Processes buy strong isolation and independent failure at the cost of creation time, memory per process and slower communication. A design that uses many processes is robust and easy to reason about; one that crams everything into one process is fast and fragile. Most production systems use a few processes, each with many threads or an event loop, to get some of both.
In an interview
Use processes to talk about blast radius and limits: "Each tenant's job runs in its own process with a memory limit, so a runaway job is killed by the kernel without affecting the others." And when an incident mentions file descriptors: "Every socket is a descriptor; a leak in connection handling hits the per-process limit long before memory runs out."
Check yourself
A service starts failing with 'Too many open files' under load, although memory and CPU look fine. What is the most likely cause?