Quota
=====

Quota backend specifies the method how Dovecot keeps track of the current quota
usage. They don't (usually) specify users' quota limits, that's done by
<returning extra fields from userdb> [Quota.Configuration.txt]. There are
different quota backends that Dovecot can use:

 * <fs> [Quota.FS.txt]: Filesystem quota.
 * <dirsize> [Quota.Dirsize.txt]: The simplest and slowest quota backend, but
   it works quite well with mboxes.
 * <dict> [Quota.Dict.txt]: Store quota usage in a dictionary (e.g. SQL, or
   flat files).
 * <maildir> [Quota.Maildir.txt]: Store quota usage in Maildir++ maildirsize
   files. This is the most commonly used quota for virtual users.
 * <count> [Quota.Count.txt]: Store quota usage within Dovecot's index files.
 * <imapc> [MailboxFormat.imapc.txt]: Use quota from remote IMAP server with
   imapc.

Since v2.2.19 we recommend using <count> [Quota.Count.txt] for any new
installations. If you need usage data to an external database, consider using
<Plugins.QuotaClone.txt> for exporting the information.

Quota service
-------------

The quota service allows postfix to check quota before delivery:

---%<-------------------------------------------------------------------------
service quota-status {
    executable = quota-status -p postfix
    inet_listener {
        port = 12340
        # You can choose any port you want
    }
    client_limit = 1
}
---%<-------------------------------------------------------------------------

And then have postfix check_policy_service check that:

---%<-------------------------------------------------------------------------
smtpd_recipient_restrictions =
    ...
    check_policy_service inet:mailstore.example.com:12340
---%<-------------------------------------------------------------------------

For more about this service see
https://sys4.de/en/blog/2013/04/08/postfix-dovecot-mailbox-quota/

Enabling quota plugins
----------------------

There are three quota related plugins:

 * quota: Implements the actual quota handling and includes also all the quota
   backends.
 * imap_quota: For reporting quota information via IMAP.
 * quota_grace: Determines if and how far user can go over quota

Enable them in configuration files, e.g.:

conf.d/10-mail.conf:

---%<-------------------------------------------------------------------------
# Space separated list of plugins to load for all services. Plugins specific to
# IMAP, LDA, etc. are added to this list in their own .conf files.
mail_plugins = $mail_plugins quota
---%<-------------------------------------------------------------------------

conf.d/20-imap.conf:

---%<-------------------------------------------------------------------------
protocol imap {
  # Space separated list of plugins to load (default is global mail_plugins).
  mail_plugins = $mail_plugins imap_quota
}
---%<-------------------------------------------------------------------------

conf.d/90-quota.conf: (for use with the quota-status service)

---%<-------------------------------------------------------------------------
plugin {
    quota_grace = 10%%
    # 10% is the default
    quota_status_success = DUNNO
    quota_status_nouser = DUNNO
    quota_status_overquota = "552 5.2.2 Mailbox is full"
}
---%<-------------------------------------------------------------------------

Configuration
-------------

See <Quota.Configuration.txt> for backend-independent quota configuration.

Quota recalculation
-------------------

If your quotas are out of sync, you can use 'doveadm quota recalc -u <uid>'
command to recalculate them.

Quota and Trash mailbox
-----------------------

Standard way to expunge messages with IMAP works by:

 1. Marking message with \Deleted flag
 2. Actually expunging the message using EXPUNGE command

Both of these commands can be successfully used while user's quota is full.
However many clients use a "move-to-Trash" feature, which works by:

 1. COPY the message to Trash mailbox
 2. Mark the message with \Deleted
 3. Expunge the message from the original mailbox.
 4. (Maybe later expunge the message from Trash when "clean trash" feature is
    used)

If user is over quota (or just under it), the first COPY command will fail and
user may get an unintuitive message about not being able to delete messages
because user is over quota. The possible solutions for this are:

 * Disable move-to-trash feature from client
 * You can create a separate quota rule ignoring Trash mailbox's quota. Note
   that this would allow users to store messages infinitely to the mailbox.
 * You can create a separate quota rule giving Trash mailbox somewhat higher
   quota limit (but not unlimited).

To make sure users don't start keeping messages permanently in Trash you can
use a nightly <cronjob> [Plugins.Expire.txt] to expunge old messages from Trash
mailbox.

(This file was created from the wiki on 2019-06-19 12:42)
