Skip to main content


·4 mins

Source code on GitHub

What is it? #

Shake is a defragmenter that runs in userspace, without the need of patching the kernel and while the system is used (for now, on GNU/Linux only).

There is nothing magic in that : it just works by rewriting fragmented files. But it has some heuristics that could make it more efficient than other tools, including defrag and, maybe, xfs_fsr.

As an example, it allows you to write:

find -iname '*.mp3' | sort | shake

to defrag all mp3 in a directory, puting together on the disk those close in lexical order.

How to install it? #

If you can, use the package suitable to your distribution:

  • Repository for Ubuntu/Debian
  • Gentoo: emerge sys-fs/shake
  • Archlinux: pacman -S shake

If you want to build it by yourself, install cmake and developpment files for libattr. Then extract the tarball, open the build/ directory in a terminal, and run cmake .. (to generate the Makefiles), make (to build files) and make install.

How to use it? #

Before any use, check that your partition is mounted with user_xattr. If it is not, edit your fstab to add this option then call mount -o remount MY_PARTITION. Shake can works without them, but will be less efficient (it uses xattr to store information helping incremental use).

Short version #

As root, call shake my_dir, and go do something usefull or pleasant until it completes. Then my_dir should be less fragmented. For better results, you should call Shake on the whole partition, when you’re not using it.

If you just wanted to see the fragmentation, call shake --pretend --verbose --verbose my_dir, alias shake -pvv my_dir.

Tips #

With --old 0 --bigsize 0, you can tell him that all files are old enough, not too big, and so need to be shaked. If you see a warning saying “failed to set position time”, read the above message about setting user_xattr on your partition.

Long version #

If you want to adapt the behaviour of Shake, here are the lengthy details. Shake does the following to decide if a file is fragmented (guilty) or not :

  • It first looks at the file size, to determine it’s tolerance regarding this file. The less is the tolerance, the more is the probability for a file to be guilty.
    If a file is smaller than smallsize (determined with --smallsize, 16 kB by default), then --small-tolerance (0.1 by default) applies.
    If a file is bigger than big_size (determined with --bigsize, 95 mB by default), then by default, the file _won’t be shaked
    so you can tell it to let big files alone. If you want to change this behaviour, set --big-tolerance to something else.

  • Then it looks at the date of the last shake (xattr), or the ctime.
    If the file is older than 8*31 days, it will be shaked, in order to reorganise free space. You can change this value with --old.
    If a file is newer than 2 month, it won’t be shaked. You can change this date with --new.

  • If you tell Shake to examine a whole dir, it will look at the distance between two files with the similar atimes (file used together). If this distance is too high, then those files will be shaked.
    The tolerance multiply this distance. You can change the default value with --max-deviance.

  • Then, it looks at the actual number of fragments, and class them in two categories:

    • The first is the one of crumbs, that is fragments which contains less than crumbratio*file_size bytes. You can change that with --crumbratio.
    • The other is the one of all fragments, including crumbs. If a file countains more fragments than max_fragc or more crumbs than max_crumbc, then it is considered as guilty. You can change max_crumbc and max_fragc respectively with --max-crumbc and --max-fragc.

The code #

I will write this section if someone asks for it 😀.