An open benchmark for email clients
Mail clients, measured the same way.
One mailbox, one machine, one instrument that watches the screen — the time from a click or a keypress until the pixels stop changing. The harness, the mailbox and every raw result are on GitHub. Run it on your Mac, add your client, send a pull request.
6 clients measured · 8 defined · 2 runs
Latest results
The most recent run on each mailbox size. Lower is better throughout; the best in each test is marked, whoever has it.
Mac Studio (Apple M1 Ultra), macOS 15.460 Hz display50,000-message mailboxOctober 14, 2026
Submitted by @wes, who works on Spool. Imported from where it was first published; raw output not yet in the repository. Every number, and the notes →
Open a message
Click a message in the list until the reader has finished drawing it.
- Spool55 ms (best)
- Thunderbird◐ (partial mailbox)56 ms (best)
- Apple Mail73 ms
- MailMate150 ms
- Mailflare◐ (partial mailbox)1151 ms
- Canary Mail181 ms
2 clients are within one frame (17 ms) of the lowest, closer than the instrument can tell apart, so all of them are marked best.
- 1Mailflare. Opening a message downloads its body from the server the first time, where the other clients already have it.
Next message
Press ↓ until the next message has finished drawing.
- Spool55 ms (best)
- Apple Mail77 ms
- Canary Mail181 ms
- Mailflare◐ (partial mailbox)273 ms
- Thunderbird◐ (partial mailbox)305 ms
- MailMate423 ms
Search
Type a word into the search field until the results have finished drawing. Typing it is part of the time, about 80 ms.
- Spool61 ms (best)
- Apple Mail1120 ms
- MailMate2185 ms
- Thunderbird◐ (partial mailbox)3372 ms
- Mailflare◐ (partial mailbox)4428 ms
- Canary Mail519 ms
- 1Apple Mail. Apple Mail searches through Spotlight. The time is what a person waits for, not a comparison of search engines.
- 2MailMate. MailMate searches when Return is pressed, not as you type, so its time includes the Return.
- 3Thunderbird. The Quick Filter, Thunderbird's search-as-you-type, looks at sender, recipients and subject by default but not the message body, which is less work than full-text search.
- 4Mailflare. Searches subject, sender and preview in the messages it has downloaded, never the full text or the server, and waits 200 ms after a keystroke before it starts.
Launch
Open the app until the inbox is on screen and has stopped changing. Warm: the app has run before and its files are cached.
- Spool282 ms (best)
- Mailflare◐ (partial mailbox)521 ms
- Canary Mail1,620 ms
- Apple Mail1,691 ms
- MailMate1,909 ms
- Thunderbird◐ (partial mailbox)2,171 ms
Quit
Ask the app to quit, as the menu item does, until its process has exited. The process is checked every 2 ms.
- Spool28 ms (best)
- Canary Mail44 ms
- Mailflare◐ (partial mailbox)48 ms
- Thunderbird◐ (partial mailbox)97 ms
- MailMate196 ms
- Apple Mail218 ms
Scroll
Thirty notches of the scroll wheel until the list stops moving. Posting the thirty notches takes about 240 ms of it.
- Canary Mail305 ms (best)
- Apple Mail306 ms (best)
- MailMate319 ms (best)
- Mailflare◐ (partial mailbox)321 ms (best)
- Spool324 ms
- Thunderbird◐ (partial mailbox)571 ms
4 clients are within one frame (17 ms) of the lowest, closer than the instrument can tell apart, so all of them are marked best.
Memory
Physical footprint after the tests, as Activity Monitor counts it, including the helper processes macOS charges to the app (WebKit, GPU, networking).
- Spool144 MB (best)
- Mailflare◐ (partial mailbox)158 MB
- MailMate219 MB
- Apple Mail260 MB
- Canary Mail407 MB
- Thunderbird◐ (partial mailbox)1,148 MB
Idle CPU
Share of one core used over ten seconds of the app sitting idle after the tests.
- MailMate0.2% (best)
- Spool1.1%
- Apple Mail1.7%
- Canary Mail2.1%
- Mailflare◐ (partial mailbox)13.4%
- Thunderbird◐ (partial mailbox)4.1%
- 1Mailflare. Includes re-checking the newest 50 messages in every folder once a minute.
Mac Studio (Apple M1 Ultra), macOS 15.460 Hz display250,000-message mailboxOctober 15, 2026
Submitted by @wes, who works on Spool. Imported from where it was first published; raw output not yet in the repository. Every number, and the notes →
Open a message
Click a message in the list until the reader has finished drawing it.
- Spool56 ms (best)
- Thunderbird◐ (partial mailbox)74 ms
- Canary Mail121 ms
- MailMate139 ms
- Apple Mail154 ms
- Mailflare◐ (partial mailbox)1158 ms
- 1Mailflare. Opening a message downloads its body from the server the first time, where the other clients already have it.
Next message
Press ↓ until the next message has finished drawing.
- Spool54 ms (best)
- Canary Mail171 ms
- Apple Mail180 ms
- Thunderbird◐ (partial mailbox)339 ms
- MailMate454 ms
- Mailflare◐ (partial mailbox)1507 ms
- 1Mailflare. Mailflare's next message is unexplained. Because it holds about the same few hundred messages at either size, its numbers here and at 50,000 differ by noise and by things not yet pinned down, not by scale: moving to the next message took 507 ms here against 273 ms at 50,000, and nobody yet knows why.
Search
Type a word into the search field until the results have finished drawing. Typing it is part of the time, about 80 ms.
- Spool134 ms (best)
- Apple Mail1254 ms
- Thunderbird◐ (partial mailbox)2433 ms
- MailMate3440 ms
- Mailflare◐ (partial mailbox)4458 ms
- Canary Mail524 ms
- 1Apple Mail. Apple Mail searches through Spotlight. The time is what a person waits for, not a comparison of search engines.
- 2Thunderbird. The Quick Filter, Thunderbird's search-as-you-type, looks at sender, recipients and subject by default but not the message body, which is less work than full-text search.
- 3MailMate. MailMate searches when Return is pressed, not as you type, so its time includes the Return.
- 4Mailflare. Searches subject, sender and preview in the messages it has downloaded, never the full text or the server, and waits 200 ms after a keystroke before it starts.
Launch
Open the app until the inbox is on screen and has stopped changing. Warm: the app has run before and its files are cached.
- Spool321 ms (best)
- Mailflare◐ (partial mailbox)520 ms
- Apple Mail724 ms
- Canary Mail1,737 ms
- MailMate3,376 ms
- Thunderbird◐ (partial mailbox)3,603 ms
Quit
Ask the app to quit, as the menu item does, until its process has exited. The process is checked every 2 ms.
- Mailflare◐ (partial mailbox)40 ms (best)
- Spool42 ms (best)
- Canary Mail74 ms
- Apple Mail116 ms
- Thunderbird◐ (partial mailbox)128 ms
- MailMate341 ms
2 clients are within 2 ms of the lowest, closer than the instrument can tell apart, so all of them are marked best.
Scroll
Thirty notches of the scroll wheel until the list stops moving. Posting the thirty notches takes about 240 ms of it.
- Spool321 ms (best)
- Canary Mail328 ms (best)
- Mailflare◐ (partial mailbox)331 ms (best)
- MailMate337 ms (best)
- Apple Mail343 ms
- Thunderbird◐ (partial mailbox)580 ms
4 clients are within one frame (17 ms) of the lowest, closer than the instrument can tell apart, so all of them are marked best.
Memory
Physical footprint after the tests, as Activity Monitor counts it, including the helper processes macOS charges to the app (WebKit, GPU, networking).
- Spool129 MB (best)
- Mailflare◐ (partial mailbox)143 MB
- Canary Mail318 MB
- Apple Mail344 MB
- MailMate548 MB
- Thunderbird◐ (partial mailbox)1,040 MB
Idle CPU
Share of one core used over ten seconds of the app sitting idle after the tests.
- MailMate0.1% (best)
- Spool0.6%
- Mailflare◐ (partial mailbox)10.9%
- Thunderbird◐ (partial mailbox)2.5%
- Apple Mail224.3%
- Canary Mail2163.0%
- 1Mailflare. Includes re-checking the newest 50 messages in every folder once a minute.
- 2Apple Mail, Canary Mail. Idle CPU was taken straight after the tests. Apple Mail and Canary were both still working at that point — Apple Mail at a quarter of a core, Canary at more than one and a half — and the numbers say so rather than waiting until they stopped.
What makes it fair
The same mailbox, byte for byte
A generated mailbox of 50,000 or 250,000 messages, identical on every machine that generates it and checked against a published digest. Served by Dovecot on the same Mac, so no client is helped or hurt by a network.
Measured from outside
A small tool posts a real click or keypress and watches the window through ScreenCaptureKit. It needs nothing from the app under test, which is the only way to put different apps in one table.
Finished, not started
Each time runs from the event until the window stops changing. An app that paints a spinner quickly and the message slowly gets the slow number.
A frame is the resolution
The screen is read once a frame, so results within one frame of the fastest are a tie, and are shown as one. The instrument’s own overhead is measured on every machine and published beside its results.
Every client does the whole job
Each one is set to keep the full mailbox locally. Where a client cannot, its numbers are marked, next to the numbers, as a smaller job than everyone else’s.
Numbers nobody can edit
The published numbers are generated from the instrument’s raw output, which is committed with them. CI regenerates them on every change and fails if one differs.
Who runs this
Started by the author of one of the clients here.
mailbench began as the benchmark harness for Spool, written by @wes. That is a conflict of interest, and this project is set up to make it not matter: the instrument treats every client identically and from the outside, the mailbox is the same bytes everywhere, every published number is regenerated from raw output by CI, and every run says who submitted it and which clients they work on.
If you find anything that favours one client — a setting, a coordinate, a word on this site — that is a bug. Open an issue. Client authors are especially welcome to maintain their own client’s definition.
Make a mail client? Add it.
A client is one JSON file: where its window keeps the message list, the reader and the search field. The harness does the rest, the same way it does for everyone.
How to add a client →Different hardware? Run it.
An afternoon of setup on a Mac, then one command per client. ./mailbench submit turns the results into a pull request, and they appear here once it is merged.