Skip to main content

Media Storage

What This Page Covers

This page explains how recordings, clips and snapshots are stored and accessed within the Video Management Capability. It covers the S3 storage layout, the presigned URL access pattern, recording segmentation, clip assembly, snapshot upload paths and metadata persistence.

For the runtime flows that produce these media artifacts, see Streaming Flows. For camera and channel setup, see Camera Configuration.


Storage Architecture

All media — recordings, clips and snapshots — is stored in AWS S3. The Cloud NVR never serves media directly to clients. Instead, it presigns S3 URLs and hands them to the client, which then interacts with S3 directly for both uploads and downloads.

Client

├── Upload (presigned PUT) ──────► AWS S3
│ │
└── Download (presigned GET) ◄────────┘

Cloud NVR
├── Presigns URLs (PUT for uploads, GET for downloads)
├── Tracks metadata in RDS database
└── Listens on SQS for upload confirmations

This pattern keeps media transfer off the Cloud NVR, allowing it to focus on metadata coordination and authorization.


Presigned URL Pattern

Every media access — read or write — uses presigned S3 URLs. The Cloud NVR generates these on demand, scoped to a specific object and operation.

OperationURL TypeWho Uses It
Recording downloadPresigned GETClient (playback)
Snapshot downloadPresigned GETClient (viewing)
Clip downloadPresigned GETClient (playback)
Snapshot uploadPresigned PUTClient or Local Agent

Presigned URLs carry embedded credentials and have a limited expiration time. No additional authorization is required once the client has the URL — S3 validates the signature directly.

Access Flow

  1. Client requests media through the Cloud VMS API.
  2. Cloud VMS forwards the request to the Cloud NVR.
  3. Cloud NVR queries its database for metadata (paths, time ranges).
  4. Cloud NVR presigns the appropriate S3 URLs.
  5. Client receives URLs and interacts with S3 directly.

Recordings

Segmentation

While a live stream is active, the NVR Worker continuously segments the stream into 30-second recording files and uploads them to S3.

PropertyValue
Segment duration30 seconds
Upload methodrclone (HTTPS to S3)
Temporary storagetmpfs on the NVR Worker
TriggerAutomatic while stream is active

The NVR Worker is stateless — it buffers the current segment in tmpfs and uploads it to S3 as soon as the segment window closes. Multiple workers can process independent streams simultaneously.

Upload Notification

When a segment is uploaded, two notification paths fire in parallel:

  1. S3 → SQS — S3 emits an event to an SQS queue. The Cloud NVR listens on this queue for clip assembly (see below).
  2. NVR Worker → Cloud NVR — The worker directly notifies the Cloud NVR over HTTP that a segment was uploaded.

The Cloud NVR then persists recording metadata to its database.

Metadata

Each recording entry in the database contains:

FieldPurpose
Channel IDWhich camera channel this recording belongs to
Time rangeStart and end timestamp of the 30-second segment
S3 pathObject key in the recordings bucket
StatusUpload state (used during clip assembly)

Playback

When a client requests recordings for a channel:

  1. The Cloud NVR queries its database, optionally filtering by time range.
  2. For each matching recording, it generates a presigned S3 GET URL.
  3. The client receives a list of recordings with their presigned URLs.
  4. The client downloads segments directly from S3.

The client is responsible for stitching segments together for continuous playback.


Clips

A clip is a user-defined time range extracted from continuous recordings. Unlike recordings (which are produced automatically), clips are explicitly requested by the user.

Assembly Process

Clip creation is asynchronous because the requested time range may extend into the present — segments that haven't been uploaded yet must be waited for.

PhaseWhat Happens
RequestClient specifies channel ID, start time and end time
Entry creationCloud NVR creates a clip entry with status: in_progress
Existing segmentsNVR queries the database for recordings already within the time range and appends them to the clip
WaitingNVR listens on SQS for new recording uploads that fall within the range
CompletionOnce all segments in the range are covered, clip status is set to finished

Clip Lifecycle

StatusMeaning
in_progressClip is being assembled — some recordings may still be uploading
finishedAll recordings within the time range are included and the clip is accessible

The client can poll the clip status endpoint until it transitions to finished.

Access

Finished clips are accessed using the same presigned GET URL pattern as individual recordings. The clip object in S3 contains the concatenated segments for the requested time range.


Snapshots

Snapshots are single-frame image captures associated with a camera channel. They use a two-step upload pattern: the Cloud NVR creates the metadata entry and provides a presigned PUT URL, then the uploader sends the image directly to S3.

Upload Paths

SourceDescription
Client-uploadedThe mobile app or web client captures a frame and uploads it via the presigned PUT URL
Agent-capturedThe Local Agent on the hub captures a frame from the camera's snapshot URL and uploads it via the presigned PUT URL

Both paths produce the same result in S3 — the distinction is only in who initiates the capture.

Upload Flow

  1. Client (or agent) requests a snapshot entry for a channel via the VMS API.
  2. Cloud NVR creates a snapshot entry in the database.
  3. Cloud NVR presigns an S3 PUT URL for the snapshot object.
  4. The presigned URL is returned to the requester.
  5. The requester uploads the image directly to S3 using the PUT URL.

Retrieval

Snapshots are retrieved through the same presigned GET URL mechanism as recordings. The client requests snapshot metadata for a channel, receives presigned download URLs, and fetches images directly from S3.


Metadata Database

The Cloud NVR maintains all media metadata in an RDS database. This database is the source of truth for what media exists and where it is stored — S3 is treated as a dumb object store.

EntityKey Fields
Recordingchannel_id, time_start, time_end, s3_path
Clipchannel_id, clip_id, time_start, time_end, status
Snapshotchannel_id, snapshot_id, s3_path

The VMS and NVR databases share the same RDS instance but use separate schemas.


Storage Characteristics

PropertyRecordingsClipsSnapshots
Produced byNVR Worker (automatic)Cloud NVR (on request)Client or Local Agent
Storage locationS3 recordings bucketS3 recordings bucketS3 recordings bucket
Upload methodrclone (NVR Worker → S3)Assembled from recordingsPresigned PUT (client → S3)
Access methodPresigned GET URLPresigned GET URLPresigned GET URL
Granularity30-second segmentsUser-defined time rangeSingle frame

NVR Worker and S3

The NVR Worker uses rclone as its S3 upload mechanism. This provides:

  • Retry on transient failures
  • Checksum verification of uploaded objects
  • Efficient transfer without loading full segments into memory

The worker stores segments temporarily in tmpfs (RAM-backed filesystem) before upload. This avoids disk I/O bottlenecks and keeps the worker stateless — if a worker instance dies, no persistent state is lost. The segments that were in tmpfs are simply not uploaded, and the recording will have a gap for that period.


Where to Continue

GoalPage
See the streaming and recording flows step by stepStreaming Flows
Understand camera setup and channel creationCamera Configuration
See the full video management modelOverview