Benchmarking IMAP servers
There will be 4 tests against mailboxes of varying sizes; 100, 1000, and 10000 messages. Each of the tests will be repeated in full 5 times, and an average calculated.
Test #1: A stat of a fresh mailbox - at this point the mailbox will never have been accessed Test #2: A stat of the mailbox again Test #3: Accessing message 85 - a ‘random’ message Test #4: Flagging all messages as deleted, and then expunging them
The tests currently will be run against cyrus and courier imap servers. Configs are left as-is except what was required to change to get the mailboxes working with plain text login.
Hardware
The tests were run on a old p3 server, with a single IDE hard disk drive. The system is on a single partition (except / boot) which is formatted as EXT3.
# cat /proc/cpuinfo processor : 0 vendor_id : GenuineIntel cpu family : 6 model : 8 model name : Pentium III (Coppermine) stepping : 3 cpu MHz : 802.043 cache size : 256 KB fdiv_bug : no hlt_bug : no f00f_bug : no coma_bug : no fpu : yes fpu_exception : yes cpuid level : 2 wp : yes flags : fpu vme de pse tsc msr pae mce cx8 sep mtrr pge mca cmov pat pse36 mmx fxsr sse bogomips : 1581.05
Software
Distro: Gentoo 2005.1 Kernel: Linux p3 2.6.12-gentoo-r6 net-mail/cyrus-imapd-2.2.12 -afs -drac -idled -kerberos +pam -snmp +ssl +tcpd mail-mta/exim-4.50-r1 -X -dnsdb -exiscan -exiscan-acl -ipv6 -ldap +lmtp -mailwrapper -mbox -mysql -nis +pam +perl -postgres -sasl +ssl -syslog +tcpd net-mail/courier-imap-4.0.1 +berkdb -debug -fam +gdbm -ipv6 +nls (-selinux)
Scripts used
Script used to create test data
Main test script: test.sh
#!/bin/sh NUM_MAILS=10000 USER="cyrus" PASS="password" ./emails.sh $NUM_MAILS $USER ./virgin.pl localhost $USER $PASS ./virgin.pl localhost $USER $PASS ./fetch.pl localhost $USER $PASS ./delete.pl localhost $USER $PASS $NUM_MAILS
email.sh
#!/bin/sh
n=0
while test $n -lt $1
do
echo "this is a test mail!!!" | uuencode - | mail -s "Test message $n" $2
n=`expr $n + 1`
done
./virgin.pl
#!/usr/bin/perl -w
use Expect;
use Time::HiRes qw(gettimeofday tv_interval);
die "Usage: $0 server user password\n" if $#ARGV != 2;
our $server=$ARGV[0];
our $user=$ARGV[1];
our $password=$ARGV[2];
our $ok = '^\d+\s+OK';
print "Testing select on $user\n";
my $exp = Expect->spawn("telnet", "$server", "143") or die "Could not connect";
$exp->expect(2, "-re", '^\* OK') or die "didn't see OK";
$exp->send("001 LOGIN $user $password\n");
$exp->expect(20, "-re", "$ok") or die "didn't see OK";
$t0 = [gettimeofday];
$exp->send("002 SELECT INBOX\n");
$exp->expect(30, "-re", "$ok") or die "didn't see OK";
$time = tv_interval($t0 , [gettimeofday]);
$exp->send("002 LOGOUT\n");
$exp->expect(5, "-re", "$ok") or die "didn't see OK";
$exp->hard_close();
open (LOGFILE, ">> output.log");
print LOGFILE "\nSelect INBOX Time: ", $time, " s\n";
close LOGFILE;
fetch.pl
#!/usr/bin/perl -w
# This test does a set of uid fetches
use Expect;
use Time::HiRes qw(gettimeofday tv_interval);
my @commands = (
"SELECT INBOX",
"FETCH 85 (FLAGS BODYSTRUCTURE)",
"FETCH 85 BODY[HEADER]",
"FETCH 85 BODY[1]"
);
die "Usage: $0 server user password\n" if $#ARGV != 2;
our $server=$ARGV[0];
our $user=$ARGV[1];
our $password=$ARGV[2];
our $ok = '^\d+\s+OK';
our $num = 2;
my $exp = Expect->spawn("telnet", "$server", "143") or die "Could not connect";
$exp->expect(2, "-re", '^\* OK') or die "didn't see OK";
$exp->send("001 LOGIN $user $password\n");
$exp->expect(5, "-re", "$ok") or die "didn't see OK";
$t0 = [gettimeofday];
for $command (@commands) {
$exp->send(sprintf("%03d %s\n", $num++, $command));
$exp->expect(20, "-re", "$ok") or die "didn't see OK";
}
$time = tv_interval($t0 , [gettimeofday]);
$exp->send("999 LOGOUT\n");
$exp->expect(5, "-re", "$ok") or die "didn't see OK";
$exp->hard_close();
open (LOGFILE, ">> output.log");
print LOGFILE "\nFetch Mail 85 Time: ", $time, " s\n";
close LOGFILE;
delete.pl
#!/usr/bin/perl -w
# This test does a deletion of 10 messages, including the expunge
use Expect;
use Time::HiRes qw(gettimeofday tv_interval);
die "Usage: $0 server user password\n" if $#ARGV != 3;
our $server=$ARGV[0];
our $user=$ARGV[1];
our $password=$ARGV[2];
our $ok = '^\d+\s+OK';
our $num = 2;
my @commands = (
'SELECT INBOX',
'STORE 0:' . $ARGV[3] . ' +FLAGS (\Deleted)',
'EXPUNGE',
);
my $exp = Expect->spawn("telnet", "$server", "143") or die "Could not connect";
$exp->expect(5, "-re", '^\* OK') or die "didn't see OK";
$exp->send("001 LOGIN $user $password\n");
$exp->expect(5, "-re", "$ok") or die "didn't see OK";
$t0 = [gettimeofday];
for $command (@commands) {
$exp->send(sprintf("%03d %s\n", $num++, $command));
$exp->expect(600, "-re", "$ok") or die "didn't see OK";
}
$time = tv_interval($t0 , [gettimeofday]);
$exp->send("999 LOGOUT\n");
$exp->expect(5, "-re", "$ok") or die "didn't see OK";
$exp->hard_close();
open (LOGFILE, ">> output.log");
print LOGFILE "\nDelete All Mail Time: ", $time, " s\n";
close LOGFILE;
Exim Setup
begin routers
router_courier:
driver = accept
local_parts = courier
transport = transport_courier
route_cyrus:
driver = accept
local_parts = cyrus
transport = transport_cyrus
begin transports
transport_courier:
driver = appendfile
directory = /var/spool/mail/$local_part/Maildir
maildir_format
delivery_date_add
envelope_to_add
return_path_add
group = mail
mode = 0660
transport_cyrus:
driver = pipe
user = cyrus
group = mail
message_prefix = ""
message_suffix = ""
log_fail_output
return_output
envelope_to_add = true
command = "/usr/lib/cyrus/deliver -r $return_path $local_part"
Setting up Courier
# userdb courier set home=/var/spool/mail/courier/Maildir/ mail=/var/spool/mail/courier/Maildir/ uid=8 gid=12 # userdbpw -md5 | userdb courier set systempw Password: Reenter password:
Setting up Cyrus
# saslpasswd2 cyrus Password: # cyradm --user cyrus localhost Password: localhost> cm user.cyrus #
Results
Cyrus with 100 emails
| Pass #1 | Pass #2 | Pass #3 | Pass #4 | Pass #5 | Avg. | |
|---|---|---|---|---|---|---|
| Select INBOX Time | 0.02079 s | 0.026778 s | 0.017001 s | 0.01661 s | 0.022283 s | 0.0206924 s |
| Select INBOX Time | 0.016981 s | 0.016437 s | 0.0174 s | 0.016668 s | 0.016487 s | 0.0167946 s |
| Fetch Mail 85 Time: | 0.027505 s | 0.026558 s | 0.02679 s | 0.027753 s | 0.027234 s | 0.027168 s |
| Delete All Mail Time: | 0.71607 s | 0.712235 s | 0.700168 s | 0.628634 s | 0.695603 s | 0.690542 s |
Cyrus with 1000 emails
| Pass #1 | Pass #2 | Pass #3 | Pass #4 | Pass #5 | Avg. | |
|---|---|---|---|---|---|---|
| Select INBOX Time | 0.017401 s | 0.028108 s | 0.018 s | 0.018645 s | 0.027476 s | 0.021926 s |
| Select INBOX Time: | 0.01735 s | 0.016473 s | 0.01748 s | 0.016768 s | 0.017668 s | 0.0171478 s |
| Fetch Mail 85 Time: | 0.02844 s | 0.028391 s | 0.028335 s | 0.028039 s | 0.029717 s | 0.0285844 s |
| Delete All Mail Time: | 6.357008 s | 6.722728 s | 6.547113 s | 6.518259 s | 6.26573 s | 6.4821676 s |
Cyrus with 10000 emails
| Pass #1 | Pass #2 | Pass #3 | Pass #4 | Pass #5 | Avg. | |
|---|---|---|---|---|---|---|
| Select INBOX Time | 0.02509 s | 0.024013 s | 0.024759 s | 0.039652 s | 0.044786 s | 0.03166 s |
| Select INBOX Time: | 0.023885 s | 0.022277 s | 0.023066 s | 0.024021 s | 0.023261 s | 0.023302 s |
| Fetch Mail 85 Time: | 0.034599 s | 0.034738 s | 0.034921 s | 0.034499 s | 0.03485 s | 0.0347214 s |
| Delete All Mail Time: | 63.572404 s | 64.103166 s | 64.885044 s | 64.525608 s | 64.575804 s | 64.3324052 s |
Courier with 100 emails
| Pass #1 | Pass #2 | Pass #3 | Pass #4 | Pass #5 | Avg. | |
|---|---|---|---|---|---|---|
| Select INBOX Time | 0.016494 s | 0.016528 s | 0.017743 s | 0.019349 s | 0.020325 s | 0.0180878 s |
| Select INBOX Time | 0.011814 s | 0.011904 s | 0.013547 s | 0.014432 s | 0.014947 s | 0.0133288 s |
| Fetch Mail 85 Time: | 0.100413 s | 0.103036 s | 0.102572 s | 0.104415 s | 0.104242 s | 0.1029266 s |
| Delete All Mail Time: | 0.100758 s | 0.113163 s | 0.111109 s | 0.118635 s | 0.131973 s | 0.1151276 s |
Courier with 1000 emails
| Pass #1 | Pass #2 | Pass #3 | Pass #4 | Pass #5 | Avg. | |
|---|---|---|---|---|---|---|
| Select INBOX Time | 0.286212 s | 0.268349 s | 0.318321 s | 0.327233 s | 0.338235 s | 0.30167 s |
| Select INBOX Time | 0.037391 s | 0.046393 s | 0.052735 s | 0.062361 s | 0.072064 s | 0.0541888 s |
| Fetch Mail 85 Time: | 0.128323 s | 0.136582 s | 0.139927 s | 0.148851 s | 0.15892 s | 0.1425206 s |
| Delete All Mail Time: | 1.150425 s | 1.760016 s | 2.458087 s | 4.20293 s | 6.827013 s | 3.2376942 s |
Courier with 10000 emails
| Pass #1 | Pass #2 | Pass #3 | Pass #4 | Pass #5 | Avg. | |
|---|---|---|---|---|---|---|
| Select INBOX Time | 43.05989 s | 42.14172 s | 41.156438 s | 42.457034 s | 40.053152 s | 41.7736468 s |
| Select INBOX Time | 0.303113 s | 0.299262 s | 0.299641 s | 0.30249 s | 0.304539 s | 0.301809 s |
| Fetch Mail 85 Time: | 0.386024 s | 0.389193 s | 0.389436 s | 0.391477 s | 0.392033 s | 0.3896326 s |
| Delete All Mail Time: | 131.052095 s | 133.001318 s | 131.905814 s | 129.643691 s | 128.014233 s | 130.7234302 s |
100 emails
| Cyrus | Courier | Dovecot | Diff. | |
|---|---|---|---|---|
| Select INBOX Time | 0.0206924 s | 0.0180878 s | ||
| Select INBOX Time | 0.0167946 s | 0.0133288 s | ||
| Fetch Mail 85 Time: | 0.027168 s | 0.1029266 s | ||
| Delete All Mail Time: | 0.690542 s | 0.1151276 s |
1000 emails
| Cyrus | Courier | Dovecot | Diff. | |
|---|---|---|---|---|
| Select INBOX Time | 0.021926 s | 0.30167 s | ||
| Select INBOX Time | 0.0171478 s | 0.0541888 s | ||
| Fetch Mail 85 Time: | 0.0285844 s | 0.1425206 s | ||
| Delete All Mail Time: | 6.4821676 s | 3.2376942 s |
10000 emails
| Cyrus | Courier | Dovecot | Diff. | |
|---|---|---|---|---|
| Select INBOX Time | 0.03166 s | 41.7736468 | ||
| Select INBOX Time | 0.023302 s | 0.301809 s | ||
| Fetch Mail 85 Time: | 0.0347214 s | 0.3896326 s | ||
| Delete All Mail Time: | 64.3324052 s | 130.7234302 s |
—- References: