Skip to main content
Convoy supports exporting events to any S3 compatible cold storage.
Note:
  • Retention policies are available only on a paid license.
  • Partition conversions and per-project retention windows are part of that license. There is no separate feature flag to turn partitioning on.

Configuring Retention

JSON Configuration

You can configure read replicas by adding the storage_policy object to your database configuration JSON.
using storage policy via JSON configuration

Environment Variables Configuration

Alternatively, you can supply environment variables to configure the storage policy.
using storage policy via environment variable configuration

Retention Using Postgres Partitions

Convoy retains webhook history with Postgres-native daily partitions (go_partman). Licensed instances can convert tables from the dashboard or the CLI. Partitioning is a paid feature; it is not a feature flag. Before Convoy v25.1.1 the retention job both uploaded to S3 and ran DELETE on the same tables. Timeouts and network errors left duplicates or skipped deletes, and large deletes triggered autovacuum pressure. Partitions drop a day at a time instead. You can set a different retention duration per project from project settings.

Tables

These tables can be partitioned:
  • delivery_attempts
  • event_deliveries
  • events
  • events_search
Back up the database, or try the conversion on a copy, before you convert a large production table.

Convert from the admin dashboard

On a licensed instance, open Admin → Table partitions. Pick a table and an operation. Convert one table at a time. Attach (the usual conversion) keeps ingestion running. The existing table becomes one history partition that holds everything written up to the cutoff; new rows go into daily partitions after that. Retention expires that history partition in full once every row in it is older than your window, then expires later days one partition at a time. Detach / copy unpartition convert back to a plain table. Copy unpartition should run in a maintenance window: rows written during the copy are not carried over, so pause ingestion first. Progress for the in-flight run is shown on the same page.

Convert from the CLI

partition all tables
Or one table at a time:
partition tables one after the other
If you are running Convoy in Docker:
partitioning using docker exec
Un-partition:
unpartition
unpartition one table

Breaking change in v26.7.2

Partitions created by convoy utils partition used to be ignored by retention because their names were folded to lower case. They are managed now. History that survived only because those partitions were skipped is dropped at CONVOY_RETENTION_POLICY on the next maintenance run. Confirm that duration before you upgrade.

Indexes after conversion

An interrupted index build, or an upgrade that drops a large index so migrate can finish, leaves work on Admin → Table indexes. convoy utils indexes reports the same list. From v26.7.3 server and agent work through that list themselves, in the background after boot, one index at a time and unique indexes first. No rebuild holds a lock against traffic, but a large index takes hours. Use Rebuild on that page to retry one that failed.

Breaking change in v26.7.3

Boot also drops any index Postgres left INVALID (a killed CREATE INDEX CONCURRENTLY) and queues it the same way, instead of leaving it until the next migrate with the planner ignoring it silently. An invalid unique index still enforces its key. Dropping one gives that up until the rebuild finishes, so upgrade in a window where losing the constraint for a few hours is acceptable, and watch the page until every owed index is valid again. A rebuild that meets duplicate rows is recorded as blocked, with the offending key, and skipped from then on. Resolve those duplicates by hand before you retry it.