Room Message Retention Rules and Automated Purging Policy

Running a community involves balancing database growth, compliance requirements, and ongoing conversations. In chat-backed communities or federated setups, leaving entire channels unmanaged can lead to ballooning database tables. According to the Message Retention Policies - Synapse documentation, homeserver administrators can implement room-level retention and automated background purge jobs to clean up expired events while safeguarding active discussions.
Understanding Room-Level Retention Semantics
Message retention policies operate on a room level, following the semantics defined in MSC1763. This configuration lets server and room admins dictate how long messages should stay in a homeserver database prior to being removed. While a default message retention policy is considered a stable feature in Synapse, using m.room.retention events for per-room rules is considered experimental because it is not yet part of the Matrix specification.
A policy centers around the max_lifetime parameter. This defines the duration a message is retained after it was sent. If neither the room nor the server sets a retention policy, messages in that room are never purged from that server. MSC1763 also introduces a min_lifetime parameter—the time after which an event can be purged—though Synapse registers it without further support. State events are excluded from these retention policies, ensuring essential room configurations remain intact.
Configuring Server Defaults and Administrative Guardrails
Before room moderators can apply retention settings, the server administrator must enable support in the homeserver configuration. Within the retention block, setting enabled to true turns the feature on. Admins can then define fallback rules and safe boundaries:
- Default Policy: A fallback configured under
default_policyapplies to any room without an explicit state policy. An example setup usesmin_lifetime: 1dandmax_lifetime: 1yto keep messages from remaining indefinitely. Duration values accept seconds (s), minutes (m), hours (h), days (d), weeks (w), and years (y), or explicit millisecond counts. - Allowed Lifetime Limits: To prevent room moderators from picking values that are too short or overly long, admins can configure
allowed_lifetime_minandallowed_lifetime_maxunder theretentionblock. If set to1dand1y, Synapse brings any room rule into that inclusive window. Messages younger than one day are preserved, while those exceeding one year are purged.
For additional details on underlying server maintenance and software setups, see our guide on forum software server requirements.
Deploying Room-Level State Events
When room administrators or moderators want to establish custom timelines, they send an m.room.retention state event into the room. The event payload requires duration values formatted strictly in milliseconds:
{
"max_lifetime": ...
}
A moderator can also supply min_lifetime in the event payload. On federated networks, only homeservers that have actively enabled message retention policy support will remove expired events. On servers where retention is inactive, events remain stored. If you are drafting broad moderation guidelines that govern how rooms handle lifecycles, refer to our forum rules template for structural tips.
Automated Purge Intervals and Room Continuity
Once an event reaches its expiration date (the time sent plus max_lifetime), Synapse immediately stops serving the event to clients via any endpoint. The event then waits for a background purge job to remove it from the database. Because these background tasks run on defined schedules rather than continuously, expired records may linger temporarily in the database host storage, yet they stay completely hidden from local client views.
Synapse guarantees room continuity by requiring at least one message in each room. It will never delete the final message in a room, though it hides that message from clients if it has expired. Similarly, if a server with retention enabled receives an expired event from another homeserver, it stores the event until the next purge job runs, keeping it hidden from users in the interim.
Structuring Tiered Background Purge Jobs
Purge jobs run automatically using defaults if left unconfigured, but admins can schedule tiered runs to optimize server load. Purge tasks can become heavy if they process too many rooms at once. Scheduling lower intervals for targeted sets of rooms prevents performance degradation. The Message Retention Policies - Synapse documentation provides an example configuration defining three distinct background jobs:
- A job running every 12 hours (twice a day) handling rooms where
max_lifetimeis less than or equal to 3 days (longest_max_lifetime: 3d). - A job running once every 1 day handling rooms where
max_lifetimeis between 3 days and 1 week (shortest_max_lifetime: 3d,longest_max_lifetime: 1w). - A job running once every 2 days handling rooms where
max_lifetimeexceeds 1 week (shortest_max_lifetime: 1w).
In production, administrators must ensure configurations include one job with no minimum boundary and one job with no maximum boundary so that all policies are covered.
Reclaiming Storage on the Database Host
Executing purge jobs removes records from the database, but physical disk space will not decrease immediately on the host. Instead, database engines begin writing new records into the space freed up by purged data. To reclaim that unallocated storage and return it directly to the host operating system, server admins must manually execute VACUUM FULL; on PostgreSQL databases, or run VACUUM; when utilizing SQLite.
Sources
Message Retention Policies - Synapse
Published October 31, 2026. No affiliate links on this page. Facts come from the sources linked above; check them for updates.