RadiatorDB Backup
Export and import RadiatorDB backup files
RadiatorDB backup operations export and import full or filtered RadiatorDB backend data through Radiator Management API. Use backups to move data between environments or restore a RadiatorDB backend from a saved backup file. The API can also export and import gzip-compressed backups.
Backup export and import require Radiator Management API write or all
privilege. Collection-level RadiatorDB roles cannot grant access to backup operations.
Export and import stream backup data instead of loading the full backup into memory. This keeps memory usage low for large backups.
Backup metadata records source time-series collection names and effective export bounds. It does not record source partition intervals. Restore uses the target collection's configured interval. Management API import can restore an included time-series collection when the target configuration registers it as time-series storage. An excluded time-series collection does not block a filtered normal-collection import.
Export Backup
Export a RadiatorDB backup:
POST /api/v1/backends/radiatordb/:db_name/backups/export
Content-Type: application/json
{
"includeRevisions": true,
"batchSize": 1000,
"gzip": true,
"collections": {
"include": [
{"name": "users"},
{
"name": "events",
"from": "2026-07-01T00:00:00Z",
"until": "2026-08-01T00:00:00Z"
}
]
}
}
The export request accepts these JSON fields:
| Field | Type | Description |
|---|---|---|
includeRevisions | boolean | Include archived revision records after active documents. Default: true |
batchSize | number | Maximum number of documents fetched per internal database batch. Default: 1000, minimum: 1, maximum: 10000 |
gzip | boolean | Compress the exported backup stream with gzip. Default: true |
collections | object | Optional exact-name collection filter. Omit it to export every collection |
collections.include must contain one or more unique entries. Each entry
contains name and can contain from or until. from is inclusive and
until is exclusive. Either bound can be omitted. Bounds apply only to live
rows in that time-series collection. Normal documents and revisions remain
unbounded. A bound on a normal collection returns 400 Bad Request.
Time-series bounds select rows during export. They do not create an import range. Import collection filters select complete collections by name.
Returns 200 OK with a backup stream.
The attachment filename uses the backend name and a sortable timestamp in the server timezone. Radiator picks the timezone from the operating system local timezone setting. If the server timezone cannot be detected, Radiator uses UTC.
The backup contains a consistent snapshot from the start of the export. Other clients can continue to write while the export is running, but those later changes are not included in the backup. Large exports can temporarily increase database load until the export finishes or fails.
Example:
Save a backup file with curl. Use -JO so curl saves the file with the name from the Content-Disposition response header:
curl -JO -u alice:password \
--json '{"includeRevisions": true, "gzip": true}' \
https://radiator.example.com/api/v1/backends/radiatordb/RADIATORDB/backups/export
For example, this command can save a compressed backup as RADIATORDB-2026-06-22T13-55-32+0300.jsonl.gz.
Import Backup
Import a gzip-compressed RadiatorDB backup. The import endpoint accepts gzip compressed and plain backup streams:
POST /api/v1/backends/radiatordb/:db_name/backups/import
<backup file stream>
The import endpoint accepts these query parameters:
| Parameter | Description |
|---|---|
importRevisions | Set to false to skip revision lines without validating or restoring them. Default: true with strategy=reset; false with other strategies |
strategy | Import strategy. Allowed values: reset, override, skip, newest. Default: reset |
batchSize | Target number of documents per internal import batch. Default: 1000, minimum: 1, maximum: 5957 |
validate_schema | Set to false only for disaster recovery to skip active schema validation and canonicalization. Default: true |
collections | URL-decoded JSON object with an include array of exact collection names. Omit it to import every collection |
For strategy behavior, use cases, and caveats, see Import Strategies.
Returns 200 OK with an import summary:
| Field | Type | Description |
|---|---|---|
documents | number | Number of document rows inserted or updated |
revisions | number | Number of revision records imported |
Example response:
{
"documents": 2,
"revisions": 5
}
Import a backup file with curl:
curl -u alice:password \
-X POST \
--data-binary @RADIATORDB-2026-06-22T13-55-32+0300.jsonl.gz \
'https://radiator.example.com/api/v1/backends/radiatordb/RADIATORDB/backups/import?importRevisions=true&batchSize=1000'
Import only users and devices by percent-encoding
{"include":[{"name":"users"},{"name":"devices"}]}:
curl -u alice:password \
-X POST \
--data-binary @selected.jsonl.gz \
'https://radiator.example.com/api/v1/backends/radiatordb/RADIATORDB/backups/import?collections=%7B%22include%22%3A%5B%7B%22name%22%3A%22users%22%7D%2C%7B%22name%22%3A%22devices%22%7D%5D%7D'
The importer parses every JSON Lines record. It skips excluded document and revision records before field validation, conflict handling, batching, and summary counting. Malformed JSON and a second metadata line still fail the import.
Use the same request for an uncompressed backup file. RadiatorDB automatically detects the content type from the incoming stream bytes.
By default, import validates and canonicalizes document keys and document and
revision payloads with the active collection schemas. Set
validate_schema=false only when disaster recovery requires restoring values
that no longer match the active configuration. This setting preserves those
values without schema-driven canonicalization. The import still enforces the
backup format, metadata, structural key, storage, transaction, database, and
PostgreSQL constraints. Schema-invalid data can be unavailable to normal
operations until you repair the data or restore a compatible schema.
Import Strategies
Use strategy to choose whether import replaces the backend or merges backup documents into existing data. The strategy descriptions in this section apply to normal collections. For time-series restrictions, see Time-series Import Strategies.
reset
reset is the default strategy. An unfiltered reset removes all existing live
documents and revisions on every configured RadiatorDB node. A filtered reset
clears only included normal documents, revisions, and time-series collection
parents. It preserves excluded rows and topology.
Before clearing existing data, RadiatorDB waits for cluster synchronization and validates the backup metadata line. After metadata validation, import opens a transaction on every physical RadiatorDB node and truncates documents and revisions inside those transactions. The import then restores backup documents through one transaction node and commits all node transactions after the stream imports successfully and finally commits the transaction on the import node.
Use reset for full restores, disaster recovery, and replacing a test or staging database with a known backup. Use it when you need the imported backend to match the backup file exactly, including revision history.
reset is the only strategy that can import and validate revision records. If importRevisions is omitted, reset imports revisions by default. Set importRevisions=false when you want to restore live documents without revision history.
reset is destructive. Keep a separate valid backup before you run it on production data. If a backup line is malformed, contains a duplicate key, or cannot be written before commit starts, RadiatorDB rolls back all import transactions and preserves the previous backend contents.
If a transaction commit fails after one or more nodes have already committed, RadiatorDB cannot roll back the committed nodes. Keep a separate valid backup file and retry the import to repopulate the backend if a fatal commit error occurs.
override
override imports backup documents into the existing backend and makes conflicting backup documents win over existing documents. A conflict means an existing document has the same collection and key as an imported document.
Use override when the backup file is the desired source for the documents it contains, but you do not want to remove unrelated existing documents. This is useful for partial restores and controlled promotion from another environment.
When an imported document conflicts with an existing document, RadiatorDB may assign a newer updated_at value and a fresh revision UUID to the imported document. This is required for the imported document to win RadiatorDB last-write-wins replication on synchronized clusters.
override cannot import revisions.
skip
skip imports backup documents only when the backend does not already have an document with the same collection and key.
Use skip to seed missing documents without overwriting operator changes. This is useful when you import a baseline data set into a backend that may already contain local edits.
Import summary document counts include only documents imported or restored. Skipped conflicts are not included in the document count.
skip cannot import revisions.
newest
newest imports backup documents and lets RadiatorDB last-write-wins conflict resolution choose between an imported document and an existing document.
Use newest when you merge backups from synchronized or related environments and want the document with the newest RadiatorDB update metadata to win. This can preserve newer production edits while still restoring older missing documents.
If an imported document has the same timestamp as an existing document, RadiatorDB uses its normal conflict tie-break rules.
newest cannot import revisions.
Time-series Import Strategies
Time-series from and until bounds select live rows during backup export.
They do not define an import range. An import collection filter selects the
complete time-series collection by name, not a time range. Time-series import
supports only reset and skip.
| Strategy | Behavior for a selected time-series document |
|---|---|
reset | Clears the complete selected collection, then restores rows from the backup. Existing rows outside the exported range are removed. |
override | Rejects the import. This strategy does not support selected time-series documents. |
skip | Inserts the backup row only when the same collection and key do not exist. Other rows remain unchanged. |
newest | Rejects the import. This strategy does not support selected time-series documents. |
Use reset only when the included time-series collection must match the backup
contents. For example, importing a backup exported with from and until
removes existing events before from and at or after until.
Use skip to restore deleted events from a bounded backup without changing
events that still exist. Do not use override or newest when the selected
backup data contains time-series documents. RadiatorDB rejects the import when
it reaches a selected time-series document.
The target backend must register the collection as time-series storage. During import, RadiatorDB creates required partitions from each imported event timestamp and the target collection's configured partition interval. The source partition interval is not stored in the backup.
Backup File Format
The backup file is a JSON Lines stream, or a gzip-compressed JSON Lines stream. Each non-empty line in the uncompressed stream must contain one complete JSON object. The first non-empty line must be a metadata record. The remaining lines can be document or revision records.
When export compression is enabled, the attachment filename ends with .jsonl.gz. When export compression is disabled, the response uses Content-Type: application/x-jsonl, and the attachment filename ends with .jsonl. Use the same content type when you import an uncompressed backup file.
For example, an export from backend RADIATORDB can create RADIATORDB-2026-06-22T13-55-32+0300.jsonl.gz for a compressed backup, or RADIATORDB-2026-06-22T13-55-32+0300.jsonl for an uncompressed backup.
Metadata records have these fields:
| Field | Type | Description |
|---|---|---|
type | string | Must be metadata |
format | string | Must be radiatordb-backup-jsonl |
version | number | Must be 1 |
createdAt | string | Backup creation time in RFC 3339 format. Uses the server timezone, or UTC if the server timezone cannot be detected |
includeRevisions | boolean | Whether the backup stream includes revision records |
timeseriesCollections | array | Source time-series names and optional inclusive from and exclusive until bounds. Omitted when empty |
Version 1 backups created before timeseriesCollections remain importable. A
missing or empty list means that source storage information is unknown.
Time-series restore derives every required partition from each document key and
the target collection configuration.
Document and revision records have these fields:
| Field | Type | Description |
|---|---|---|
type | string | document for live documents, or revision for historical records |
key | string[] | Ordered document key parts |
rev | string | Document revision UUID |
data | object, array, scalar, or null | Stored JSON payload. document records cannot use null; revision records can use null for tombstones |
expire_at | string or null | Expiration time in RFC 3339 format, or null when the document does not expire |
previous | object or null | Rename metadata, or null when the document was not created by a rename |
collection | string | RadiatorDB collection name |
created_at | string | Document creation time in RFC 3339 format |
updated_at | string | Last update time in RFC 3339 format |
updated_by | string or null | User that last updated the document |
origin | string | Origin node identifier |
When previous is not null, it has this shape:
| Field | Type | Description |
|---|---|---|
key | string[] | Previous document key parts |
rev | string | Previous document revision UUID |
Example backup stream:
{"type":"metadata","format":"radiatordb-backup-jsonl","version":1,"createdAt":"2026-06-12T10:00:00+03:00","includeRevisions":true}
{"type":"document","key":["helsinki","edge-1"],"rev":"00000000-0000-0000-0000-000000000001","data":{"hostname":"edge-1","enabled":true},"expire_at":null,"previous":null,"collection":"DEVICES","created_at":"2026-06-12T10:00:00Z","updated_at":"2026-06-12T10:15:00Z","updated_by":"alice","origin":"node-1"}
{"type":"revision","key":["helsinki","edge-1"],"rev":"00000000-0000-0000-0000-000000000002","data":null,"expire_at":null,"previous":null,"collection":"DEVICES","created_at":"2026-06-12T10:00:00Z","updated_at":"2026-06-12T10:20:00Z","updated_by":"alice","origin":"node-1"}
Related Documentation
Application log message index
Architecture Overview
Backend Load Balancing
Basic Installation
Built-in Environment Variables
Byte Size Units
Certificate Revocation Lists
Comparison Operators
Configuration Editor
Configuration Import and Export
Containers
Cron and interval timers
Data Types
Duration Units
Environment Variables
Execution Context
Execution Pipelines
Filters
Getting a Radiator License
Health check /live and /ready
High Availability and Load Balancing
High availability identifiers
HTTP Basic Authentication
Introduction
Linux systemd support
Local AAA Backends
Logging
Management API privilege levels
Namespaces
Password Hashing
Password Rehashing During Login
Probabilistic Sampling
Prometheus and OpenMetrics scraping
PROXY Protocol Support
Radiator server health and boot up logic
Radiator sizing
Radiator software releases
Radiator software security and dependency compliance
RadiatorDB
RadiatorDB Backup
RadiatorDB CLI
RadiatorDB Installation
RadiatorDB PostgreSQL 10k TPS example
RadiatorDB REST API
RadiatorDB sizing
Rate Limiting
Rate Limiting Algorithms
Reverse Dynamic Authorization
Service Level Objective
TACACS+ Authentication, Authorization, and Accounting
Template Rendering CLI
Timestamps
Tools radiator-client
TOTP/HOTP Authentication
What is Radiator?
YubiKey Authentication
YubiKey Context Variables
Application log message index
Architecture Overview
Backend Load Balancing
Basic Installation
Built-in Environment Variables
Byte Size Units
Certificate Revocation Lists
Comparison Operators
Configuration Editor
Configuration Import and Export
Containers
Cron and interval timers
Data Types
Duration Units
Environment Variables
Execution Context
Execution Pipelines
Filters
Getting a Radiator License
Health check /live and /ready
High Availability and Load Balancing
High availability identifiers
HTTP Basic Authentication
Introduction
Linux systemd support
Local AAA Backends
Logging
Management API privilege levels
Namespaces
Password Hashing
Password Rehashing During Login
Probabilistic Sampling
Prometheus and OpenMetrics scraping
PROXY Protocol Support
Radiator server health and boot up logic
Radiator sizing
Radiator software releases
Radiator software security and dependency compliance
RadiatorDB
RadiatorDB Backup
RadiatorDB CLI
RadiatorDB Installation
RadiatorDB PostgreSQL 10k TPS example
RadiatorDB REST API
RadiatorDB sizing
Rate Limiting
Rate Limiting Algorithms
Reverse Dynamic Authorization
Service Level Objective
TACACS+ Authentication, Authorization, and Accounting
Template Rendering CLI
Timestamps
Tools radiator-client
TOTP/HOTP Authentication
What is Radiator?
YubiKey Authentication
YubiKey Context Variables