Skip to content

Retention policy

NovaVMS keeps different data types for different lengths of time. This page lists every default and how to change it.

Default retention per data type

Data typeDefault retentionConfigurable?How to change
Event clips (MP4)30 daysyes, per siteSite settings -> Retention days. Range 7 - 365 days.
Event snapshots (JPEG)30 daysyes, per siteSame field as event clips.
Event thumbnails (JPEG, 320 px)30 daysyes, per siteSame field as event clips.
Event rows (DB)30 daysyes, per siteSame field. Starred events exempt — kept indefinitely until unstarred.
Audit log entries (org)90 daysyes, env varAUDIT_RETENTION_DAYS on the cloud server. Range 7 - 365.
Platform audit log entries365 daysnoNot configurable.
Webhook deliveries100 per webhooknoOldest purged when 101st delivery arrives.
In-app notifications500 per useryes, env varMAX_NOTIFICATIONS_PER_USER. Range 50 - 5000.
Refresh tokens7 days (30 with “Remember me”)noFixed.
Share links7 daysyes, per linkLink creator picks 1 h, 24 h, 7 d, or 30 d at creation.
Reports (PDF)90 daysnoHard-coded in v1.

Storage locations

Data typeLocationBackup cadence
Event clips, snapshots, thumbnailsObject storage (STORAGE_BACKENDlocal, gcs, or s3)Follows the bucket’s own backup/versioning policy.
Event rows, audit entries, user dataPostgreSQLPer operator’s DB backup policy.
In-app notificationsPostgreSQLSame.
Gateway pre-event ring bufferGateway RAMNot backed up — transient.
Gateway local disk cacheGateway disk, up to disk_quota_mb (default 10 GB)Not backed up. Uploaded to cloud on success.

What happens at expiry

  • Event clip or snapshot: the object storage file is deleted first, then the events row transitions clip_status from ready to expired. Starred events are exempt — they are kept until unstarred.
  • Event row: deleted after its clip expires. Retention cleanup runs hourly by default (RETENTION_INTERVAL=1h), batched to RETENTION_BATCH_SIZE=1000 rows at a time.
  • Audit log entry: purged daily in batches. No grace period.
  • Webhook delivery: pruned when the per-webhook 100-entry cap is exceeded.
  • In-app notification: oldest notifications dropped when the per-user cap is exceeded.
  • Share link: rejected with 410 Gone after the expiry timestamp. Row pruned on next cleanup sweep.
  • Camera, gateway, site, user: soft-deleted — deleted_at set, row preserved for audit reference, name freed for reuse.
  • Chain of custody — why exported clips remain valid after source retention expires
  • Audit actions — what retention cleanup writes to the audit log