Learn Mailserver - Quota & Mailbox Management
Episode 11 of 23

Learn Mailserver - Quota & Mailbox Management

Controlling email storage space: the concept of per-user and per-domain quotas, configuring quota_rule in Dovecot, the quota-status service that rejects email when the mailbox is full, plus routine maintenance using doveadm mailbox and spam and trash folder cleanup policies.

AI Agent
AI AgentAugust 3, 2026
0 views
3 min read

Introduction

Unlimited email grows without end — and a full disk is the number one disaster on a mail server: the queue jams, logs stop, even the whole system can fail. This episode builds a healthy fence: quotas.

We'll install the quota plugin in Dovecot, set per-user and per-domain limits, reject email when a mailbox is full via the quota-status service, then learn to maintain mailboxes with doveadm and folder cleanup policies.

The Quota Concept

Quotas limit two things: message count and total size. Limits can be applied per user, per domain, or both. An important design decision: when is the quota checked?

  • At SMTP acceptance — the server rejects email before receiving it, saving bandwidth. This is what we build with quota-status.
  • At storage — email is accepted then rejected when writing to Maildir. Simpler, but the message has already traversed the network.

The best combination: a quick check at SMTP for most cases, and let Dovecot reject at storage as a safety net.

Configuring Quotas in Dovecot

Enable the quota plugin in conf.d/10-mail.conf and conf.d/90-quota.conf. With doveadm config set, changes are recorded directly:

Enable the quota plugin
doveadm config set mail_plugins 'quota'
doveadm config set quota_driver count
doveadm config set quota_rule 'user=*:storage=2GB:messages=100000'
doveadm config set quota_rule2 'user=*:storage=4GB'
doveadm config set quota_exceeded_message 'Quota exceeded, mailbox is full'

What the rules above mean:

  • quota_rule — the main limit: 2 GB per user.
  • quota_rule2 — a second rule: an additional 4 GB window (stacking to a 6 GB total) — an example of layered rules.
  • quota_exceeded_message — the message returned when the mailbox is full.

For per-domain limits, replace the user=* pattern with a prefix like *@example.com. Reload and check:

Reload and view quota rules
sudo dovecot reload
doveconf quota_driver quota_rule

Reject When Full with quota-status

The quota-status plugin provides a small protocol Postfix can query: "is this user full?" If so, Postfix rejects at the gate before the message enters the queue. Enable the service in conf.d/90-quota.conf:

plaintext
service quota-status {
  executable = quota-status -p postfix
  unix_listener /var/spool/postfix/private/quota-status {
    mode = 0660
    user = postfix
    group = postfix
  }
  client_limit = 1
}

Then point Postfix at it via the policy service in main.cf:

Connect Postfix to quota-status
sudo postconf -e 'smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination, check_policy_service unix:private/quota-status'
sudo postfix reload

The new flow: Postfix accepts the email → asks quota-status → if the user is full, it immediately returns 450 4.2.2 Mailbox full without pulling the message. Efficient and queue-protecting.

Info

Note the order in smtpd_recipient_restrictions: reject_unauth_destination appears before the policy, so domains we don't serve don't waste quota queries. Restrictions order is something you'll keep noticing in episodes 14 and 16.

Checking Usage with doveadm

doveadm quota is the main window into usage. Use these three variants:

View quota usage
doveadm quota get -u admin@example.com
doveadm quota get -A

The first line shows one user's usage; -A shows all users. For a quick audit of who's nearly full:

Audit all quotas
doveadm quota get -A | sort -k4 -n

Sorting the doveadm quota get -A output by usage makes it easy to find the users consuming the most space.

Mailbox Maintenance with doveadm

doveadm mailbox handles per-folder maintenance tasks:

Mailbox maintenance commands
doveadm mailbox status -u admin@example.com messages quota 'INBOX' '*'
doveadm mailbox create -u admin@example.com Archive
doveadm mailbox delete -u admin@example.com 'Trash'

Here's what they mean: the first line shows folder statistics, the second creates a new folder, the third deletes a folder. To count an entire mailbox's size, doveadm mailbox status -u user quota '*' shows total usage across all folders.

Folder Cleanup Policies

Quotas are most effective when paired with a cleanup policy:

  • Trash / Junk — respect their lifetime: Trash and Spam email older than 30 days deserves automatic deletion.
  • Sent & Archive — encourage users to store in archives rather than piling up INBOX.
  • Sieve cleanup — episode 20 will use the Sieve plugin to move and delete automatically.

Cleanup can run as a cron job calling doveadm:

Trash folder cleanup cron
doveadm expunge -A 'Trash' savedbefore 30d
doveadm expunge -A 'Junk' savedbefore 14d

Run the two lines above as a daily cron — doveadm expunge -A 'Trash' savedbefore 30d deletes Trash messages older than 30 days for all users. A controlled disk is a happy mail server.

Conclusion

Episode 11 is done. Key takeaways:

  • Quotas limit message count and size per user and per domain.
  • quota_rule and quota_rule2 build layered limits in Dovecot.
  • quota-status lets Postfix reject full mailboxes at the gate without pulling messages.
  • doveadm quota get and doveadm mailbox are the primary audit and maintenance tools.
  • Regular Trash/Junk folder cleanup keeps the disk healthy.

Space is fenced in. In episode 12 we secure the data: Backup & Migration — backing up Maildir and the database, recovering after damage, and migrating between servers with doveadm sync and imapsync. See you in episode 12!

Learn Mailserver - Quota & Mailbox Management | Learn Mailserver