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 type | Default retention | Configurable? | How to change |
|---|
| Event clips (MP4) | 30 days | yes, per site | Site settings -> Retention days. Range 7 - 365 days. |
| Event snapshots (JPEG) | 30 days | yes, per site | Same field as event clips. |
| Event thumbnails (JPEG, 320 px) | 30 days | yes, per site | Same field as event clips. |
| Event rows (DB) | 30 days | yes, per site | Same field. Starred events exempt — kept indefinitely until unstarred. |
| Audit log entries (org) | 90 days | yes, env var | AUDIT_RETENTION_DAYS on the cloud server. Range 7 - 365. |
| Platform audit log entries | 365 days | no | Not configurable. |
| Webhook deliveries | 100 per webhook | no | Oldest purged when 101st delivery arrives. |
| In-app notifications | 500 per user | yes, env var | MAX_NOTIFICATIONS_PER_USER. Range 50 - 5000. |
| Refresh tokens | 7 days (30 with “Remember me”) | no | Fixed. |
| Share links | 7 days | yes, per link | Link creator picks 1 h, 24 h, 7 d, or 30 d at creation. |
| Reports (PDF) | 90 days | no | Hard-coded in v1. |
Storage locations
| Data type | Location | Backup cadence |
|---|
| Event clips, snapshots, thumbnails | Object storage (STORAGE_BACKEND — local, gcs, or s3) | Follows the bucket’s own backup/versioning policy. |
| Event rows, audit entries, user data | PostgreSQL | Per operator’s DB backup policy. |
| In-app notifications | PostgreSQL | Same. |
| Gateway pre-event ring buffer | Gateway RAM | Not backed up — transient. |
| Gateway local disk cache | Gateway 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.