Tune your PostgreSQL and get 10x faster tests
For me, the biggest annoyance when running tests is the time that they need to be finished. In a customer's project, we are using RSpec with PostgreSQL. I noticed that, when running the tests, the hard disk was specially noisy. I was curious about what was having so many access to the disk, so I used pidstat to find out it.
$ sudo pidstat -d 3 -T TASK Linux 3.2.0-2-amd64 (silencio) 12/09/12 _x86_64_ (4 CPU) 01:29:21 PID kB_rd/s kB_wr/s kB_ccwr/s Command 01:29:24 222 0,00 1,33 0,00 jbd2/sda5-8 01:29:24 1562 0,00 40,00 0,00 jbd2/dm-7-8 01:29:24 4203 0,00 4,00 0,00 gnome-terminal 01:29:24 6373 0,00 41,33 0,00 postgres 01:29:24 6376 0,00 10,67 0,00 postgres 01:29:24 6378 0,00 165,33 0,00 postgres 01:29:24 6579 0,00 8,00 0,00 ruby 01:29:24 6612 0,00 480,00 72,00 postgres 01:29:24 PID kB_rd/s kB_wr/s kB_ccwr/s Command 01:29:27 1562 0,00 34,67 0,00 jbd2/dm-7-8 01:29:27 4203 0,00 1,33 0,00 gnome-terminal 01:29:27 6373 0,00 41,33 0,00 postgres 01:29:27 6376 0,00 13,33 0,00 postgres 01:29:27 6378 0,00 165,33 0,00 postgres 01:29:27 6612 0,00 226,67 0,00 postgres
The output is longer, but this fragment is enough to see that PostgreSQL is doing a lot of I/O operations. If you take a closer look, you will notice that all operations are writing (the kB_rd/s column is always 0,00). We can assume that (almost) everything needed to manage the queries is cached on memory, so no read operation is needed.
I was wondering how I could reduce the write accesses. Thus, the performance should improve. I decided to play with the configuration options for the PostgreSQL WAL. In Debian, these options can be modified in /etc/postgresql/9.1/main/postgresql.conf.
The changes are:
work_mem = 100MB fsync = off wal_writer_delay = 10000
With this three options I ran the tests again, and I was impressed by the results. Previously, the tests was taking 21 minutes to finish:
Finished in 22 minutes 18.48 seconds 146 examples, 0 failures
Now, the time is just 2 minutes. This is, 10x faster:
Finished in 2 minutes 53.25 seconds 146 examples, 0 failures
Obviously, your mileage may vary. The difference will be smaller if your disk are fast. But, anyway, this will improve the time needed to run the tests.
Don't do this in production
The default values are better for a production environment. What we are doing here is to reduce the disk access, but that is not a good idea if you are managing real data. In a test/development environment, we can loss data and still be alive





