What Is the Page Cache and How It Affects Timings Explained
What the Linux page cache is, how it speeds file access and distorts timings, how to read free and /proc/meminfo, and when cached memory is available.

"The server has no free memory!" is the most common false alarm in Linux administration. The memory is used by the page cache, which the kernel gives back on demand. The same cache is why a command is slow the first time and fast the second, and why a file copy appears to finish before the data is on disk. Understanding it removes three kinds of confusion. It is the background of why benchmarks lie and of the swap tuning in swappiness. The commands assume Linux 6.x and procps-ng 4.
Reading free
free -h
grep -E '^(MemTotal|MemFree|MemAvailable|Buffers|Cached|Dirty|Writeback):' /proc/meminfo total used free shared buff/cache available
Mem: 15Gi 2.8Gi 0.4Gi 210Mi 12Gi 12Gi
MemTotal: 16384000 kB
MemFree: 410000 kB
MemAvailable: 12900000 kB
Cached: 11800000 kB
Dirty: 2400 kB
Only 0.4 GiB is "free", yet 12 GiB is "available". The kernel keeps spare RAM busy with cached file data because unused memory is wasted memory. When a program asks for memory, clean cache pages are dropped instantly. Judge memory pressure by available, and by swap activity (vmstat 1 columns si and so), not by free. The figures above are illustrative.
How reads and writes use it
read(): look in the cache; if present, copy from RAM; else read from disk, keep a copy
write(): copy into the cache, mark the page dirty, return; flush to disk later
sync: write all dirty pages to disk now
A write returns when the data is in memory, not on disk, which is why copying a large file seems instant and then the system keeps writing for a while. Dirty pages are flushed after a delay (about 30 seconds by default) or when too many accumulate, controlled by vm.dirty_ratio and vm.dirty_background_ratio. Pull a USB stick without unmounting and the data in dirty pages is lost. fsync and sync force it out; databases call fsync for durability, and dd ... conv=fsync does it for copies, see using dd.
See and control the cache
fincore /var/log/syslog
sudo sync; echo 3 | sudo tee /proc/sys/vm/drop_caches
echo 1 | sudo tee /proc/sys/vm/drop_caches
dd if=big.iso of=/dev/null bs=1M iflag=directfincore reports how much of a file is cached. Writing 3 to drop_caches frees clean page cache and slab objects (1 is page cache only); run sync first so dirty pages are flushed and can be dropped. It is for testing, not for routine "freeing memory": it makes the system slower afterwards while the cache refills. iflag=direct or oflag=direct bypasses the cache and measures the device, though some file systems and devices handle it differently.
Effects on timings
time cat big.log > /dev/null # cold: dominated by disk read
time cat big.log > /dev/null # warm: RAM speed
time sh -c 'cp big.log /tmp/x' # returns before the data is on disk
time sh -c 'cp big.log /tmp/x && sync'A benchmark that reads the same file repeatedly measures memory after the first run. A write benchmark that does not sync measures how quickly the kernel accepts data into RAM. State which you mean, and use drop_caches or --prepare in hyperfine to test cold; see trustworthy benchmarks. Containers share the host's page cache, and a cgroup memory limit counts the cache used by its files, so a container can appear to hit its limit with cache that is reclaimable.
When the cache is a problem
A job that reads a huge file once (a backup, a log scan) fills the cache with data that will not be reused and evicts useful pages. Tools such as nocache, dd iflag=direct, rsync --drop-cache (a newer option) or posix_fadvise avoid that. On a database server, the database's own buffer pool and the kernel cache can duplicate data; databases such as PostgreSQL rely on the page cache and are tuned with that in mind.
What the numbers in the tools mean
Different tools present the same memory in different ways, and the confusion is a source of needless alarms. The "free" column counts memory that holds nothing at all. The "available" column estimates what could be given to programs without swapping, including cache that can be dropped and reclaimable kernel structures. The "used" column counts what programs have allocated, and on newer versions of free it excludes cache. Dashboards that plot "used plus cache" as used memory will show a server running near the ceiling by design, and an alert on it fires every time the cache fills, which is a good sign, not a problem.
The right signals for memory trouble are different. Watch swap activity with vmstat and its si and so columns, pressure stall information in /proc/pressure/memory on kernels that provide it, and kernel messages about the out-of-memory killer. Sustained swapping, rising memory pressure or a kill message means a real shortage, regardless of what the free column says.
Dirty pages and write behaviour
The write path explains several common puzzles. Copying a big file to a slow USB drive appears to finish quickly and then the eject command hangs: the copy completed into memory and the kernel is still writing, which is why you must wait for sync or the eject to finish before unplugging. The kernel controls how much dirty data may accumulate with tunables such as vm.dirty_ratio and vm.dirty_background_ratio. When dirty data crosses the upper limit, writers are throttled, and an application that was fast suddenly stalls, which looks like a disk problem and is actually the cache protecting memory.
Databases and journalled applications call fsync to force data to disk at specific points, because they need durability guarantees that the cache alone does not give. An application that does not call it can lose recent writes in a power cut, while one that calls it too often pays a performance cost. This is the origin of settings such as relaxed durability modes in test databases.
Containers and cgroups
In a container with a memory limit, the page cache counts toward the limit. A process reading many files can push the container near its ceiling with cache alone, and the kernel then reclaims cache within the container to make room, which is normal. The metrics to watch are the container's working set, which excludes easily reclaimed cache, and the OOM-kill count. Monitoring tools that report the raw usage number may show a container at 95 percent that is perfectly healthy, and tuning the limit on that figure causes needless restarts. Read the documentation of your runtime to see which figure it reports.
Practical consequences
Leave RAM for the cache when sizing servers: a database or file server is faster with spare memory that the kernel uses for hot data than with the same memory tied up by an oversized application. Do not drop caches in cron jobs; it slows the system down by forcing disk reads and hides the real problem. When a benchmark needs a cold start, drop them once, on a test machine. And when someone reports that the server is out of memory, ask for the available figure, the swap activity and any kill messages before anything else.
Where this does not apply
Network and FUSE file systems have their own caching rules, and memory-mapped files and tmpfs behave differently (tmpfs is memory, see tmpfs). On macOS the unified buffer cache plays the same role, with different tools. See the kernel memory management concepts and the linuxatemyram.com explanation.


