...

vm.vfs_cache_pressure Explained – Getting the Most Out of the Linux File System Cache

I'll show how the kernel parameter vm.vfs_cache_pressure how the VFS cache is weighted relative to the page cache, and which values deliver performance gains under real-world load profiles. I adjust this setting in clear, step-by-step increments, measure the effects, and thus make the most of the File System Cache optimal.

Key points

To get you started quickly, I'll summarize the most important aspects of tuning the VFS Caches together. This way, when choosing a value, I keep an eye on the impact on metadata lookups, I/O load, and RAM pressure. These points help me optimize typical server roles reliably and consistently.

  • Mechanism of Action: Controls how aggressively the kernel releases Dentries/inodes relative to the page cache.
  • Default setting: 100 indicates a balanced adjustment without any preferential treatment.
  • Low values: Values between 50 and 80 keep metadata in RAM longer and speed up file lookups.
  • High values: Values between 120 and 200 release VFS caches more quickly and free up space for processes.
  • Practice: Make changes step by step, measure the results, document them—and only then make further adjustments.

I consistently apply these principles to strike the right balance between Cache hit rate and available RAM. Then I adjust `vm.vfs_cache_pressure` in small increments, monitor load spikes, and make corrections as needed. This allows me to achieve stable response times without unexpected memory bottlenecks.

What is vm.vfs_cache_pressure?

This parameter controls how strictly the kernel enforces the VFS Cache Unlike other memory types, it is cleared as soon as RAM becomes scarce. Dentries and inodes—that is, directory entries and file metadata—are stored in the VFS cache, which noticeably speeds up file lookups. A value of 100 treats the VFS cache and page cache equally, while lower values prioritize keeping metadata in RAM. Higher values cause the kernel to discard VFS entries sooner and free up memory more quickly. I use this setting specifically to keep metadata hits high for web, file, and CMS workloads without displacing processes. This is how I control the balance between Lookup Speed and available memory in a very direct way.

How does the VFS cache work in detail?

The Virtual Filesystem provides a common layer for ext4, XFS, Btrfs, and others, and stores Dentries and inodes in RAM, so that directory scans and repeated accesses remain fast. The page cache, on the other hand, holds the actual file blocks; both caches complement each other but compete for memory under pressure. The more small files and frequent repeated accesses there are, the more the application benefits from a high metadata hit rate. This is exactly where `vm.vfs_cache_pressure` comes into play: I can control whether Linux retains this metadata or quickly evicts it. For more in-depth aspects of the page cache, I also use the compact Page Cache Performance Booster as background information so that I can evaluate VFS and page cache in context.

Default value and typical ranges

On most systems, the value is set to 100 This provides a balanced foundation for initial testing. If I lower the value, I prioritize metadata and optimize fast lookups, which is especially effective when dealing with many small files. If I increase the value, Linux breaks down VFS entries more quickly and creates more buffer space for applications or the page cache. I handle extreme values such as 0 or values above 500 with great caution, as they can trigger erratic behavior and cause side effects. In everyday use, I start at 100, adjust in increments of 20–40 points, and measure the effect on I/O Latency and response times.

Value Meaning When to use Risk/Note
< 100 (e.g., 50–80) The VFS cache remains in RAM longer Many small files, frequent lookups More RAM allocation to Metadata
100 Balanced Adjustment A solid starting point for measurements Good Baseline-value
> 100 (e.g., 120–200) VFS Cache Is Released More Aggressively Low RAM, databases with their own cache Possible lookup latency
Extreme (0, > 500) Significant Shifts Special Cases: A Quick Test Threat to stability and Performance

This framework helps me quickly identify which direction works best without getting carried away. I avoid making large leaps and document every change in detail. This way, the path I've taken remains clear, and I maintain a clean comparison with previous data points.

Role in memory cleanup

Under pressure, the kernel must free up RAM, and this is exactly where `vm.vfs_cache_pressure` defines the trade-off between VFS Cache, page cache, and process memory. Low values keep directory and inode entries in memory longer, which speeds up directory lookups and repeated file openings. High values free up memory sooner and provide more space for processes or the page cache, which can be helpful when RAM is limited. I specifically monitor I/O latencies here, as a metadata cache that is too empty slows down file searches. When combined with page cache clearing strategies, this insight helps me Page Cache Eviction valuable practical insights so that I can make fact-based decisions.

Measurement Methodology: Making the VFS Cache Transparent

Before I make a change, I make it visible, where storage is located and what is being overridden. That's how I can tell whether metadata is really the bottleneck—or whether the page cache, processes, or dirty pages are the main issue.

  • /proc/meminfo: I examine InodeCache, Cached, Buffers, SReclaimable, and SUnreclaim to assess their proportion and reclaimability.
  • slabtop: Real-time view of slabs, specifically dentry, inode_cache, ext4_inode_cache, and xfs_inode. This lets me see whether dentries and inodes are growing or shrinking.
  • IO Path: I use vmstat/iostat to monitor read latencies and see if disk accesses increase during lookups.
# Quick Overview
grep -E 'InodeCache|SReclaimable|SUnreclaim|Cached|Buffers' /proc/meminfo

# Slab Distribution (sorted by size)
sudo slabtop -s c

# Filter out only dentry/inode-like slabs
grep -Ei 'dentry|inode' /proc/slabinfo | sort -k3 -nr | head

# I/O and memory trends updated every second
vmstat 1
iostat -x 1

I think the interpretation is clear: If SReclaimable grows along with the dentry/inode slabs and IO latencies increase at the same time, not, this confirms that the metadata cache is working effectively. If these values frequently drop to zero and then spike during directory accesses, vm.vfs_cache_pressure is likely set too aggressively.

Practical Application: Reading and Changing the Current Value

The check can be performed on the command line in seconds and without Restart. I read the current value and initially write test values to a temporary file so that I can immediately implement rollbacks in the test window. For production-ready adjustments, I set entries in /etc/sysctl.conf or a file in /etc/sysctl.d/, reload them, and record the change in my documentation. I test each level under realistic load—not just at idle—so that effects become visible. This ensures clean before-and-after comparisons, and I evaluate the change based on measurable metrics.

# Check current value
cat /proc/sys/vm/vfs_cache_pressure
# or
sysctl vm.vfs_cache_pressure

# Test temporarily (until reboot)
sudo sysctl -w vm.vfs_cache_pressure=60
# Alternatively
echo 60 | sudo tee /proc/sys/vm/vfs_cache_pressure

# Set permanently
echo "vm.vfs_cache_pressure = 60" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

Linux Cache Tuning: Useful Scenarios

In hosting platforms with many static assets, file repositories, or applications with their own buffers, it’s worth implementing a targeted weighting of the VFS cache. Web servers with numerous small files benefit greatly from lower values because lookups are less likely to hit the SSD/HDD. File servers with a mix of file sizes can use moderately lower values if sufficient RAM is available. Database servers with high RAM usage and a large DB cache prefer higher values to ensure processes have enough space. I evaluate these patterns using monitoring data to ensure the settings match the actual access mix.

Web server with many static files

For CSS, JS, and images, I like to keep the metadata in the Cache. Values between 50 and 80 have often proven effective because reopening files is faster. I closely monitor I/O spikes during traffic bursts and compare response times before and after the change. If latencies remain stable and 404 lookup costs decrease, we’re on the right track. I keep an eye on RAM usage to ensure that processes have enough space despite a larger metadata cache.

File servers or NAS systems

High user traffic and directory changes benefit from lower to balanced values. If there’s enough RAM, I tend to aim for 50–80; if memory is tight, I stay closer to 100. I check to see if directory listings remain smooth and if snapshots/backups aren’t crowding out the caches too much. If I/O latency increases during peak periods, I carefully adjust the value upward. This way, I maintain a balance between performance and available memory.

Database Servers and Memory-Constrained Systems

Databases maintain their own buffer cache, so I'm giving the Process memory usually takes priority. Values between 120 and 200 signal that VFS caches should be flushed more often to free up RAM. I pay close attention to the application’s query latencies and page fault patterns. If the database slows down because the system starts swapping, I increase the value slightly and also reduce `vm.swappiness`. This approach prevents metadata from unnecessarily taking up space that the database could better utilize.

Workload Examples and Guidelines

I start at 100 and reduce in increments of 20 for web-related Workloads and increase it in increments of 20 for memory-intensive processes. I test each level for at least one peak phase so I can identify any effects on latencies, cache hits, and swap activity. If you want to dive deeper, you'll find the concise Page Cache Performance Booster Additional background information on file cache strategies that I consider in parallel. If the measured values match the target, I lock in the configuration and document the key metrics. This ensures that the optimization remains reproducible and allows me to make quick adjustments later on.

Risks and pitfalls

If I set the value too low, the kernel will have a hard time freeing VFS entries, which can lead to bottlenecks during OOM—risks. If I raise it too high, latency increases during file lookups and directory changes because metadata has to be reloaded. Without testing under actual load, there’s a risk of drawing false conclusions from periods of low activity. Abrupt changes make evaluation difficult, so I proceed step by step. I record every change along with the time, load profile, and metrics so that the causes remain clear.

Monitoring and Metrics

Hard data will show whether an adjustment is worthwhile Metrics. I monitor RAM usage, the distribution between caches and processes, I/O latencies, and swap activity. In addition, I analyze cache hit rates and page fault trends to quickly identify side effects. Improvements in time-to-first-byte are particularly noticeable when dealing with many small files. If I/O latency remains low and swapping decreases, this confirms we’re on the right track.

Tuning Playbook: From Hypothesis to Reliable Setting

Structure prevents flying blind. I follow a set procedure to ensure that results are reliable and that my teammates can understand the steps involved.

  1. Record Baseline: vm.vfs_cache_pressure=100, 24–72 hours of realistic load. Record key metrics (latencies: median/95th/99th percentiles, I/O wait time, CPU steal, swap activity, inode/dentry size).
  2. Formulate a hypothesis: „Many small files; lookups are expensive—lower values speed things up“ or „RAM is tight—higher values keep processes running smoothly.“.
  3. Change step by step: ±20 to ±40 points. Measure at least one peak phase per level.
  4. Compare: I'm checking to see if the SLOs (e.g., the 95th percentile) are consistently improving, without No more swap or OOM events.
  5. Rollback criterion: If 95th/99th percentile latencies rise, I/O wait times increase, or cache misses become more frequent, I take a step back.
  6. Freeze & Documentation: Record the final value, date, load window, and key figures.
# Quick Test for Controlled Measurement Windows (Maintenance Only!)
# Before: Take a snapshot of key metrics
date; free -h; grep -E 'InodeCache|Cached' /proc/meminfo; vmstat 1 5

sudo sysctl -w vm.vfs_cache_pressure=80
# Wait for the load test/peak, then capture metrics again and compare them

File Systems and Mount Options: Context Matters

The effect of `vm.vfs_cache_pressure` also depends on the file system and the mount options. I evaluate these factors as follows:

  • relatime/noatime: Prevents frequent atime writes. noatime reduces I/O pressure during multiple reads, making the benefits of metadata more apparent.
  • lazytime: Delays metadata updates in RAM; this smooths out peaks but interacts with flush times.
  • ext4 vs. XFS vs. Btrfs: Different inode structures and shrinker behavior. I always measure on the target FS, rather than passing on assumptions.
  • NFS/Network File System: Attribute caching and invalidation can limit the benefits of VFS. Aggressive release (high values) then drives up the number of remote lookups.
  • OverlayFS/FUSE: Many small metadata operations benefit greatly from the VFS cache; I tend to keep the values moderate to low, provided there is sufficient RAM available.

Container and Cgroup Considerations

In container environments, I keep in mind that `vm.vfs_cache_pressure` is a host-wide Switch. Changes affect all Pods/containers on the node. That's why I'm taking a conservative approach and coordinating tuning at the node level.

  • Storage Limits: Memory cgroups limit the process and page cache; slab memory can be counted proportionally. I've observed related Pod-OOMs and Node-Pressure events.
  • Workload Mix: Nodes that host both DB pods and web frontends at the same time do not experience extreme values. If necessary, I distribute roles across different nodes.
  • Rollout: First the Canaries (one node), then a staggered rollout. I document the changes in the Node baseline (sysctl.d) and note the deployments affected.

Special cases from practice

Some patterns can be specifically addressed once I know their causes:

  • CI/Build Jobs: Many short file accesses and directory scans benefit from lower values. I increase them again after the job is complete if nodes are used for mixed purposes.
  • Backup/Scan Window: Long directory traversals flush the cache. Temporarily, a higher Set a value (e.g., 180) during the backup to prevent dentries/inodes from filling up the RAM—then I'll reset it.
  • Negative Dentries: Non-existent files (404) are also cached. Web workloads with frequent access failures see measurable performance gains if the VFS cache is not flushed too aggressively.
  • Streaming/Sequential I/O: The page cache dominates here; setting the value too low doesn't do much good and ties up RAM unnecessarily. I keep it close to 100 or slightly above.
# Example: Be a little more aggressive during a full backup
sudo sysctl -w vm.vfs_cache_pressure=180
# After the backup, revert to the previously determined optimal value
sudo sysctl -w vm.vfs_cache_pressure=60

Automation and Governance

After successful testing, I incorporate the setting into my standard builds. It's important that teams know, why a value has been selected and when it must be checked (e.g., after version or workload changes).

  • Configuration management: For each role (Web, DB, file server), I maintain defined defaults in /etc/sysctl.d/ and distribute them centrally.
  • Drift Control: Regular audits verify that the live values match those in the repository.
  • Runbooks: I document measurement steps, rollback thresholds, and emergency procedures (e.g., resetting to 100).
# Role: Web Server (Example)
cat <<'EOF' | sudo tee /etc/sysctl.d/50-web-vfs.conf
vm.vfs_cache_pressure = 60
EOF
sudo sysctl --system

vm.vfs_cache_pressure and other kernel parameters

A good result can only be achieved through collaboration with vm.swappiness and the dirty page thresholds. A lower swappiness value (e.g., 10–20) keeps processes in RAM longer and prevents unnecessary swapping. I use `vm.dirty_background_ratio` and `vm.dirty_ratio` to control how early the system writes modified pages to disk, so that write spikes don’t block everything. I adjust these values so that metadata lookups remain fast and write operations proceed in a predictable manner. I use this concise overview of how file caches interact: File System Caching Overview.

Recommendations for Hosting Environments and WordPress

Many themes, plugins, and media files generate countless small files, which is why a powerful VFS Cache makes a noticeable difference. I start with 100, lower it to 80 if there’s enough RAM, then to 60 later, and check response times, the 95th percentile of latencies, and CPU steal. If memory remains ample, I test 50 and validate again during the evening peak or while campaigns are running. If latencies drop without triggering swap or the OOM killer, I lock in the setting permanently. At the same time, I keep an eye on the page cache to ensure that both caches complement each other effectively.

Summary

I use vm.vfs_cache_pressure to control the Balance I adjust this very precisely based on the balance between fast metadata lookups and available RAM. For web-oriented workloads, I lower the value moderately; for memory-intensive applications, I raise it. I back up every change with metrics on I/O latencies, cache hits, and swap activity. In combination with `vm.swappiness` and the `dirty` parameters, I achieve stable memory management. This allows me to use the Linux filesystem cache efficiently and reliably keep response times low under load.

Current articles