Wednesday, May 14, 2014

Tips for using an SSD under Linux

Solid state drives (SSDs) offer amazing performance, but do have one major limitation. There is a maximum limit to how many times it can be written to (or to think of it another way, that memory can be overwritten). Moreover, writes can be slowed when previously freed space has not been reclaimed by the SSD, because then this reclaiming needs to happen before the write can occur. TRIM commands from the operating system to the SSD allow the drive to do this in the background. Unfortunately this isn't as well integrated into the OS as under Windows.

To get all set up and optimize the life and performance of your SSD, I recommend the following steps:

1) Set your drive not to set access times on files (otherwise the inodes need to be written each time you do)
in /etc/fstab. Normally these are not needed and will save you from writing to the drive each and every time you read. To do this, add the noatime and nodiratime parameters to your SSD drive, eg:

UUID=xxxx-xxx-xxx-xxxx / ext4 noatime,nodiratime,errors=remount-ro  0  1

Note: DO NOT use the discard option, which is the original method of enabling TRIM support and which does not perform well, especially when deleting large numbers of large files (instead, use the userspace command fstrim, as below).
Finally, if you think you really need the access times, you can use the relatime setting instead of noatime -- it doesn't save as many writes, but still saves a lot (in fact this is usually now the default option).

2) To send TRIM commands to the HD, run the fstrim utility regularly to notify the SSD of newly freed space. Make a new file called fstrim in /etc/cron.daily, with the following contents:

#!/bin/sh
echo Running fstrim on SSD.
fstrim /

where the / should be the mount point of the SSD. Run chmod +x /etc/cron.daily/fstrim to make it executable. It will run automatically each day.

3) Don't use swap space on the SSD unless you need to. Using the SSD for swap space is way faster than a HDD, but swap is normally a heavy disk user, and we need to avoid unnecessary writes on an SSD. So what to do? Well, one, you might not need a swap if you have a lot of RAM and not so much demand. In my case I do need that extra memory occasionally, and it kind of does need to be SSD-fast. So what I ended up doing is telling Linux to only use the swap when absolutely necessary (eg, when it's running out of memory) -- by setting swappiness to a setting well-below the default; I chose 5, but something in the 0-10 range is probably good (0 tells linux to only use the swap when it is completely out of physical memory when it tries to allocate; higher may allow some degree of caching in swap space). To set swappiness, add this line in /etc/sysctl.conf and reboot:

# Change default swappiness (60) to reduce unnecessary writes to SSD swap
vm.swappiness = 5

4) Use ram disks for common temporary files to avoid unnecessary writes to disk. tmpfs will allocate space for ramdisks as-needed. I did this for 3 directories: /var, /var/tmp, and /var/spool, by emptying out those directories and placing the following lines in /etc/fstab:

# Use ramdisks for temp files to avoid excessive writes to SSD
tmpfs /tmp    tmpfs defaults,noatime,mode=1777 0 0
tmpfs /var/spool tmpfs defaults,noatime,mode=1777 0 0
tmpfs /var/tmp   tmpfs defaults,noatime,mode=1777 0 0

5) Change the I/O scheduler to DEADLINE for your SDD. The default is CFQ which is great for HDDs but overkill and slower for SDDs. For SDD, you don't really even need a scheduler, and could instead choose NOOP which is a simple first in first out scheduler, but DEADLINE is a little better, since for example it prioritizes reads over writes in the queue, ensuring decent read responsiveness even under heavy writes. Put the following lines (after modifying to match your drive locations sda/sdb/etc) in your /etc/rc.login so they run every bootup.

# use deadline scheduler for SDDs (and CFQ for HDDs)
echo deadline > /sys/block/sda/queue/scheduler


5) Finally, you can move caches for your commonly used programs (especially the web browser) off of the SSD. These write a lot to disk, and are already well optimized to work with a hard drive (HDD). If you also have an HDD, you can redirect the .cache directory under your home onto that HDD. Since cache is already optimized for hard drives, it shouldn't negatively impact performance unduly. (Alternatively you could do something similar for just the browser cache(s) using tmpfs, although the cache will be lost each reboot). First, close any programs that may be using the cache (or better, login at the terminal) Then run these commands to create a symbolic link:

cd /myHDDmountpt
mkdir .cache
cp -R ~/.cache .cache
cd
rm -Rf .cache
ln -s /myHDDmountpt/.cache .

Hopefully these tips will help your SSD live long and perform well. Let me know in the comments if you know any other good tricks!