Compare
Side-by-side on the decisions that recur: process vs thread, threads vs async, mutex vs semaphore, blocking vs non-blocking I/O, container vs VM — with when to choose each.
Process vs ThreadThreads vs Async / event loopConcurrency vs ParallelismMutex vs SemaphoreBlocking I/O vs Non-blocking / async I/Oselect / poll vs epoll / kqueueContainer vs Virtual machineStack vs HeapPipe vs Shared memoryOS page cache vs Application cache
| OS page cache | Application cache | |
|---|---|---|
| Who manages it | The kernel, transparently, for every file read/write and mmap | Your process: a buffer pool, an LRU map, Redis in front of the database |
| Granularity | 4 KB pages of file data (Linux, macOS; Windows uses 4 KB pages plus its own cache manager) | Whatever you choose: rows, objects, rendered responses, 8 KB database pages |
| Eviction | Under memory pressure, by the kernel’s LRU — you cannot pin (except mlock) | Your policy: LRU, LFU, TTL; sized explicitly |
| Cost of a hit | A syscall and a copy into user space (or none with mmap) | A pointer chase — no syscall |
| Double caching | If you also cache, the same data sits twice in RAM | Databases use O_DIRECT to bypass the page cache and own their buffer pool |
| Visibility | free -m "buff/cache"; counts against a cgroup memory limit | Part of your RSS; visible in your metrics |
| Choose this when | Reading files sequentially or via mmap, or any workload where the kernel’s cache already delivers hits and you want zero code. | You need a specific eviction policy, data in a decoded shape, cross-process or cross-machine sharing, or control over what stays resident. |