{"slug":"backups-recovery","title":"Backups & recovery","description":"Every VPS, cache and database on DanubeData has recovery points: consistent copies of its data you can go back to. This page explains what a recovery point is, how you restore from one, how your data...","section":"Features","url":"https://docs.danubedata.ro/backups-recovery","markdown_url":"https://docs.danubedata.ro/backups-recovery.md","breadcrumbs":[{"title":"Features","slug":null},{"title":"Backups & Recovery","slug":"backups-recovery"}],"headings":[{"level":1,"title":"Backups & recovery","id":"backups-recovery"},{"level":2,"title":"Recovery points","id":"recovery-points"},{"level":2,"title":"Restore to a new resource (the default)","id":"restore-to-a-new-resource-the-default"},{"level":3,"title":"Point-in-time recovery (PostgreSQL)","id":"point-in-time-recovery-postgresql"},{"level":2,"title":"Replace the existing resource (advanced)","id":"replace-the-existing-resource-advanced"},{"level":2,"title":"Operations","id":"operations"},{"level":2,"title":"Second copies and protection labels","id":"second-copies-and-protection-labels"},{"level":2,"title":"Backup policies","id":"backup-policies"},{"level":3,"title":"Protection health","id":"protection-health"},{"level":2,"title":"What each product can do","id":"what-each-product-can-do"},{"level":2,"title":"API and CLI","id":"api-and-cli"},{"level":2,"title":"Related","id":"related"}],"format":"markdown","word_count":1291,"content":"# Backups & recovery\n\nEvery VPS, cache and database on DanubeData has **recovery points**: consistent copies of its data you can go back to. This page explains what a recovery point is, how you restore from one, how your data is protected, and what each product can do today.\n\n## Recovery points\n\nA recovery point is a snapshot of a VPS disk, a cache dataset, or a database. Each point has an **origin**:\n\n- **Manual** — you took it, from the instance's Backups tab or the API. Kept until you delete it.\n- **Automated** — taken on a schedule by the platform default or by your backup policy. Kept for the retention period, then removed.\n- **Safety point** — taken automatically right before a replace-existing restore, so you can come back to the data you had.\n\nEvery point shows its state (available, creating, degraded, failed), its size, whether it has a second copy, and the actions available for it, with a plain reason when an action is not available.\n\nThe **Backups & recovery** page in the sidebar lists every recovery point across your resources, with filters by product, state and origin. Each instance's **Backups** tab shows the same points for that instance, together with its protection settings.\n\n## Restore to a new resource (the default)\n\nRestoring creates a **new** resource from the recovery point. The original is not changed, keeps running, and keeps its address and credentials; the new resource gets its own.\n\n1. Open the recovery point and choose **Restore**, or open **Restore** from the Backups & recovery page.\n2. Pick the recovery point (or, for PostgreSQL, a moment in time — see below).\n3. Choose **New resource**, give it a name and a plan.\n4. Review the server's check of the request: the resolved name, plan, storage and monthly cost, plus any warnings.\n5. Start the restore. You land on the operation page, which follows the restore through its stages and survives page reloads.\n\nBilling for the new resource starts when it is ready.\n\n### Point-in-time recovery (PostgreSQL)\n\nManaged PostgreSQL keeps continuous backups. In the restore wizard you can pick a **moment in time** instead of a recovery point; the wizard shows the UTC equivalent of the time you enter. Point-in-time recovery always creates a new database, and is available within the continuity window while continuity is healthy. MySQL and MariaDB restore from their recovery points only.\n\n## Replace the existing resource (advanced)\n\nReplacing puts the recovery point's data back **into the existing resource**. It is destructive: everything written after the recovery point is lost, and the resource is unavailable while the restore runs. Its address and credentials do not change.\n\nReplacing is opened per product, and for MySQL, caches and VPS only; PostgreSQL and MariaDB restore to a new instance. When it is available to your account, the recovery point's **Replace existing** action opens the restore wizard in replace mode:\n\n- a **safety recovery point** of the current data is taken first (on by default; you can decline it);\n- the review step states the data-loss cutoff in plain words;\n- you must type the resource's exact name to confirm;\n- the operation page shows every stage, and the restore counts as successful only after the resource is verified running again.\n\nA VPS can be replaced from its local snapshot while that snapshot is intact, or from its exported copy.\n\n## Operations\n\nEvery restore is a durable **operation** with its own page: the current stage, a timeline of what happened, the result, and — if it failed — a plain reason and whether it can be retried. Submitting the same request twice returns the same operation instead of starting a second one; changing the request under the same key is refused. One destructive operation runs per resource at a time, and a recovery point cannot be deleted while an operation depends on it.\n\n## Second copies and protection labels\n\nRecovery points of VPS, caches and MySQL databases get a **second copy** in the platform backup store, a separate storage system in the same datacenter. Each copy is recorded and re-verified against the store every hour, so the protection label on a point says what is actually there:\n\n- **Local only** — no second copy yet.\n- **Second copy syncing** — the copy is being written.\n- **Second copy** — the copy exists; it counts as verified once the hourly check has confirmed it.\n- **Second copy failed** — the copy failed; you can retry it from the point's actions.\n\nThe second copy is **not an offsite copy**: it lives in the same datacenter as the original. A point reads as *offsite* only when a verified copy lives in a store declared to be in another failure domain, which the platform does not offer yet. PostgreSQL and MariaDB backups are stored directly in the platform's object store; they have no separate second copy.\n\n## Backup policies\n\nBy default, automated recovery points are taken every day at 2:00 AM UTC and kept for 3 days. A **backup policy** replaces that default for one resource. From the instance's Backups tab choose **Set your own schedule** and pick:\n\n- the **time** and the **timezone** it applies in (daylight-saving changes move the UTC moment, never your local time);\n- how often: **every day**, **on weekdays**, or **once a week** on a weekday of your choice;\n- how long automated points are kept: **1 to 90 days**;\n- for VPS, caches and MySQL, whether a **second copy is required**.\n\nOnly the controls a product supports are shown. PostgreSQL and MariaDB take their scheduled backups through their own mechanism; the policy sets its time and retention. Turning automated points **off** keeps the policy and every existing recovery point; the points expire on their retention.\n\n### Protection health\n\nEvery hour the platform checks each policy: whether the point it last owed arrived within six hours of its schedule, and — when a second copy is required — whether the latest automated point has a verified copy. When a policy falls behind, the instance's Backups tab says so in plain words and your team is notified once; you are notified again when it is back on track.\n\n## What each product can do\n\nThis table is generated from the platform's own capability rules; the API returns the same rows from `GET /api/v1/recovery/capabilities`. *Behind a gate* means the capability exists and is opened per account by the platform.\n\n<!-- capability-matrix:start -->\n| Product | Create a point | Restore to new | Replace existing | Point in time | Notes |\n|---|---|---|---|---|---|\n| VPS | yes | when the exported copy is ready | behind a gate | no | Restore to new creates a VPS from the exported copy. Replacing uses the local snapshot while it is intact, otherwise the exported copy. |\n| Cache | yes | yes | behind a gate | no | The cache is unavailable while its storage is replaced. |\n| Redis and Valkey (operator-managed) | yes | unavailable until validated | unavailable until validated | no | Waits for a clone topology proven on a real cluster. |\n| Dragonfly (operator-managed) | yes | unavailable until validated | unavailable until validated | no | Waits for a clone topology proven on a real cluster. |\n| MySQL | yes | through the clone action | behind a gate | no | The database is unavailable while its storage is replaced. |\n| PostgreSQL | yes | yes | no (restore to new only) | yes | Point in time within the continuity window, while continuity is healthy. |\n| MariaDB | yes | yes | no (restore to new only) | no | Named physical backups only. |\n<!-- capability-matrix:end -->\n\n## API and CLI\n\nThe API v1 snapshot endpoints keep working. Restoring through `POST /api/v1/snapshots/{product}/{id}/restore` replaces the existing resource; when the product's gate is open for your account the endpoint answers `202` with an `operation_id` and the operation's page, otherwise it starts the restore directly as before. Send an `Idempotency-Key` header to make retries safe. The CLI, Terraform and Pulumi providers use the same endpoints and the same capability rules.\n\n## Related\n\n- [Automated snapshots](/automated-snapshots)\n- [Database backups](/databases-backups)\n- [VPS snapshots](/vps-snapshots)\n","prev":{"title":"Monitoring","slug":"cache-monitoring","url":"https://docs.danubedata.ro/cache-monitoring","markdown_url":"https://docs.danubedata.ro/cache-monitoring.md","json_url":"https://docs.danubedata.ro/cache-monitoring.json"},"next":{"title":"Networking","slug":"networking-overview","url":"https://docs.danubedata.ro/networking-overview","markdown_url":"https://docs.danubedata.ro/networking-overview.md","json_url":"https://docs.danubedata.ro/networking-overview.json"},"index_url":"https://docs.danubedata.ro/index.json"}