Skip to main content
CoreWeave Database (CWDB) protects every database with automatic, scheduled backups by default. You don’t configure storage credentials, choose a location, or set up a schedule. The operator handles all of that against CoreWeave-managed storage. Scheduled backups run automatically against every database. Create a CWDBBackup resource when you want an explicit on-demand recovery point. Restores always provision a new database. CWDB doesn’t modify the source database. This page explains how automatic backups work, how to take on-demand backups, and how to restore from a backup into a new database.

How automatic backups work

For every database, the operator runs two coordinated backup streams against CoreWeave-managed object storage:
  • Daily base backups of the entire database, retained for 7 days. The schedule is configurable. See Customize the backup schedule.
  • Continuous write-ahead log (WAL) archiving, which streams every change to backup storage to keep base backups consistent and to support restores.
These scheduled backups let you restore the database to the state captured by any of the last 7 daily base backups. CWDB encrypts backups at rest using a CoreWeave-managed key. CoreWeave handles lifecycle, credentials, and access policies for backup storage. You don’t see or manage backup storage directly.

Customize the backup schedule

To run base backups on a different cadence, set spec.postgres.backupSchedule on the CWDBCluster manifest to a cron expression. By default, CWDB takes one base backup per database per day at midnight (equivalent to a 0 0 0 * * * cron expression). The following example schedules base backups every two hours, at the 15-minute mark:
The operator evaluates schedules in the cluster’s local time zone, which corresponds to the region the cluster runs in. For example, 0 0 6 * * * triggers a backup at 6 AM in the cluster’s region, not at 6 AM UTC. You can change backupSchedule after the database is created. The operator applies the new cadence on the next reconcile. CWDB uses the CNPG backup schedule format, which is a six-field cron expression. The first field is seconds, not minutes. This differs from the more common five-field Unix cron format:
The following table shows common schedule expressions: For the full set of supported expressions and predefined schedules, see the robfig/cron documentation, the underlying parser CNPG uses. The following table describes the field: Retention is fixed at 7 days regardless of cadence. More frequent base backups produce more recovery points within the same 7-day window, not a longer backup history. For most workloads, daily base backups are sufficient. Schedule more frequent base backups only when you have a recovery-point objective the default cadence doesn’t meet. Continuous WAL archiving already covers the gap between base backups for restores.

Opt out of managed backups

Managed backups are on by default for every database. To opt out, set spec.postgres.disableManagedBackups: true on the manifest. The CoreWeave Cloud Console exposes this as the Enable backups toggle in the Create database form (see Create a database).
Disabling managed backups means the database has no recovery point. Only opt out if you have another backup strategy.

View backup status

The CWDB operator surfaces backup history on the CWDBCluster resource and in the Cloud Console.

View backups from the Cloud Console

The Cloud Console exposes a Backups tab on each database’s details panel. The tab lists every available backup for the database, including scheduled base backups and on-demand backups. It’s also the entry point for the Take backup and Restore actions described later on this page. To open the Backups tab, follow these steps:
  1. In the Cloud Console, open Infrastructure > Data and storage and select the Databases tab.
  2. Open the Backups tab in one of two ways:
    • Click the database row to open the details view, then click the Backups tab alongside Details and YAML.
    • In the row’s three-dot menu, select Manage backups.
    Both open the same panel.
Each entry in the list shows the time the backup was taken, a Scheduled or On-demand badge, the compressed size, and the backup ID. Entries are grouped by day and sorted from newest to oldest. To copy a backup ID, click the copy icon next to it. When you restore from a specific backup with kubectl, pass this value to spec.postgres.restore.backupID. The search field above the list accepts free-text matches against backup IDs and supports filtering by field. To list only one backup type, enter type:scheduled or type:on-demand in the search field.

View backups with kubectl

The CWDBCluster resource reflects the status of automatic backups:
The status.backupStatus section reports the timestamp of the most recent successful base backup, current WAL archiving health, and a list of available backups under availableBackups. Each entry in availableBackups includes a composite backupID, timestamp, type (Scheduled or OnDemand), and size. These identifiers are the values you pass to spec.postgres.restore.backupID when restoring from a specific backup.

Create an on-demand backup

An on-demand backup is an explicit recovery point that you create outside the daily schedule. Use one before any operation you want a precise rollback point for: major version upgrades, schema migrations, large data imports, or one-off batch jobs. You can take an on-demand backup from the Cloud Console or by applying a CWDBBackup resource with kubectl. Both methods create the same CWDBBackup resource and count against the on-demand backup quotas.

Create from the Cloud Console

To take an on-demand backup from the Cloud Console, follow these steps:
  1. Open the Backups tab for the database.
  2. At the top right of the Backups tab, click Take backup.
The Console submits a CWDBBackup resource with an auto-generated name and shows a Backup started notification. The backup appears at the top of the list under Today with an On-demand badge as soon as the operator picks it up, and the size column updates from to the compressed size when the backup completes. The Cloud Console doesn’t let you set the CWDBBackup resource name. When you need a specific resource name (for example, to reference the backup from a GitOps manifest or an automated rollback procedure), use the kubectl flow.

Create with kubectl

Create an on-demand backup with a CWDBBackup resource. Save the following manifest as cwdb_backup.yaml. Replace [BACKUP-NAME] with a name for this backup and [CLUSTER-NAME] with your database name:
cwdb_backup.yaml
The CWDBBackup spec is intentionally minimal. The operator resolves the backup destination from the referenced database’s configuration. You never specify object storage details for on-demand backups. Apply it to the same namespace as the database:
Poll the resource to track the backup as it progresses through Pending, Running, and Succeeded phases. A failed backup transitions to Failed:
After it reports Succeeded, the recovery point is durable in backup storage. The status.backupID field is the identifier you pass to spec.postgres.restore.backupID when you restore from this specific backup.

On-demand backup status fields

The CWDBBackup.status exposes the following fields:

List on-demand backups

To see all on-demand backups in a namespace and their current status, run:
You should see output similar to the following:
Example output

On-demand backup quotas

Each database has the following quotas on CWDBBackup resources:
  • Maximum 50 on-demand backups per database.
  • Maximum 10 TB cumulative compressed size per database, summed from status.compressedSizeBytes across all Succeeded backups.
The operator rejects new CWDBBackup resources with phase=Failed if either quota would be exceeded. On-demand backups aren’t subject to the 7-day scheduled-backup retention. They persist until you delete them or until a quota cap is hit. If your workload needs higher quotas (for example, to keep monthly recovery points for compliance), contact your CoreWeave account team.

Delete an on-demand backup

To permanently remove an on-demand backup and free its slot against the per-database quota, run:
The operator runs a deletion finalizer that removes the backup data from object storage and updates the backup registry before the CWDBBackup resource is removed. Deletion is irreversible. If you may need the recovery point, restore from it into a new database before deleting.

Restore from a backup

A restore in CWDB creates a new database from a previously captured backup. There’s no separate restore resource. You create a new CWDBCluster and set spec.postgres.restore to point at the source database and, optionally, a specific backup. The operator bootstraps the new database from the chosen backup as part of its normal provisioning lifecycle. Restores always create a new database. CWDB doesn’t support in-place rollback of an existing database. Common use cases include:
  • Recovering after data loss or corruption.
  • Cloning a production database into a sandbox for testing.
  • Validating a backup before relying on it.
  • Migrating to a new database after a major version upgrade or topology change.
You can restore from the Cloud Console or with kubectl. The Console restore flow is a quick path for a one-off recovery from an existing backup. When you need to script the restore, resize storage during the restore, or restore from user-managed object storage with spec.postgres.restoreObjectStore, use kubectl.

Restore from the Cloud Console

To restore from a specific backup using the Cloud Console, follow these steps:
  1. Open the Backups tab for the source database.
  2. Locate the backup you want to restore from. Use the type:scheduled or type:on-demand filter to narrow the list.
  3. On the backup row, click Restore. The Console opens a Restore from backup panel.
  4. Review the Backup and Configuration summaries (described in the following section) and edit New database name if you want a name other than the pre-filled default.
  5. Click Restore to new database.
The Restore from backup panel summarizes the restore in three sections:
  • Backup identifies the source database, the timestamp the backup was taken, its type (Scheduled or On-demand), its compressed size, and its backup ID.
  • Configuration shows the compute and storage settings the new database inherits from the source. The Console restore flow doesn’t let you change these before provisioning. If the backup is much smaller than the inherited storage size, the panel surfaces a note that you can increase storage after provisioning.
  • New database name is the name of the new CWDBCluster. The Console pre-fills [SOURCE-NAME]-restore-[YYYYMMDD]-[HHMM]. Edit it to give the restored database a different name.
The Console submits a new CWDBCluster with spec.postgres.restore.sourceClusterName set to the source database and spec.postgres.restore.backupID set to the selected backup’s ID. The new database appears in the Databases list with a Provisioning status and transitions to Ready once the operator has bootstrapped Postgres from the backup. The source database keeps running unchanged. After the restored database reaches Ready, you can point your application at the new database, run both side by side, or delete either one. For the cut-over steps, see Cut over to the restored database.
A restore always provisions the new database in the same namespace as the source, whether you use the Cloud Console or kubectl. Cross-namespace restore isn’t supported in limited availability.

Restore from the latest scheduled backup

The minimum required field is spec.postgres.restore.sourceClusterName. When backupID is omitted, the operator restores from the latest entry in the source’s scheduled backup history. Save the following manifest as cwdb_restore.yaml. Replace [SOURCE-CLUSTER-NAME] with the source database name and [NEW-CLUSTER-NAME] with a name for the new database:
cwdb_restore.yaml
Apply the manifest to the same namespace as the source database:

Restore from a specific backup

To restore from a specific backup (for example, the on-demand backup you took before a schema migration), set spec.postgres.restore.backupID to the composite identifier of that backup:
cwdb_restore.yaml
Discover available backup IDs from either of:
  • The status.backupID field on a CWDBBackup resource.
  • The status.backupStatus.availableBackups list on the source CWDBCluster.

Resize storage during restore

When you restore with kubectl, you can set the new database’s spec.storage.resources.requests.storage to a different value than the source. The new database is sized according to its own manifest. The source’s storage size doesn’t carry over. Pick a size that comfortably exceeds CWDBBackup.status.actualSizeBytes for the backup you’re restoring from. Resizing during restore isn’t available in the Cloud Console restore flow. Use kubectl when you need different storage sizing on the restored database.

Restore after deleting the source database

You can restore even after the source database has been deleted. CWDB keeps backup history in a registry independent of the source database’s lifecycle. Set sourceClusterName to the deleted database’s name and the operator looks up its backup history. The new database can reuse the deleted source’s name. The operator allocates a fresh lifecycle context, so there’s no collision with the source’s backup data.

CWDBCluster restore fields

The following fields on a new CWDBCluster control restore behavior: spec.postgres.restore is a one-time bootstrap instruction. After the new database reaches Ready, the operator doesn’t re-process the field on subsequent reconciles.

Monitor the restore

The new CWDBCluster goes through its normal provisioning lifecycle. Track progress with:
The cluster reports Provisioning while the operator bootstraps from the backup, then transitions to Ready once the database is online. Wait for Ready before cutting traffic over:
Large databases take proportionally longer to bootstrap. Plan your recovery time objective accordingly.

Cut over to the restored database

After the restored database is Ready:
  1. Validate the data. Run application-level checks against the new database to confirm the expected recovery point.
  2. Update connection strings. Point your application at the new database’s pooler Service ([NEW-CLUSTER-NAME]-pooler-rw). The credentials Secret is named [NEW-CLUSTER-NAME]-[DBNAME]-credentials. For the default dbName: app, that resolves to [NEW-CLUSTER-NAME]-app-credentials. Use [NEW-CLUSTER-NAME]-[DBNAME]-credentials-ro to route read-only traffic to replicas.
  3. Cut over traffic. Deploy the updated configuration and drain connections from the old database.
  4. Optional: Retire the source database. The source database is untouched by the restore. Keep it until you have confidence in the restored data, then delete it explicitly.
A restore doesn’t modify or pause the source database. Writes to the source database after the restore starts won’t appear in the restored database. If you need the two databases to align, plan a maintenance window or quiesce writes before you restore.
Last modified on July 21, 2026