I recently ran across this helpful Digital Ocean community answer about creating a swap file at droplet creation time.
So I decided to test how long using my old method (using dd
) takes to run vs using fallocate
.
Here’s how long it takes to run fallocate
on a fresh 40GB droplet:
root@ubuntu:/# rm swapfile && time fallocate -l 1G /swapfile real 0m0.003s user 0m0.000s sys 0m0.000s root@ubuntu:/# rm swapfile && time fallocate -l 2G /swapfile real 0m0.004s user 0m0.000s sys 0m0.000s root@ubuntu:/# rm swapfile && time fallocate -l 4G /swapfile real 0m0.006s user 0m0.000s sys 0m0.004s root@ubuntu:/# rm swapfile && time fallocate -l 8G /swapfile real 0m0.007s user 0m0.000s sys 0m0.004s root@ubuntu:/# rm swapfile && time fallocate -l 16G /swapfile real 0m0.012s user 0m0.000s sys 0m0.008s root@ubuntu:/# rm swapfile && time fallocate -l 32G /swapfile real 0m0.029s user 0m0.000s sys 0m0.020s
Interestingly, the relationship of size to time is non-linear when running fallocate
.
Compare to building a 4GB swap file with dd
(on the same server, it turned out using either a 16KB or 4KB bs gives the fastest run time):
time dd if=/dev/zero of=/swapfile bs=16384 count=262144 262144+0 records in 262144+0 records out 4294967296 bytes (4.3 GB, 4.0 GiB) copied, 4.52602 s, 949 MB/s real 0m4.528s user 0m0.048s sys 0m4.072s
Yes, you read that correctly – using dd
with an “optimum” bs of 16KB (after much testing different bs settings) takes ~1000x as long as using fallocate
to create the same “size” file!
How is fallocate
so much faster? The details are in the man pages for it (emphasis added):
fallocate is used to manipulate the allocated disk space for a file, either to deallocate or preallocate it. For filesystems which support the
fallocate
system call, preallocation is done quickly by allocating blocks and marking them as uninitialized, requiring no IO to the data blocks. This is much faster than creating a file by filling it with zeroes.
dd
will “always” work. fallocate
will work almostall of the time … but if you happen to be using a filesystem which doesn’t support it, you need to know how to use dd
.
But: if your filesystem supports fallocate
(and it probably does), it is orders of magnitude more efficient to use it for file creation.
And here is an example of the difference in time to run `mkswap` on a fallocate’d 32G file vs a dd’d 32G file:
$ rm swapfile && time (dd if=/dev/zero of=swapfile bs=16384 count=2097152) && time (mkswap swapfile)
2097152+0 records in
2097152+0 records out
34359738368 bytes (34 GB) copied, 273.383 s, 126 MB/s
real 4m33.384s
user 0m0.155s
sys 0m16.156s
Setting up swapspace version 1, size = 33554428 KiB
no label, UUID=923e4201-832a-48f6-baa0-c16a9941db72
real 1m58.893s
user 0m0.000s
sys 0m1.028s
$ rm swapfile && time (fallocate -l 32G swapfile) && time (mkswap swapfile)
real 0m0.034s
user 0m0.000s
sys 0m0.011s
Setting up swapspace version 1, size = 33554428 KiB
no label, UUID=c917fd42-fed8-419f-8164-56e44cbb08b0
real 0m0.144s
user 0m0.002s
sys 0m0.000s