Choosing Dovecot’s Mail Storage: Maildir vs. mdbox/sdbox for High‑Volume Servers
When running a large mail server with thousands of users, the choice of storage format can affect performance, reliability, and maintenance. This post compares Dovecot’s Maildir, mdbox, and sdbox, shows how to convert between them, and explains the trade‑offs you should weigh before making decision.
17 Jul 2025, 07:21 UTC

Why the storage format matters
In Dovecot, the mail_location setting tells the server where to find each mailbox. The format you choose determines how often the server touches the file system, how many inodes you consume, and how resilient the data is to crashes. For a server that receives and stores thousands of messages per day, these differences can become the difference between smooth operation and a hard‑to‑debug outage.
Three options in a nutshell
- Maildir – one file per message, stored in a directory tree. Very reliable, but can exhaust inodes on filesystems with a low inode limit.
- mdbox – a binary bundle that packs many messages into a single file. Reduces inode usage and can improve read/write throughput, but a single corrupt file can affect many messages.
- sdbox – a hybrid that keeps larger messages in separate files while still packing small ones into a bundle. A compromise between the two extremes.
When to pick each format
Below is a quick decision matrix. The numbers are illustrative; your real thresholds will depend on your filesystem and workload.
| Metric | Maildir | mdbox | sdbox |
|---|---|---|---|
| Maximum messages per mailbox | Unlimited (inode‑limited) | ~10 000 per file (configurable) | Same as mdbox, but large messages stay separate |
| Crash resilience | High – atomic file creation | Low – one corrupt file can damage many messages | Medium – large messages safe, small ones bundled |
| Write throughput | Moderate – many small file ops | High – single file writes | High – most writes go to bundle |
| Read latency | Low for single messages (no index) | Very low – index jumps directly to message | Very low – same as mdbox for most messages |
| Inode usage | High – one per message | Low – one per mailbox | Low – one per mailbox + a few large files |
| Migration effort | None – native format | Requires doveadm convert and temporary space | Same as mdbox |
Practical conversion example
Assume you have a mailbox at /var/mail/vhosts/example.com/alice using Maildir, and you want to switch to mdbox for performance. Here’s a step‑by‑step guide you can run on a Linux host with Dovecot 3.4+.
- Verify current format
# grep mail_location /etc/dovecot/dovecot.conf mail_location = maildir:/var/mail/vhosts/%d/%nMake sure the path points to a Maildir structure (ends with
maildir:). - Back up the mailbox
# tar -czf /tmp/alice-backup.tgz /var/mail/vhosts/example.com/aliceStore the archive outside the mailbox directory to avoid accidental truncation.
- Stop Dovecot (or use
doveadm shutdownfor a graceful stop)# systemctl stop dovecot - Configure the new format
# sed -i 's/maildir:/mdbox:/g' /etc/dovecot/dovecot.conf # systemctl start dovecotNow Dovecot will create an
mdboxfile in the same directory. - Convert the mailbox
# doveadm -u alice convert mdbox:/var/mail/vhosts/example.com/aliceThis command copies messages from the Maildir into a new
mdboxfile, preserving flags and timestamps. The operation can take minutes on a large mailbox; monitordoveadm logfor progress. - Verify the conversion
# doveadm mailbox list # doveadm -u alice fetch 1:1Check that the mailbox shows up as
mdboxand that you can fetch a message without errors. - Cleanup
# rm -r /var/mail/vhosts/example.com/alice/*maildir* # rm -rf /var/mail/vhosts/example.com/alice/.maildir*Remove the old Maildir directory to free space.
During the conversion you should monitor disk usage with df -h and inode counts with df -i. If the host runs out of inodes, the conversion will fail; you can pause, free space, and resume.
Limitations and risks
- Hard crashes – if the server or filesystem crashes while writing to an
mdboxfile, the entire bundle can become unreadable. Use journaling filesystems (ext4 with journaling, XFS) and ensure regular backups. - Concurrency – a single mailbox file can become a bottleneck under extreme write loads. For a multi‑core server with many simultaneous senders, consider splitting the mailbox into multiple
mdboxfiles or usingsdboxto keep large attachments separate. - Conversion cost – the
doveadm convertstep requires disk space roughly equal to the size of the mailbox, because it writes a new file while the old one remains. Plan for that when converting large mailboxes. - Index corruption – the internal index files (
index,index.1, etc.) can become corrupted if the filesystem is damaged. In such cases, rundoveadm index -fto rebuild.
Actionable next steps
1. Audit inode usage on your current server:
# df -i /var/mail
If you’re close to the inode limit, consider moving to mdbox or sdbox.
doveadm fetch or a real IMAP client to measure read/write latency under simulated load.
3. Plan a staged migration. Convert a subset of mailboxes during off‑peak hours, verify performance, then roll out to the rest.
4. Set up monitoring for mailbox size and index health. Dovecot’s doveadm monitor can alert you if a mailbox becomes unreadable.
Choosing the right storage format is a balancing act. Maildir offers the simplest crash safety, mdbox maximizes throughput and reduces inode pressure, and sdbox gives you the best of both worlds for large attachments. By following the steps above, you can evaluate each option in your environment, convert safely, and keep your mail server running smoothly even as traffic grows.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.