I have a huge Mercurial repository (take a guess how many directories it has -- it's gonna be more than you guessed). The time taken to do basic repository operations is heavily dependent on whether the system buffer cache is hot or cold, as the following example demonstrates (one command run right after the other):

bash> time hg status

real    0m41.809s
user    0m0.815s
sys     0m0.217s

bash> time hg status

real    0m0.858s
user    0m0.679s
sys     0m0.175s

After I don't use the machine for a few days (without rebooting), I find the cache has gone cold, and it takes a long time again to run hg status. This is despite none or few of the directories having changed (verified by checking mtimes) and having a gigantic amount of RAM (which even counting the page cache isn't all used; verified with free).

So given that there is no memory pressure, why are things getting evicted from the dentry or inode caches? Do they have some max size somewhere? Anecdotally, I've never seen the "buffers" column in free go much above 4 GB. Not sure if the system is refusing to let the buffer cache grow bigger than this.


The cache that matters most for directory traversal is the inode cache. This isn't included in the “cache” figure that free displays. It's part of the kernel data (the “slab”). You can see how much memory the various slab pools occupy in /proc/slabinfo (this requires root access). You can use slabtop to see them vary in real time, or this snippet to get a report with each pool's size in bytes:

</proc/slabinfo awk '{print $1, $3*$4}' |sort -k2n

On a typical machine, pressure on the inode cache comes from the nightly updatedb job. If you find how to avoid this, let me know.

The size of the inode cache pool is not fixed, it's determined by a ratio of metadata cache per data cache: the vm.vfs_cache_pressure parameter. You may want to experiment with this — either a low value (the default is 100) to keep more entries in the cache so that the ones from hg aren't displaced, or a high value so that the entries from nightly cron jobs don't stay to pollute RAM.

Finally there's always the hack of running hg status in a morning cron job.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.