Running Ubuntu and other Linux flavors on an SSD
effective immediately, we have moved to our dedicated servers in http://www.brizoma.com/
Please update your bookmarks, since we will not update this site anymore.
See you in BRIZOMA.COM
There are some guides on the internet with tweaks on how to make your solid-state drive (SSD) run faster or last longer in Linux. While researching how to optimize my box to run on a dual approach (SSD for the operating system and SATA for data), I could not find all the information I needed in one single article.
Here is a guide I put together based on my experiences; it is also some kind of check list for my future installations, e.g. in case of SSD crash, which has already happened to me. Since SSDs work so much differently than HDDs, it’s important to make some optimization in Ubuntu for them. SSDs are much faster than HDDs, but have a limited number of writes before they wear out. This makes balancing performance with the life of your SSD also a big concern for how you tune your system.
Mount Points and File System
I don’t like tweaks that change the mainstream status of my distribution, i.e. I always try to stick to the most frequent (but user-friendly) configuration of my distribution of choice. This is why I decided to keep ext4 as my filesystem. I will boot from the SSD and use automatic mount feature of Ubuntu (12.04 at the time of this writing) for the data disk, which actually includes the old installation of my other Linux (HDD), so I can always dual boot in case of failure.
Since the HDD is a huge 2TB disk, I don’t have to worry about a few GBs eaten up by the OS and I get a fail-safer system. I partitioned my 120GB SSD (OCZ Agility 3 SATA III) into a single root (/) partition using the default ext4 filesystem. I kept my old HDD home partition automatically mounted by Ubuntu at:
I did not use a swap partition for the installation on the SSD. I will use the swap partition of the HDD instead. More details about this below.
If you want to make the access to these files from your home directory seamless, you can symlink folders from the SSD to the HDD. However, I found that this wouldn’t be fully seamless for some applications that don’t follow symlinks. Bind mounts may be a better solution for you since they allow a directory in a filesystem to be mounted in additional locations, similarly to symlinks but fully transparent to applications. Test bind-mounting your Sounds directory, i.e. running mount with the –bind option on a terminal, and specify the source directory (on the HDD), and the mount point (which must already exist on the SSD):
mount --bind /media/UUID-of-HDD/home/username/Sounds /home/username/Sounds
To make your bind mounts permanent, you can include them in your /etc/fstab file using this format:
/media/UUID-of-HDD/home/username/Sounds /home/username/Sounds none bind 0 0
If you need to add a path with a space character in it, replace the space with “backslash040” (sorry about this, but WordPress removes the “\” character, so replace the string “backslash” with the appropriate character) to escape it. If you make a mistake and one of the bind mounts fails, Ubuntu will allow you to skip it and continue booting. By default, many distributions use the ‘relatime‘ flag for updating file metadata when files are accessed, but you will most probably do without last access times.
Additionally, Linux supports TRIM with ext4. TRIM is important for maintaining the performance of an SSD over time as files are added, deleted and changed, and lets the SSD know which blocks can be safely cleared. No distributions currently enable it by default, but it’s simple to do by adding the ‘discard‘ flag to any mounted SSDs.
Any recent SSD should have the TRIM command available, which prevents performance degradation by allowing the OS to notify the SSD which blocks are unused. The ext4 filesystem uses TRIM when the discard option is set. The noatime option reduces writes to the SSD by not writing access time updates whenever a file is read. This improves performance and increases the life of the SSD. Please make sure your SSD actually supports TRIM by entering this into a terminal:
sudo hdparm -I /dev/sda | grep TRIM
This will output a list of drive features related to TRIM, with an asterisk to indicate if that feature is supported on the drive. If your drive supports TRIM, you will see a line like this:
* Data Set Management TRIM supported
In my case, the OCZ Agility 3 answered with:
* Data Set Management TRIM supported (limit 1 block) * Deterministic read data after TRIM
It is very important to notice the asterisk at the beginning of the response. If it is not there, the feature is NOT supported. To make all these changes, open up a terminal and run:
sudo nano -w /etc/fstab
Then for all SSD devices in your system remove ‘relatime‘ if present (not in Ubuntu 12.04) and add ‘noatime,nodiratime,discard‘. Therefore, change this line (do not modify your SSD’s UUID):
UUID=5689a7e0-f85f-4185-938c-f674a9982828 / ext4 errors=remount-ro 0 1
into this (put all text in one line, without line breaks):
UUID=5689a7e0-f85f-4185-938c-f674a9982828 / ext4 errors=remount-ro,noatime,nodiratime,discard 0 1
Swap and Swappiness
I mean to use the swap partition on the old HDD. Swap on the SSD would be faster, but would also shorten the SSD’s life. Therefore you need to edit /etc/fstab on your current installation of the SSD to point swap to the old /dev/sdb5 partition
sudo nano -w /etc/fstab
and include the following line:
/dev/sdb5 none swap sw 0 0
My system has 8GB of memory it almost never swaps, so I could have also reduced the swappiness value to 0 to tell Ubuntu to only swap when absolutely necessary. You can do this by adding the following line to /etc/sysctl.conf:
sudo nano /etc/sysctl.conf vm.swappiness=0
Linux has several different disk schedulers, which are responsible for determining in which order read and write requests to the disk are handled. Using the noop scheduler means that Linux will simply handle requests in the order they are received, without giving any consideration to where the data physically resides on the disk. This is good for solid-state drives because they have no moving parts, and seek times are identical for all sectors on the disk, but there are other alternatives, too. To see which scheduler your system is using, view the contents of /sys/block/sda/queue/scheduler:
The scheduler currently in use is listed in brackets:
[noop] deadline cfq
For a good description of the different schedulers available in Linux, check out this article at Linux Magazine. The scheduler helps organize reads and writes in the I/O queue to maximise performance. The default scheduler in the Linux kernel is CFQ (Completely Fair Queuing), which is designed with the rotational latencies of spinning platter drives in mind. So while it works well for standard hard drives, it doesn’t work so well when it comes to SSDs. Fortunately, the kernel comes with some other schedulers to play with, and here the deadline and NOOP schedulers are ideal. Both are basic schedulers that guarantee fast turnaround of I/O requests. NOOP is basically no scheduler at all, it’s a basic FIFO (First In, First Out) queue whereas deadline does some sorting to guarantee read requests take priority over write, which is useful if you want to guarantee read responsiveness under heavy writes. Changing scheduler is easy, and even better – you can do it on a per-device basis if you have a mixed SSD and spinning platter hard drive system, using deadline for SSDs and CFQ for traditional drives. As CFQ is the default, change SSDs to use deadline by opening up a terminal and running:
sudo nano -w /etc/rc.local
Then add the following line for each SSD in your system:
echo deadline >/sys/block/sda/queue/scheduler
Changing ‘sda‘ to ‘sdb‘ and so on for each SSD device. If you only have SSDs in your system, you can set the global scheduler policy to apply to all devices at boot time instead. For Ubuntu and other distributions using GRUB2, edit the /etc/default/grub file and add ‘deadline‘ to the GRUB_CMDLINE_LINUX_DEFAULT line like this:
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash elevator=deadline"
Move your browsers cache to a tmpfs in RAM
For most of us, using Firefox and Chromium is probably responsible for the largest percentage of our disk activity. To reduce the number of writes to the disk you can move your cache to a tmpfs filesystem. Your browser cache will be stored in your physical memory (RAM), bypassing the need to store it on the disk altogether. Of course, it will be wiped out when you reboot, but most people won’t really mind that. I don’t recommend this if you have less than 4GB RAM on your system.
To create a tmpfs filesystem, you’ll need to edit your /etc/fstab file again. Adding the following line will convert your system’s /tmp directory to tmpfs:
none /tmp tmpfs defaults 0 0
If you’ve verified that your tmpfs has been created, open Firefox and enter
in the location bar. Right-click and choose the option:
Enter (without quote marks):
- “browser.cache.disk.parent_directory” for the preference name, and
- “/tmp/firefox-cache” for the string value
Restart Firefox, and look inside the /tmp directory to make sure the browser’s cache is being written to the new location.
With Chromium the trick is not that easy, since the location of the cache files can’t be easily entered over the browser settings or about:config parts. For Ubuntu 12.04 I tried entering the following into a terminal:
sudo gedit /etc/chromium-browser/default
Comment out the line containing (include a # character at the beginning of the line):
and add this line to it to get a 300MB cache size:
After restarting your chromium browser your cache files should be running on the /tmp/chromium/ directory.
After making so many changes to your system, check that everything is working using the mount command in a terminal. In my case it looks like:
/dev/sda1 on / type ext4 (rw,noatime,nodiratime,errors=remount-ro,discard) proc on /proc type proc (rw,noexec,nosuid,nodev) sysfs on /sys type sysfs (rw,noexec,nosuid,nodev) none on /sys/fs/fuse/connections type fusectl (rw) none on /sys/kernel/debug type debugfs (rw) none on /sys/kernel/security type securityfs (rw) udev on /dev type devtmpfs (rw,mode=0755) devpts on /dev/pts type devpts (rw,noexec,nosuid,gid=5,mode=0620) none on /tmp type tmpfs (rw) tmpfs on /run type tmpfs (rw,noexec,nosuid,size=10%,mode=0755) none on /run/lock type tmpfs (rw,noexec,nosuid,nodev,size=5242880) none on /run/shm type tmpfs (rw,nosuid,nodev) gvfs-fuse-daemon on /home/danny/.gvfs type fuse.gvfs-fuse-daemon (rw,nosuid,nodev,user=danny) gvfs-fuse-daemon on /root/.gvfs type fuse.gvfs-fuse-daemon (rw,nosuid,nodev)