Why we benchmarked our own tool against imapsync

imapsync is the long-established open-source standard for IMAP-to-IMAP migration, and it is a good tool. When we built IMAPLANE, our in-house Rust migration engine, we wanted to know where it is better, where it is worse, and why, instead of assuming that our design choices were free.

This post summarizes that benchmark. All numbers come from the project's own benchmark report and changelog. They were measured on one laptop against local test servers, so read them as a comparison under controlled conditions, not as a prediction for your mailbox on your network.

How the test was run

Two identical Dovecot 2.3.21 containers acted as source and destination, with both tools running in the same runner image under the same CPU and memory limits (2 CPUs and 2 GiB). The imapsync version was 2.314, run both with defaults and in a tuned configuration. The dataset held 3,280 messages (395 MB) in 9 folders, with nested and Unicode folder names, attachments up to 7.3 MB, messages without a Message-ID, mixed flags, dates across eight time zones, and four kinds of duplicate-looking mail.

Correctness was checked by an independent verifier that compares multisets of SHA-256, flags and INTERNALDATE across both servers, so a doubled message cannot be counted as a copy and a dropped message cannot hide behind a duplicate. Runs were repeated, interleaved and checked for isolation.

Verification levels are not equivalent

The tools do different amounts of work, and a fair comparison has to say so. After a fresh copy, IMAPLANE has read every message back from the destination and compared it by SHA-256, INTERNALDATE and flags. imapsync treats a message as present when its header-derived identifier matches, and does not read content back.

That extra read-back is part of why IMAPLANE does more work per message. It is also the reason IMAPLANE can tell you which messages are proven and which are not.

Speed: imapsync is faster at a fresh copy

On the 3,280-message dataset, imapsync finished a fresh copy in about 65 seconds. The first IMAPLANE build took about 244 seconds, roughly 3.8 times slower. Profiling showed that about 72 percent of IMAPLANE's time went into durable journal commits, not into verification, which accounted for about 3 percent.

The fix kept every durability guarantee. Moving the SQLite journal to write-ahead logging with synchronous=FULL, plus fdatasync, cut a full copy from about 245 seconds to about 105 seconds, against about 66 seconds for tuned imapsync. imapsync is still faster, and we say so. Disk sync latency is a property of the storage, so the gap shrinks on faster disks and grows on slower ones.

  • Fresh copy, first build: imapsync about 65 s, IMAPLANE about 244 s
  • Fresh copy after the journal change: about 105 s for IMAPLANE against about 66 s for tuned imapsync
  • Peak memory: IMAPLANE 17 to 35 MiB, imapsync about 190 MiB
  • No-change rerun at the default level: IMAPLANE 0.4 s, imapsync 1.2 to 2.1 s, but the IMAPLANE default is a metadata check and not a content check
  • Full content re-check of the 395 MB mailbox: about 8 s, with no imapsync equivalent

Completeness: no message left behind

IMAPLANE copied all 3,280 messages, including every duplicate-looking one. With default settings, imapsync left 160 messages uncopied in every run and exited successfully, because its header-based duplicate detection treats exact duplicates and same-Message-ID messages as already present. This is imapsync's documented design, and its tuned configuration (using UIDs with a persistent cache) copied everything.

One difference runs the other way: IMAPLANE never copies the \Deleted flag. In the test, 30 messages carried that flag at the source, so their flags differ at the destination while content and dates are exact.

Crash recovery: no duplicates, but a manual step

Each tool was killed four times with SIGKILL in the middle of a transfer and then resumed. Neither tool produced a duplicate or silently lost a message. imapsync re-derived its state from the destination by itself each time. IMAPLANE needed an operator step (recover or resolve) in two of four kills, because it marks an upload as uncertain when it cannot prove what happened and refuses to guess.

That is the price of its stronger evidence. The sample is small, so treat these as counts rather than rates.

What the benchmark does not cover

It ran at LAN latency on one machine and one Dovecot version. It did not test real providers such as Gmail or Microsoft 365, mailboxes beyond 5,000 messages of small size, concurrent jobs, or imapsync features outside the test. IMAPLANE is documented as a technical preview, XOAUTH2 against live Gmail and Microsoft 365 accounts is untested, and Gmail silently merges identical messages, which IMAPLANE detects and reports instead of hiding.

What this means for a real migration

For our clients, the trade-off fits how migrations are actually staged: speed matters less when the baseline copy runs in the background for days, and proof matters more at cutover. We pilot every project on a small folder first and give you a written report of what was verified and how. Through our Email Migration Calgary service we scope the work in writing before any billable hours begin, and our business email and identity services cover the account setup around it.

Written by YYCIT Systems Engineering

We design, deploy, and manage Linux servers, OpenStack clouds, and high-reliability systems for Calgary businesses. Direct engineering access with published $115–$150/hr rates and zero contract lock-in.