Retention Policy
Convoy supports exporting events to any S3 compatible cold storage.
Note:
- The retention policies functionality is available only for licensed users.
- This feature is currently in beta and disabled by default. To enable it, use the environment variable
CONVOY_ENABLE_FEATURE_FLAG=retention-policy
or the CLI flag--enable-feature-flag=retention-policy
.
Configuring Retention
JSON Configuration
You can configure read replicas by adding the storage_policy
object to your database configuration JSON.
Key | Description |
---|---|
type | Storage type, either “s3” or “on_prem” |
s3.prefix | Prefix for S3 storage path |
s3.bucket | Name of the S3 bucket |
s3.access_key | AWS access key for S3 authentication |
s3.secret_key | AWS secret key for S3 authentication |
s3.region | AWS region where the S3 bucket is located |
s3.session_token | Temporary session token for AWS authentication (optional) |
s3.endpoint | Custom endpoint URL for S3-compatible storage |
on_prem.path | File system path for on-premises storage location |
Environment Variables Configuration
Alternatively, you can supply environment variables to configure the storage policy.
Environment Variable | Description |
---|---|
CONVOY_STORAGE_POLICY_TYPE | Storage type, either “s3” or “on_prem” |
CONVOY_STORAGE_AWS_PREFIX | Prefix for S3 storage path |
CONVOY_STORAGE_AWS_BUCKET | Name of the S3 bucket |
CONVOY_STORAGE_AWS_ACCESS_KEY | AWS access key for S3 authentication |
CONVOY_STORAGE_AWS_SECRET_KEY | AWS secret key for S3 authentication |
CONVOY_STORAGE_AWS_REGION | AWS region where the S3 bucket is located |
CONVOY_STORAGE_AWS_SESSION_TOKEN | Temporary session token for AWS authentication (optional) |
CONVOY_STORAGE_AWS_ENDPOINT | Custom endpoint URL for S3-compatible storage |
CONVOY_STORAGE_PREM_PATH | File system path for on-premises storage location |
Retention Using Postgres Partitions
We introduced a new way to manage retention using Postgres-native partitions
using go_partman with each table is partitioned by day.
Prior to Convoy v25.1.1
the job that ran the retention policy carried out two tasks:
- Running
SELECT
queries and uploading webhook event data to S3. - Running
DELETE
queries on the tables.
Problems with the old system
Concurrency
The problem with the old approach was that both the backup and deletion queries ran in the same job, and any of these tasks could fail for a number of reasons:
- The backup action could fail because of a network issue, making the retention query not run.
- The backup action could succeed, but the retention query would time out leading to duplication data the next time the backup action ran.
This approach also had some other issues:
- There also wasn’t any visibility into what error occurred or why the backup did not work.
- Running
DELETE
queries on moderately large Postgres databases triggersAUTOVACUUM
and causes disk pressure.
Retention Granularity
The previous system also didn’t make it possible to specify different retention periods for different projects. Now it is possible to specify different retention periods per project, and this can be managed from the project settings page.
Proposed Solution
With the new system, the backup and delete operations run in different jobs that are triggered at different times.
Backups
The backup job backs up events sent on a particular day at the end of that day.
Deletion
The retention (deletion) job deletes events sent on a particular day n-days after it was sent; where n is the retention policy duration.
Switching to Partition for Retention
The tables that are partitioned are:
convoy.delivery_attempts
convoy.event_deliveries
convoy.events
convoy.events_search
Before partitioning (or un-partitioning), the tables be sure to back up the database, or test it on a fresh database with all the organization and project configuration copied over.
Partitioning the tables
To switch to managing retention using Postgres partitions, you need to run:
If you are running convoy in a docker container, you can execute this command using
docker exec
partitioning using docker exec
When the above command is run, it attempts to partition all the tables at the same time. This operation can take a while (10 to 60 minutes) if the tables are moderately large, so you would need to partition them one after the other like this:
Un-partitioning the tables
To switch back from managing retention using Postgres partitions, you can un-partition all of them at the same time by running:
Or you can un-partition them one after the other by running:
Was this page helpful?