GitLab disaster recovery options compared: which approach fits your instance
Your self-managed GitLab instance holds source code, merge request reviews and pipeline history, and losing any of it can stop delivery for days. The right recovery approach depends on two things: how large the instance is and how much data loss the business can tolerate. The three options, backup archives, disk snapshots and Geo, are complementary rather than alternatives, and most mature setups combine them. Start by writing down a recovery point objective and a recovery time objective for repositories, the database and uploads separately, because they rarely need the same answer.
Backup archives are produced by the GitLab backup command and capture the database, Git repositories, uploads and related data as a portable set of files. The GitLab backup and restore documentation describes them as the way to recover from data corruption, accidental deletion or a restore onto new hardware, and they can be copied off-site and kept for retention. They do not contain gitlab-secrets.json or gitlab.rb, so those files need their own copy. Restores are slow on large instances and must match the GitLab version and edition of the backup. Disk snapshots capture the storage volumes at a point in time and can restore a whole host quickly, but they are only consistent if the database and Git data are quiesced or captured together, which the backup documentation addresses for large instances. Snapshots protect against host or volume loss; they do not protect against bad data written before the snapshot.
Geo provides a warm-standby secondary site in another region that is continuously synchronized, according to the GitLab Geo documentation. It shortens recovery time and reduces data loss when the primary site fails, but replication is not a backup: a deleted project or a bad change is replicated too. Geo is available in the Premium and Ultimate tiers for self-managed GitLab, so confirm the edition you need before designing around it. Plan to keep backup archives alongside Geo, and confirm with your team how failover, re-adding the old primary and restores interact with your retention rules before the first incident.
Backup archives, snapshots and Geo: when each fits
This table compares GitLab backup archives, disk snapshots and Geo warm standby on what each protects, recovery point, recovery effort, instance size fit and gaps. Read each row against your own data loss tolerance, and treat the gap rows as the items to confirm against the GitLab backup and restore documentation before you rely on any single method.
| Factor | Backup archives (gitlab-backup) | Disk snapshots | Geo warm standby |
|---|---|---|---|
| What it protects | Database, Git repositories, uploads and most instance data written by the backup task | Entire disks or volumes at one point in time, including files the backup task skips | Continuously replicated copy of instance data in a second site, in another region |
| Recovery point | The time of the last completed backup, so the schedule sets the maximum data loss | The time of the snapshot, usually set by your snapshot schedule and consistency method | Typically the most recent replicated state, with lag that depends on replication |
| Recovery effort | Restore onto a matching GitLab version and edition, then reconfigure and verify | Restore volumes, then check services, database state and consistency before use | Promote the secondary site and redirect users, following the documented failover steps |
| Instance size fit | Works for small instances; backup and restore windows grow with database and Git data | Often used for large instances where archive windows are too long, with consistency planning | Suited to large, multi-site or distributed teams that need a warm standby |
| Secrets file (gitlab-secrets.json) | Not covered by the archive, so back it up separately with gitlab.rb | Covered only if the snapshot includes the config directory, so confirm this per environment | Must be kept consistent across sites, so confirm how the secondary receives it |
| Object storage content | Artifacts, LFS, uploads and registry blobs in object storage are skipped, so use provider versioning or replication | Does not capture object storage data held outside the instance disks | Object storage replication needs its own configuration, so confirm coverage for each data type |
| Runner configuration | Runner config.toml and runner registration are outside the core backup, so record them separately | Covered only if the runner host is part of the snapshot, which is often not the case | Runners are not replicated by Geo, so plan their rebuild or config recovery |
| Still needed alongside the others | Yes, as the independent copy for point-in-time restore and recovery from logical errors | Yes, when snapshots are not application-consistent or are kept in the same failure domain | Yes, because replication copies bad changes too, so Geo does not replace backups |
Why Geo still needs backups
Geo gives you a warm standby, not a restore point. A GitLab Geo secondary in another region is continuously synchronized, so it can take over when the primary site is lost. That same continuous synchronization is the problem for recovery from mistakes. A deleted project, a force-pushed branch, a bulk permission change or a corrupted database row replicates to the secondary within moments. Once the secondary has caught up, it holds the damage too. Point-in-time backups are what let you go back to a state from before the error, so every Geo design still needs a backup archive that is stored separately and kept long enough to cover your detection window.
The layers do different jobs. The backup archive, created with the GitLab backup command and documented in the GitLab backup and restore guide, gives you versioned, portable copies of the database and Git data that you can restore to a clean instance. Disk snapshots of the primary's storage give fast infrastructure-level recovery, but they must be coordinated with GitLab's consistency guidance, and a snapshot of a damaged volume is still a damaged volume. Geo handles site loss with minimal downtime. In practice, the Geo secondary is the fastest recovery path for an outage, and the archive is the path for data loss caused by people or software.
Confirm two coverage gaps before you rely on this design. First, check whether the gitlab-secrets.json file and your gitlab.rb configuration are replicated to the secondary in your topology and whether you hold an independent, current copy of each; a restored database without its matching secrets file leaves encrypted tokens and CI variables unreadable. Second, confirm how your object storage is covered. Artifacts, LFS objects, uploads and registry blobs stored in S3, GCS or Azure are not included in the standard backup archive, so ask your team which replication, versioning or retention settings protect them, and test that they restore together with the database and repositories.
How to choose and validate a recovery approach
This sequence turns instance size and recovery targets into a tested recovery design, so you know which combination of backups, snapshots and Geo you can actually restore from before an incident forces the question.
Record instance size and data volumes
The platform or GitLab administrator records the GitLab version and edition, user count, database size, Git repository data size, and where artifacts, LFS objects, uploads and registry blobs are stored (local disk or object storage). Size drives the choice: the GitLab backup and restore documentation sets out how the archive scales with data, and large instances need a separate plan. Done means a one-page inventory exists that someone outside the team could read and check against the live instance.
Agree recovery point and recovery time objectives
Business owners, the security lead and the platform team agree in writing how much data loss is tolerable (recovery point objective) and how long a restore may take (recovery time objective) for source code, merge requests, CI/CD configuration and artifacts. Ask the business to rank these separately, because a repository may tolerate a day of loss while audit evidence tolerates none. Done means signed targets exist for each data class, and any target that cannot be met by backups alone is flagged for Geo or snapshots.
Choose the approach or combination
Map each target to an approach: backup archives for point-in-time recovery of the application data, disk snapshots for fast infrastructure-level recovery (with the GitLab documentation's guidance on consistent snapshots applied), and Geo warm standby for a continuously synchronized secondary site in another region. Geo is available in the Premium and Ultimate tiers, so confirm your edition first. Done means a written decision record states which approach covers which data class and why, with Geo treated as a complement to backups, not a replacement.
Configure backups, snapshots and any Geo secondary
The platform team configures scheduled backups, stores copies outside the primary failure domain, and sets up snapshot schedules or a Geo secondary where the decision record requires them. Secrets and configuration files are backed up alongside the archive, because a restore without the matching secrets fails in ways that are hard to diagnose. Check that the backup job completes, that archives land in the intended location, and that the secondary reports replication status. Done means a dated run log and a replication report exist for each component.
Confirm version and edition matching for restores
Before any restore test, confirm that the restore target runs the same GitLab version and edition as the source that produced the backup, and that the matching packages are kept for that version. Upgrade stops also matter here: if the environment will be upgraded later, check the required upgrade stops in the GitLab upgrade paths documentation so the recovery target is not stranded between versions. Done means a version record lists the source version, target version, edition and the package file kept for rebuilds.
Run a restore test on a separate environment
The team restores the latest backup, and where Geo is used, tests promotion of the secondary, on an isolated environment that cannot reach production users or runners. Restore secrets first, then data, then confirm repositories, users, CI/CD pipelines and object storage links work, and record the actual elapsed time against the recovery time objective. Done means a written test report shows whether the recovery point and recovery time objectives were met, and any gaps are logged as remediation items with owners.
Validate procedures against official documentation and the environment
Before the design is accepted, the platform team reviews each runbook step against the current GitLab backup and restore and Geo documentation, and confirms that commands, configuration keys and paths match the installed version. Your own environment (network, DNS, certificates, object storage provider) is checked separately because the documentation cannot know it. Ask DeployOpen or your internal team to confirm any step the documentation leaves open. Done means a signed runbook, a list of confirmed open questions, and a scheduled repeat of the restore test after each upgrade.
Which recovery pattern fits small, mid-size and large instances
Smaller self-managed instances, starting at the bottom of the published reference architecture range of 1,000 users, usually have data volumes and restore windows that a scheduled backup archive can handle without extra machinery. A single, well-tested backup routine with off-host storage is often the starting point, and the recovery design can stay simple because the time to rebuild is shorter.
- Backup archive as the core: A scheduled GitLab backup, stored off the host, covers repositories, database and most instance data for this size.
- Secrets stored separately: Keep
gitlab-secrets.jsonandgitlab.rbin a secured location outside the backup archive, since a restore without them can fail to decrypt data. - Restore rehearsal on a spare host: Practice a full restore onto matching package versions before you need it.
- Lower urgency for standby sites: A warm-standby Geo secondary is usually harder to justify at this size unless the business has a strict recovery time goal.
- Single-node assumptions: Confirm which components run on the same host, because that determines what a single backup must capture.
Confirm the database and Git data size limits, and the backup duration you can accept, against the GitLab backup strategy documentation before settling on this pattern.",
Mid-size instances, typically in the range where the reference architectures move from the smaller tiers toward several thousand users, begin to feel the cost of backup windows and restore duration. Snapshots of the underlying disks, taken in a coordinated way with the application, can shorten recovery, while backup archives remain the fallback that proves data is restorable across versions.
- Backup and snapshot together: Pair scheduled archives with disk snapshots so you have both a fast rollback path and an independent, portable copy.
- Backup window pressure: As repository data grows, backup duration grows with it, which makes restore rehearsal timing more important.
- Reference architecture sizing: Check the sizing tier you run against the published reference architecture for your user count and API load.
- High availability planning: Begin planning for high availability as you approach the 3,000 user point where the docs generally recommend it.
- Upgrade stops during recovery: Keep the restore target on a version that is on a required upgrade path, so a restore does not strand you between stops.
Confirm with GitLab which snapshot and read-only procedures are supported for your database and Git data sizes, using the backup strategy documentation.",
GitLab generally recommends a high availability strategy from 3,000 users. At that point the architecture typically separates components across nodes, using Gitaly Cluster with Praefect for Git data, PostgreSQL with Patroni, Redis Sentinel and Consul. Recovery planning changes because a single backup of one node no longer describes the whole platform, and restore procedures must account for each stateful component.
- Multi-node backup scope: Confirm which nodes hold which data, and back up each stateful component consistently.
- Failure of one node versus site loss: High availability protects against node failure, but it does not protect against losing a site, so backups or Geo remain necessary.
- Stateful components outside Kubernetes: The reference architectures do not support running PostgreSQL or Redis inside Kubernetes, so their recovery runs on VMs or managed services.
- Restore testing scale: A restore test on a multi-node layout takes more planning, hosts and time than a single-node test.
- Documented procedures: Use the version-specific restore and failover instructions rather than generic steps.
Confirm the high availability layout you will run and its backup coverage with GitLab before committing to a recovery design.",
At the upper end of the range, up to 50,000 users and 1,000 API requests per second in the published reference architectures, backup archives can take long enough that they no longer fit comfortably into a recovery window. Large deployments usually combine snapshots, a Geo warm-standby secondary and carefully planned archives, because each covers a different failure. Geo keeps a second site synchronized, but it is not a backup, so archives still matter for corruption, accidental deletion and point-in-time needs.
- Geo as warm standby: A secondary site in another region is continuously synchronized for disaster recovery, which shortens failover compared with a restore.
- Archives for logical errors: Replication copies mistakes as well as data, so keep archives that let you roll back to an earlier point.
- Snapshot coordination: Large snapshots need planned read-only windows and consistent capture across database and Git storage.
- Object storage data: Artifacts, LFS and registry data may need their own provider versioning and replication, since the backup command does not always cover them.
- Recurring cost of a second site: A standby site adds infrastructure, licensing and operations work that recurs for as long as it runs.
Confirm with DeployOpen or GitLab which combination meets your recovery time and data loss goals before any build starts.
Protecting recovery copies themselves
A recovery copy is only useful if it can be restored, and it is also a concentrated copy of your source code, secrets and user data. The cards below cover the risks that appear in the recovery path itself, from archive contents and storage access to where copies sit relative to the primary site. Confirm each control in your own environment before relying on it.
Archives contain source and secrets
A GitLab backup archive holds repositories, database content and, when included, configuration that can expose credentials. The gitlab-secrets.json file is needed to decrypt sensitive values after a restore, so it is as sensitive as the database it protects. Treat every archive and the secrets file as restricted material with the same classification as production, and confirm which files your backup job actually copies.
Access control on backup storage
Backup buckets, NAS shares and tape libraries often have looser permissions than the production instance they came from. Review who can list, read, overwrite or delete recovery copies, and separate the identity that writes backups from the identities that read or purge them. Confirm this with your storage platform's audit logs and your own access review process.
Encryption at rest
Encrypt recovery copies at rest with keys managed outside the GitLab host, so that a stolen disk or bucket snapshot does not expose plaintext. Decide where key material lives, who can rotate it, and how a restore responder gains access to keys during an incident. Confirm the encryption method and key custody with your storage and key management teams.
Restore access for responders
During an incident, the people who need to restore may not be the people who normally administer the system, and their accounts may be locked or unavailable. Define a break-glass path with named responders, documented approvals and tested access to archives and secrets. Verify this before an incident by running a restore drill that uses only the access the responders would have in practice.
Copies outside the failure domain
A backup stored in the same cloud account, data center or credential scope as the primary can be lost in the same event that takes the primary down. Keep at least one copy in a separate account, region or site with independent credentials, and check that the Geo secondary, if you run one, does not share those dependencies. Confirm the separation against your own failure scenarios, not only the diagram.
Retention and deletion controls
Recovery copies must survive long enough to cover the time it takes to notice a compromise or corruption, but they also expand the data you hold and must be deleted on schedule. Set retention rules that match your recovery and legal requirements, and protect copies from accidental or malicious deletion with versioning or object locks where your platform supports them. Confirm the rules with legal, compliance and storage owners.
Questions buyers ask about GitLab disaster recovery
What drives the cost of GitLab disaster recovery?
The cost is driven by four components: the infrastructure for a second site, the storage for backup archives and retention, the GitLab subscription tier, and the people who design, build and test the recovery path. A warm standby needs a full second set of application, database and Git storage in another region, so it roughly multiplies the infrastructure line. Backup storage recurs with retention length and instance size. Geo is available only in the Premium and Ultimate tiers for self-managed GitLab, and the GitLab pricing page lists Premium at 29 US dollars per user per month billed annually, with Ultimate custom priced. Ask any partner to split the quote into one-time design and build work and recurring testing and storage.
Does Geo replace the need for backups?
No. Geo provides a warm-standby secondary site that is continuously synchronized, which protects against loss of a site, but it replicates changes, including mistakes and corrupted data, to the secondary as well. A separate backup archive, stored away from both sites and tested by restore, is what lets you return to an earlier point in time. Plan both: Geo for fast failover, backups for point-in-time recovery and for protection against replicated damage.
How long does it take to design and test a recovery approach?
Duration depends on instance size, the number of components in scope, how many environments must be rebuilt, and how much of the restore test is automated. Larger instances with separate Gitaly, PostgreSQL and object storage layers take more design time because each one needs its own snapshot or backup method. Ask for a written timeline tied to a defined scope, and ask whether it includes a full restore into a clean environment, not only a backup job that finishes without errors. DeployOpen engagements are fixed-scope, so the agreed deliverables and timeline are set in writing before work starts.
What do we need to provide from our own team?
Your team needs to provide access to the target cloud accounts, data centers or air-gapped networks, a named owner for the GitLab instance, details of the current version and edition, the sizes of the database and Git data, and the recovery objectives that the business has agreed. You also need someone who can approve maintenance windows and change control for a restore test. Identify who holds the gitlab-secrets.json file and who manages DNS, certificates and object storage, because those owners must take part in the test.
Can our own team run the restore test without a partner?
Yes, if your team has the skills and time to run it. GitLab documents restore procedures, and the most important rule is that the restore must use the same GitLab version and edition as the backup, with the matching secrets file restored. The harder part is repeating the test on a schedule, recording results, and proving that a restore into a clean environment works end to end, including repositories, CI variables and users. If your team lacks that capacity, ask a partner to design the test runbook and run the first full restore, then decide whether to keep it in-house.
What can go wrong during a GitLab recovery?
The most common failures are an incomplete backup that omits the secrets file, a restore onto a different GitLab version or edition than the backup, and a secondary site that has fallen behind the primary without anyone noticing. Object storage data such as artifacts, LFS and registry blobs may fall outside the standard backup command when stored in S3, GCS or Azure, so it needs its own protection. Upgrade stops also matter: if the target version does not respect required upgrade stops, the restore path may be blocked. Test each of these explicitly rather than assuming the backup job covers them.
Which infrastructure details should we confirm before choosing an approach?
Confirm the total size of the PostgreSQL database and Git repository data, the number of users and CI load, whether object storage is used for artifacts and registry data, the hosting model (Linux package, Helm chart or Operator), and whether the instance runs in an offline environment. Also confirm your recovery time and recovery point objectives, the location and independence of a second site, and whether snapshots of your storage platform can be taken consistently. These answers decide whether snapshots, backup archives, Geo or a combination fits your instance.
Official GitLab sources for backup and Geo
Before you choose between backup archives, disk snapshots and Geo, read GitLab's own backup and restore documentation and the Geo documentation in full. The backup and restore guide is the reference for what the backup command includes, what it skips and how restores are sequenced. The Geo documentation describes the warm-standby secondary site, how replication is configured and what a failover involves. Use both as the source of truth for any procedure your runbook will contain, and treat this page as a decision aid rather than a substitute for them.
GitLab procedures change by version. Backup paths, restore steps, Geo promotion commands and the rules for matching package versions and editions are all tied to the release you run, so check every step against the documentation for that exact version before you rely on it. Confirm the version and edition of each node, the Geo release on each site, and whether the instance uses Linux package, Helm chart or another install method, because those details change which steps apply. Also confirm the upgrade path in the upgrade stops documentation, since a recovery target that sits on the wrong stop can complicate a restore.
Ask your vendor or implementation partner to walk through these sources against your own topology and to record which version each runbook step was validated on. Keep that record with your backup evidence, and repeat the check whenever you upgrade. Where the documentation leaves a choice to your environment, such as storage layout or network path, write down the decision and the person who owns it.
How DeployOpen scopes and delivers GitLab recovery work
DeployOpen plans, builds and documents self-managed GitLab recovery inside your own infrastructure, starting from your instance size, data-loss tolerance and recovery time expectations. We scope backups, snapshots and Geo together so the recovery design fits how your GitLab actually runs.
How we scope
- Written scope lists the instances, storage locations and backup targets covered, agreed before work starts.
- We record your instance size, database and Git data volumes, and where artifacts, LFS and uploads are stored.
- Scope names the secrets, configuration and TLS material that must be recovered alongside the data.
How we build
- We configure backup schedules, retention and storage for the GitLab backup archive and any disk snapshot routine.
- Where Geo is in scope, we build the secondary site and confirm replication health before relying on it.
- We run timed restore tests into an isolated environment and record the results against the agreed scope.
How we hand over
- Deliverables include runbooks for restore, failover and re-adding a former primary, written for your operators.
- We document the backup chain, version and edition matching rules, and the upgrade stops to plan around.
- Your team receives the restore test evidence and a list of open items to confirm with your environment owners.
How we support
- Ongoing support, upgrades and recurring restore testing are available as a retainer after handover.
- Retainers can cover GitLab version moves through required upgrade stops and re-verification of backups afterward.
- Support scope and response arrangements are set in writing, so you know what is covered before an incident.

