Messages are purged by a thread that runs in the server process. The purge thread continuously iterates all the mailboxes that are in memory and purges them, one at a time. Mailboxes not in memory are not purged, to avoid the I/O cost of swapping in a mailbox only to purge it. The assumption is that if a mailbox is not in memory, it's not receiving mail and has less of a need to be purged. Bug 20720 was filed for the issue of guaranteed purging of mailboxes.
Purge thread activity is throttled by the zimbraMailPurgeSleepInterval server attribute. This value specifies the amount of time that the purge thread sleeps between subsequent purges. If the interval is set to 0, purging is turned off. The default value is "1m" (one minute).
we currently purge by date received (not by how long it's been in trash) however you can change this in ZCS 5.0.17+ by setting zimbraMailPurgeUseChangeDateForTrash TRUE bug 19702
The retention policy is specified by two sets of attributes on an account. The user retention policy set is set by the user and stored as duration attributes on the account:
The system retention policy is set by the administrator. These attributes are also at the account/COS level, but not modifiable by the end user:
When a mailbox is purged, all attributes are considered. In cases where there's both a system and user-level policy is specified for the same folder, the shorter interval is used.
There is one safeguard in place. If zimbraMailMessageLifetime is set to less than 31 days, an interval of 31 days is used. All other attributes don't have a safeguard.