Skip to main content

Backup and disaster recovery

Who owns each part of DALP recovery: what is stateful, what the charts back up, point-in-time recovery, restore order, failover, and what sets RTO and RPO.

DALP's Helm charts can schedule backups of Kubernetes resources and volumes through Velero, a Kubernetes backup tool. Managed databases and object stores need their own backup and recovery plans, and so do the secrets that decrypt the data. DALP publishes no recovery time objective (RTO, how long until service returns) and no recovery point objective (RPO, how much recent data a recovery may lose). Those figures come from the services you choose, the schedules you set and the restores you rehearse. Configure the backup paths before production and test a restore in an isolated environment.

In an incident, go to Restoring a whole instance. To check that your backups are usable, go to Verify a backup is usable.

Who owns what

The charts run the platform and give you the switches for backup. Your team and your service providers own the recovery plan around them.

This split applies when your team operates the instance. When SettleMint hosts or operates it (Hosting and access), your service agreement sets who carries each item in the last column. What the charts provide does not change.

Area
The DALP charts and platform provide
You own
Platform pods
Separate Deployments per role, with autoscaled api, runner and Console pods, fixed pairs of serving and rebuild indexer pods, disruption budgets and spread rules (Topologies)
Node capacity across failure domains, cluster upgrades, registry access
PostgreSQL
A connection pooler in front of the database you supply
Replication, failover, backups, point-in-time recovery, retention and encryption of the managed service
Redis
Pods that keep serving from an in-process cache while Redis is away
Availability of the Redis service you supply
Object storage
Reads and writes through the configured provider
Versioning, replication and backup of the bucket
Cluster resources and volumes
A Velero schedule and storage location, rendered when you turn on the dalp chart's backup block
A running Velero server, a backup bucket outside the failure domain, the retention window, a tested restore
Ledger networks
Endpoint pools with health-scored failover
The nodes or the provider contracts behind each endpoint, at least two endpoints per network, an archive-capable endpoint for rebuilds
Secrets and keys
A refusal to start without the encryption master password
Storing the master password and the session secret in a secret manager, keeping the governance domain scope in your values file, holding signer credentials where the signer reads them, keeping the custodian credential identity key and its key ID with your other secrets, and backup and replication of the secret manager that holds signer keys when secretManager.provider is not local
Objectives and drills
Alerts in the observability chart for backup failure, database health, indexer ownership and ledger endpoint selection, and a per-chain indexing lag gauge
Setting the RTO and RPO per data class, and running the recovery drill

What is stateful

Platform pods keep no durable state of their own: caches and in-flight work in a pod are lost when it stops. Everything that must survive a failure sits in one of these stores.

Store
What it holds
If you lose it
Recovered from
PostgreSQL
Platform state, workflow journals and the indexed read models. Off-chain records such as approvals, off-chain identity records and workflow state exist only here. With secretManager.provider at its default of local, the encrypted application secrets, including local signer keys, are here too
Off-chain records are gone, and so are the signer keys when the secret manager is local
Your database provider's backup, point-in-time recovery or replica promotion
Indexed read models (inside PostgreSQL)
Typed business data that the indexer decodes from chain events
The indexer rebuilds them from the ledger when a rebuild is declared or requested, and the rebuild needs an archive-capable endpoint
The database restore plus catch-up. The indexer can also index again from the chain's start block, which a release declares or an operator requests
Redis
Cache and change notifications, not a system of record
Service degrades but continues. Pods serve from their in-process tier, and shared cache updates and change notifications stop until Redis returns
Nothing to restore
Object storage
Documents and assets that the Platform API serves, and KYC documents uploaded through the current API, which are sealed under the master password
The files are gone unless your provider kept versions
Your storage provider's versioning or replication
Ledger networks
On-chain state
Not DALP's to lose. The network operators or your node provider keep it, unless you run an in-cluster test network. Its node volumes are backed up only when they sit in a scheduled namespace and carry the schedule's label
The network itself
Secrets and keys
The encryption master password, the session secret, the custodian credential identity key and its key ID, and the governance domain scope, the name that scopes the signing of governance ballots. Signing keys sit in the application secrets, in the secret manager that secretManager.provider names, or with your custody provider when signer.provider is dfns, fireblocks, luna, ripple or utila
Without the master password, encrypted rows stay unreadable, because a new password cannot decrypt data sealed under a lost one. KYC documents uploaded through the current API are sealed the same way, so a restored bucket without the password cannot be read. Documents that arrived through the frozen /api/v1 upload are stored as uploaded. Changing the session secret (BETTER_AUTH_SECRET) without its rotation procedure can break access, a changed governance domain scope invalidates the ballots signed under the old name, and a changed custodian credential identity key leaves stored credential identities incomparable until the backfill re-hashes them
Your secret manager for the master password and session secret, and your values file for the scope. Signing keys come from the PostgreSQL restore when secretManager.provider is local, from your secret manager when it is aws, gcp, azure or vault, or from your custody provider
Observability data
Logs, traces and metrics
Investigation history is gone
Not needed to restore service. The observability stack sets its retention

What gets backed up, and what does not

When you turn on the dalp chart's backup block, the charts back up what runs inside your Kubernetes cluster through Velero, the Kubernetes-native backup tool they drive. A service outside the cluster, such as your PostgreSQL, Redis or object storage, backs up through its own mechanism, not through DALP. Prerequisites lists a tested backup and restore for PostgreSQL and object storage as a go-live item.

What
Backed up by
How
Kubernetes resources and volumes in the release namespace, by default
The dalp chart's Velero schedule
Every labelled resource, with its volumes copied by Velero's file-level backup engine (Kopia unless your Velero server selects another uploader), once a day by default. backup.namespaces.additional widens the schedule to more namespaces
PostgreSQL (a managed service is the recommended production path)
Your database provider
Not orchestrated by these charts
Redis
Your provider, if it offers one
Not orchestrated by these charts. Redis here holds cache and change-notification state, not a system of record
Object storage
Your storage provider's versioning or replication
Not orchestrated by these charts

The schedule runs no Velero backup hook, so a Velero copy of a database volume is a crash-consistent file-system copy, not a pg_dump or an application-quiesced snapshot. If you run PostgreSQL inside the cluster, use a database-native backup and verify recovery for production data.

Cluster resources back up through Velero. Services outside the cluster back up through their own mechanism.Two backup paths split by who owns the data. Inside the cluster, the DALP chart's own Velero schedule backs up Kubernetes resources and persistent volumes in the release namespace by default, widened by backup.namespaces.additional, as a file-system copy. No database-aware hook is configured, so a volume backup of a database you run in the cluster is crash-consistent rather than application-consistent. Outside the cluster, a PostgreSQL, Redis or object storage service that you supply backs up through its own provider mechanism entirely, and none of it is orchestrated by these charts. Every cluster backup lands in the bucket that backup.storage names. The shipped default endpoint is an in-cluster address, so set backup.storage to a bucket you supply before production. On the DALP chart's own schedule, only resources still carrying the default kots.io/app-slug label fall inside that backup's scope, and a resource that loses the label drops out silently, with no failure or alert.Cluster resources back up through Velero. Services outside the cluster back up through their own mechanism.The same figure as the desktop variant, drawn portrait for phone widths, and in the same reading order: what the DALP chart's Velero schedule backs up inside the cluster, where that backup lands, and its label selector scope, before the unconnected outside-the-cluster services at the bottom. Inside the cluster, the DALP chart's own Velero schedule backs up Kubernetes resources and persistent volumes in the release namespace by default, as a file-system copy. No database-aware hook is configured, so a volume backup of a database you run in the cluster is crash-consistent rather than application-consistent. That schedule's backups land in the bucket that backup.storage names. The shipped default endpoint is an in-cluster address, so set backup.storage to your own bucket before production. Only resources still carrying the default kots.io/app-slug label fall inside the schedule's scope. Outside the cluster, and outside these charts entirely, a PostgreSQL, Redis or object storage service that you supply backs up through its own provider mechanism.

The dalp chart's Velero schedule backs up the release namespace, while PostgreSQL, Redis and object storage that you supply back up through their own providers.

How the backup block works

The dalp chart never deploys a Velero server, and it is the one chart that decides what gets backed up and where. Its backup block, off by default, creates the BackupStorageLocation and Schedule. These custom resources need a Velero server that you run, for example an installation of OpenShift API for Data Protection (OADP) or Velero itself. Enabling the block backs up nothing until that server runs. Velero reconciles only its own namespace. The chart renders these resources in the release namespace unless you set backup.veleroNamespace to the Velero server's namespace, for example openshift-adp for OADP. An existingSecret you name must live in that same namespace. A workload identity (IRSA, Azure managed identity, GCP workload identity) takes effect once you bind it to the Velero server's service account, plus whatever pod settings your provider's Velero plugin documents. The shipped storage defaults are for development: the endpoint is an in-cluster address and backup.storage.s3.insecureSkipTLSVerify is true. Set both before you enable the block, as Decisions to make before you need a restore describes. What the block does with the credentials Secret depends on what you set.

You set
The chart creates
backup.storage.aws.useIRSA, azure.useManagedIdentity, or gcp.useWorkloadIdentity
No Secret, and no credential reference on the BackupStorageLocation
backup.storage.s3.existingSecret (or the equivalent field for your provider)
No Secret. The BackupStorageLocation references the one you already manage
accessKeyId and secretAccessKey inline (storageAccountKey for Azure, not offered for GCP)
The Secret, populated from those values
None of these, the shipped default
Nothing: the render fails and names the missing field, so no location ever points at a Secret that does not exist

What the default schedule captures

These are the dalp chart's own backup.* defaults.

Setting
Default
What it means
backup.schedule.cron
0 2 * * *
Daily, at 02:00
backup.retention.days
30
Sets the backup's TTL to 720 hours. Velero deletes the recovery point, and the objects it wrote, once the TTL expires
backup.includeAllPVCs
true
Turns on defaultVolumesToFsBackup, the file-system backup mode, for every included volume
backup.labelSelector.matchLabels
kots.io/app-slug: settlemint-dalp
A packaging label that the dapp, dapi, blockscout, docs and investor-portal charts set on their resources, so the default selector matches them without extra configuration
Cluster-level resources
Excluded
includeClusterResources is hardcoded false, so the schedule only ever backs up namespaced resources
Excluded resource types
events, events.events.k8s.io
Hardcoded, not configurable
Storage location name
<fullname> plus a fixed suffix
The suffix does not change with the provider, so an Azure- or GCP-backed location keeps the same resource name pattern. Find it with kubectl get backupstoragelocations.velero.io
Schedule name
<fullname>-daily
The name to look for with kubectl get schedules.velero.io

Point-in-time recovery

Point-in-time recovery returns a database to a chosen moment between two backups by replaying its write-ahead log. The DALP charts do not configure it. The Velero schedule copies each volume's files once a day by default, so its recovery points are the schedule's run times and not arbitrary moments.

For production, point-in-time recovery is a feature of your managed PostgreSQL service. Ask the provider for three answers and record them in the database's recovery plan:

  • The retention window, meaning how far back you can restore.
  • The finest restore granularity.
  • Whether a restore creates a new instance, which decides how you repoint the platform to it.

A restore to an earlier moment removes the off-chain records written after it. Whatever reached the ledger after that moment stays on the ledger. With the default local secret manager, a signer key or secret created after the restore point is lost with it, and the platform can no longer sign for the on-chain assets or roles that key controls. The indexer resumes from the position stored in the restored database and reads forward from there. Compare restored records with the ledger before you reopen traffic.

Decisions to make before you need a restore

Decide your storage target and who owns its credentials. backup.storage.provider accepts s3, aws, azure, or gcp. The shipped default endpoint is an in-cluster address, and the default s3 location ships with backup.storage.s3.insecureSkipTLSVerify set to true, so point it at a bucket you supply and set that value to false. Store production recovery points outside the failure domain they must recover from. The chart creates no inline credentials secret for GCP. Either supply backup.storage.gcp.existingSecret or set backup.storage.gcp.useWorkloadIdentity and skip the secret entirely.

Decide your retention window from your compliance or evidentiary needs. The 30-day default TTL is the only retention control. Velero keeps no minimum count of backups once older ones expire. If a regulator or an internal policy expects a longer recovery window, raise retention.days. Do not assume a floor exists underneath it.

Decide whether the default label scope covers what you need backed up. A resource that never carried kots.io/app-slug: settlemint-dalp, or that loses it later, silently falls outside the schedule. The schedule keeps completing successfully and backs up less than you expect. The pgbouncer and postgres-exporter subcharts are on by default and do not carry the label. The umbrella chart's own resources, including the shared application environment Secret that holds the encryption master password and the session secret, carry it only when you add kots.io/app-slug: settlemint-dalp to global.labels on the release. Adding that label puts the Secret, and with it the master password, in the backup bucket. Without it, a Velero-only restore needs a Helm upgrade to recreate that Secret from your secret manager. Confirm the scope with kubectl get all,pvc,configmap,secret -l kots.io/app-slug=settlemint-dalp -n <namespace>, run the same command without the label, and compare the two lists against what you expect to matter in a restore.

Decide how each datastore fails over and recovers. You supply PostgreSQL, Redis and object storage, so a restore and a failover promise only what your providers promise. See Failing over.

Confirm the backup alerts reach someone. Three Velero alert rules ship in the observability stack, and all three default to warning severity, not critical. They fire only after you switch on alerting in the observability stack and only when the Velero server's metrics are scraped. Until then, nothing alerts on a failed backup.

Alert
Condition
For
VeleroBackupFailure
A backup failed in the last hour
5 minutes
VeleroBackupPartialFailure
A backup partially failed in the last hour
5 minutes
VeleroBackupStale
No successful backup for a schedule in over 24 hours
15 minutes

A stale schedule can run silently broken for more than a day before VeleroBackupStale fires, because the rule waits for 24 hours without a success and then holds for 15 minutes. If your operating process needs faster notice than that, do not assume the default severity routes to an on-call page. Confirm it does, or raise it.

Verify a backup is usable

The Grafana dashboard Cluster · Backups & Policy (uid backups-policy) gives you the automated signal: its “Backup failures” panel and “Last successful backup” panel tell you a schedule ran and did not error, and the three Velero alerts tell you when a running schedule fails. The alerts read metrics from the Velero server. They stay silent when no Velero server runs, when its metrics are not scraped, or when a schedule has never completed a backup. Neither the dashboard nor the alerts tell you the data that came back is usable. Only a test restore does that.

Run a test restore on a fixed schedule that your recovery plan names, and at least before your first production go-live and after any change to backup.storage, backup.labelSelector, or backup.schedule. Restore into a namespace other than the one the backup came from, so you can inspect the result without touching a live workload. Confirm the resource and volume counts match what you expected. For anything that held database data, confirm the application starts cleanly against it, rather than only checking that files arrived. A restored environment Secret points at your production database, cache and ledger endpoints, and with the default labels the restore lacks that Secret and the pooler until a Helm upgrade recreates them. Before any restored pod starts, apply the isolation in Rehearse a recovery, step 1. Delete the test restore's namespace once you have confirmed it, so a stale test copy does not linger as a second, unmanaged instance.

Restoring from a backup

  1. Confirm which backup you are restoring from. A backup's phase must read Completed, not PartiallyFailed, before you trust it as your restore source. A partial failure means some resources or volumes did not make it in.

    kubectl get backups.velero.io -n <velero-namespace>

    This lists every backup in the namespace, including those the <fullname>-daily schedule created. <velero-namespace> is the release namespace unless you set backup.veleroNamespace.

  2. Decide your target before you create the restore. Restoring into the same namespace where the original resources still exist behaves differently from restoring into an empty namespace or a new cluster. Existing-resource handling depends on Velero's configured restore policy. Do not assume a restore overwrites live resources. For a test restore, set spec.namespaceMapping on the Restore (step 3) to restore into an empty namespace instead of overwriting anything live.

  3. Create the restore from the chosen backup by applying a Restore resource, then watch its phase rather than assuming it finished because the command returned.

    apiVersion: velero.io/v1
    kind: Restore
    metadata:
      name: <restore-name>
      namespace: <velero-namespace>
    spec:
      backupName: <backup-name>
      namespaceMapping:
        <original-namespace>: <target-namespace>
    kubectl get restores.velero.io <restore-name> -n <velero-namespace> -w
  4. Wait for volume restores to finish separately from the resources that reference them. The default schedule backs up volumes at the file-system level, so a restored pod can stay pending after its other resources already exist, while its volume's own restore is still copying data in the background. Watch the PodVolumeRestore resources Velero creates for this restore, not only the pod's own status:

    kubectl get podvolumerestores.velero.io -n <velero-namespace>
  5. Confirm what came back before you call the restore done. A Completed restore proves Velero moved the bytes it had. It does not prove the data is transactionally consistent, since no backup hook runs against a database volume before the copy is taken. Start the application against the restored data and confirm it comes up cleanly, as Verify a backup is usable describes.

Restoring a whole instance

A Velero restore brings back cluster resources and volumes. A full recovery after losing a cluster or a region also needs the datastores, the secrets and the ledger connection. Before step 1, confirm that the lost instance is stopped, so that two instances never act on the same ledger at once. Restore in this order. Steps 1 and 2 gate the platform, and steps 3 and 4 can run beside step 2. Keep traffic closed until step 8.

  1. Recreate the secrets. Take ENCRYPTION_MASTER_PASSWORD and BETTER_AUTH_SECRET from your secret manager, and set DALP_GOVERNANCE_DOMAIN_SCOPE from your recorded values file, all to the values the lost instance used, together with CUSTODY_CREDENTIAL_IDENTITY_KEY and CUSTODY_CREDENTIAL_IDENTITY_KEY_ID (Custody credential identity key). The platform refuses to start without the master password, a different password cannot decrypt the restored rows, a changed governance domain scope invalidates every ballot signed under the old name, and a changed custodian credential identity key leaves stored credential identities incomparable until the backfill re-hashes them. Restore the credentials of a custody provider from the same source. When secretManager.provider is not local, restore that store to the same point as PostgreSQL. Values and secrets describes each value.
  2. Restore PostgreSQL through your provider, either from a backup or to a chosen moment (Point-in-time recovery). Point global.datastores at the restored instance. The network catalogue and the RPC endpoint pools are in this database, so they return with it. Their credentials decrypt with the master password from step 1.
  3. Restore object storage through your provider, from its versions or its replica.
  4. Provide a Redis service. There is nothing to restore, because the platform treats Redis as a cache and notification transport.
  5. Install or upgrade the dalp chart. With the default hook type, the migration Job runs first, and the application Deployments update only after it succeeds. See Upgrades and migrations.
  6. Confirm that every network's endpoint pool is reachable from the new site, and that each network still has at least two endpoints.
  7. Watch the indexer catch up, as Catch-up and re-index time describes. Confirm that the application starts cleanly against the restored data, that the Platform status screen shows no stalled workflows, and that the newest restored records agree with the ledger.
  8. Switch DNS, ingress and routing to the recovered site, and reopen traffic.

Catch-up and re-index time

The platform publishes no figure for how long indexing takes after a restore, because the time depends on your chain and your endpoints. Two cases differ.

After a database restore, the indexer reads only the blocks between the stored position and the chain head. Divide that gap in blocks by the rate at which the lag shrinks to size the catch-up. The Console's Platform status screen shows how many chains are in sync and the delay of the furthest-behind chain, its Indexing detail view shows the state per network, and the indexer exports the dalp_didx_watermark_lag_blocks and dalp_indexer_serving_lag_blocks gauges. Ledger indexing stalled explains how to tell catch-up from a stall.

A rebuild is longer. A release that changes how earlier data is recorded declares one, and an operator can request one, as Ledger indexing stalled describes for a chain generation mismatch. The platform then indexes each network again from its start block into a new dataset while the current one keeps serving. Rebuild time grows with the length of the chain history, the volume of events and your provider's rate limits. The rebuild needs an archive-capable endpoint, because it asks for state at old blocks. Reads keep using the current dataset, and a read that needs data that is not available yet can receive a retryable rebuilding response. Measure a rebuild on your own data before you rely on it in a recovery plan.

Failing over

Failover splits into three jobs, because they answer to three different owners: compute, the stateful layer and the ledger connection.

Compute failover is a reschedule, because every Platform API pod and the Console are stateless. Recovering compute also requires reachable datastores, secrets, registry access, network endpoints, and routing in the target environment. Validate those dependencies before sending traffic there.

The stateful layer is where failover is decided, and it depends entirely on the services you supply. Failover for PostgreSQL, Redis and object storage is your provider's own replication and promotion mechanism, not something these charts orchestrate. A provider running a live standby promotes it, and your recovery point tracks that standby's replication lag, not the age of your last Velero backup.

A datastore with no live standby has nothing to fail over to. A cluster or regional loss then means restoring your most recent backup into new infrastructure, not promoting a replica. Recovery reaches the latest usable backup. Successful daily backups can leave a 24-hour gap, and missed or unusable backups make the gap longer. Choose services with a replica or standby for production.

Failover to the ledger is a third job, and the platform does it for you when a network has more than one endpoint. The platform scores each endpoint in a network's pool on its error rate, its latency, how far it lags behind the chain head and how far it lags behind finality. Each endpoint also carries a weight that a platform administrator sets in the pool. The platform then routes as follows:

  • It leaves out an endpoint whose head lag passes 50 blocks or whose score falls below 0.25.
  • It sends calls to the healthy endpoint with the highest weight, and prefers the better score among endpoints of equal weight.
  • It retries a transient error with backoff and moves away from a dead endpoint.
  • If every reachable endpoint is excluded, it keeps calling the excluded ones rather than failing.
  • It keeps the serving endpoint when the best rival has the same weight, the last switch was under 60 seconds ago and the rival scores less than 0.1 higher. This stops two healthy endpoints from trading places. An endpoint that falls out of the healthy set is replaced without waiting for that interval.
  • If no endpoint can serve a call, the caller receives an error.

The limits and the switching values are defaults. A platform administrator edits the pool in the Console under Networks, and the change applies without a restart. Health-based selection needs fresh scores. When the platform holds no usable score for any endpoint of a network, selection is not active for that network and the platform logs it as degraded. It then chooses endpoints in their configured order and stops excluding unhealthy ones, and after 15 minutes the RpcHealthSelectionDisabled alert fires. Treat that alert as degraded failover until scores return. A network with a single endpoint has nothing to fail over to.

What sets your RTO and RPO

Your RPO is the longest span of recent data you accept losing, stated as a time. Your RTO is the longest outage you accept before the platform serves traffic again. DALP states neither as a number, and no figure on this page is a commitment. Each one depends on choices that sit with different owners, and the weakest store sets the objective for the platform as a whole.

Part of the objective
What moves it
Who sets it
RPO for PostgreSQL
The provider's backup interval, its point-in-time retention, and the lag of a live standby. With a standby, the recovery point tracks the standby's replication lag
You, through your database provider's plan
RPO for cluster volumes
backup.schedule.cron (daily at 02:00 by default). A failed run lengthens the gap
You, in the dalp chart's values
RPO for object storage
The provider's versioning and replication settings
You, through your storage provider
RTO for the data stores
How long the provider takes to restore a database or promote a standby, and how long a volume restore takes to copy data back
Your providers, and your own measurement
RTO for the platform
The migration Job's run time, which the chart caps at 10 minutes by default (dapp.migrator.timeout), pod start-up, and node capacity in the recovery site
You, in the chart's values and the cluster
RTO for ledger data
The indexer's catch-up, or a rebuild, and the speed and rate limits of your endpoints
You, through your endpoints and chain history
RTO for traffic
DNS, ingress and routing in the recovery site
You

Set the objectives per data class with your risk owner. Off-chain records and documents have no other copy, and usually need the tightest RPO. Indexed read models can be rebuilt from the ledger, so a looser RPO costs time and not data. Retention (backup.retention.days, 30 by default) sets how far back you can restore, and does not set the RPO. A provider's published service levels apply to that provider's service alone and do not add up to an objective for the platform as a whole.

Rehearse a recovery

DALP ships no disaster recovery test tool, so you schedule and record the drill. Run it on the occasions that Verify a backup is usable lists, and after a change of database or object storage provider.

  1. Build an isolated target. The target holds production's master password, workflow journals and, with the default secret manager, signer keys, and its restored endpoint pools point at production endpoints.
    • Use a separate namespace or cluster, and never the namespace that serves production.
    • Before the pods start, block all egress except to ledger endpoints that serve reads only. That includes your custody provider and webhook receivers. A local signer signs inside the platform, so blocking the custody provider alone does not stop it.
    • Give the target its own DALP_GOVERNANCE_DOMAIN_SCOPE, because the chart's values say never to copy the scope between installs. Ballots signed under the production scope then stop verifying in the target, which a drill does not need.
    • Copy CUSTODY_CREDENTIAL_IDENTITY_KEY, although the values give the same rule for it, so the restored custody credentials stay readable. That is one more reason to keep the target isolated and delete it in step 6.
    • After the pods start, replace each pool in the Console under Networks with endpoints that serve reads only and refuse transaction submission, before you time the indexer catch-up. The network catalogue in the database overrides the deployment values.
  2. Note the moment at which you simulate the failure. Restore PostgreSQL, object storage and the secrets from the sources your plan names, following steps 1 to 7 of Restoring a whole instance, apart from the governance domain scope in step 1. Run the checks in step 5 below before any routing change, and simulate step 8 without moving production traffic.
  3. Time the drill from the moment you noted to the point where the target could serve traffic. Record each stage as well: the secrets, the database restore, the object storage restore, the migration Job, the pods becoming ready and the indexer's lag reaching zero. Stages that run beside each other count once. The result is your measured RTO. If your drill skips a stage, say which one.
  4. Compare the newest record in the restored instance with production at the moment you noted in step 2. The difference is your measured RPO.
  5. Run the checks in Verify a backup is usable and confirm that the application starts against the restored data.
  6. Record the timings and the gaps against the objectives, delete the target, and fix what the drill exposed before the next one.

What deletion removes

Once retention.days elapses, 30 days by default, Velero deletes that recovery point and the objects it wrote from your bucket, with no undo. Deleting the bucket a BackupStorageLocation points at destroys every recovery point that location owns, not only the newest one.

Measure recovery time with your own volumes. The chart does not guarantee a restore duration.

For restores into a namespace with existing resources, check the behaviour of your installed Velero version and its resource policy first. An isolated test target avoids relying on overwrite behaviour.

Frequently asked questions

Does a restore bring back cluster-scoped resources like ClusterRoles?

No. includeClusterResources is hardcoded false in the default schedule, so nothing cluster-scoped ever enters the backup, and a restore has nothing to bring back for it. If your workload depends on a ClusterRole, a ClusterRoleBinding, or another cluster-scoped object, reapply it separately, from your chart's rendered manifests or your own record of it, before or after the restore runs.

Does raising backup.retention.days extend the life of backups that already exist?

No. Velero sets a backup's time-to-live from retention.days at the moment that backup is created, not on an ongoing basis, so a change to the value only lengthens the life of backups taken afterwards. A recovery point already deleted stays deleted, and one still alive under a shorter TTL from before your change keeps that original TTL rather than adopting the new one.

If I change backup.storage.provider, do my existing backups move with it?

No. The dalp chart's BackupStorageLocation keeps one fixed name regardless of provider, and changing backup.storage.provider repoints that same location at a different bucket or account rather than copying objects between them. Your existing recovery points stay in the old bucket and become unreachable through this location once you repoint it, so migrate or archive anything you still need before you switch.

Was this page helpful?