Linux preemption models
- title
- Linux preemption models
- type
- concept
- summary
- PREEMPT_NONE, PREEMPT_FULL, and PREEMPT_LAZY โ when the kernel is allowed to take the CPU away from a running thread
- tags
- linux, kernel, scheduling
- sources
- linux-broke-postgresql
- created
- 2026-04-30
- updated
- 2026-05-14
Preemption is the scheduler's decision about when it's allowed to interrupt a running thread and hand the CPU to another. Different workloads want different answers, so the Linux kernel exposes the choice as a build-time configuration.
The three models
PREEMPT_NONE โ the kernel almost never interrupts a running thread. It runs until it gives up the CPU itself: a syscall, blocking I/O, an explicit sleep. Few context switches, high throughput, predictable behavior under load. Traditional server default.
PREEMPT_FULL โ the kernel can interrupt a running thread at almost any safe point, including inside the kernel itself. Lower latency, more context-switch overhead. Traditional desktop default, where responsiveness wins over throughput.
PREEMPT_LAZY โ introduced in Linux 6.12 as a compromise. Preemption is allowed but the scheduler tries to wait for natural boundaries before cutting in. Designed as a drop-in replacement for PREEMPT_NONE on throughput workloads.
What changed in Linux 7.0
Linux 7.0 removed PREEMPT_NONE on modern CPU architectures, leaving PREEMPT_FULL and PREEMPT_LAZY. Most server distros shifted their default to PREEMPT_LAZY. The transition is invisible for most software. But where it isn't, it really isn't โ see linux-7-postgres-regression for a workload (PostgreSQL on a 96-vCPU box) where the change cut throughput in half because the scheduler can now preempt a thread that's holding a spinlock and is midโpage fault.
Why "drop-in" isn't drop-in
PREEMPT_NONE was a free implicit guarantee for any code holding a spinlock: even if the holder did something the kernel had to handle (a fault, a slow path), it wouldn't get descheduled until it was done. Code written before PREEMPT_LAZY could quietly rely on that. Once removed, every "the holder will be gone in nanoseconds" assumption needs to actually be true โ or be backed by something stronger like restartable sequences.
What happens before any of this matters
The preemption model only takes effect after boot. During Phase 4 of linux-kernel-startup (start_kernel), interrupts are disabled for almost the entire run and the scheduler exists but isn't load-balancing yet. Real multitasking โ the world where preemption decisions actually matter โ starts in Phase 6 with sched_init_smp(). See linux-boot-phases for the broader ordering.