GitLab backup and restore: what your instance must protect
A GitLab backup is not one file. It is a set of separate pieces that must be captured together and restored into a matching GitLab version: application data (repositories, merge requests, issues, CI history and the database that indexes them), secrets, configuration files, and, in larger setups, object storage and a PostgreSQL backup taken alongside the application data. If any one piece is missing or comes from a different point in time, the restored instance can start and still be wrong. Encrypted values may not decrypt, CI jobs may fail on missing tokens, and attachments may point at files that no longer exist.
Running the gitlab-backup tool is the start of the work, not the end of it. The tool captures the application data it knows about, but the documentation is explicit that it does not cover everything. Secrets such as the encryption keys in the secrets file and the settings in gitlab.rb and related configuration files must be saved separately, and they must be stored with the same care as the data they protect, because a backup that exposes them is itself a security incident. Your own customizations, such as custom certificates, SSH host keys and reverse proxy settings, also sit outside the tool's scope. Read the current backup and restore documentation for your installed version and build a list of every path that must be captured.
Confirm the restore path before you rely on it. A backup that has never been restored into a separate environment is an assumption, not a recovery plan. Plan a restore test that runs on a schedule, records how long the restore took, checks that repositories clone, that CI pipelines run with their variables, and that users can sign in through your identity provider. Ask your team to name who performs the restore, which version of GitLab the restore target must run, and where the secrets copy is kept. Those answers decide whether the first real recovery will succeed on the first attempt.
Larger instances change the design. When object storage holds artifacts, LFS objects and uploads, and PostgreSQL runs on separate infrastructure, the backup must be coordinated across those systems so that the database, the file store and the Git data describe the same moment. Decide early whether the object store has its own versioning or replication, whether PostgreSQL backups are taken by your database platform, and how the two are timed. Ask your implementation partner to document the snapshot or backup order, the retention you need for your compliance obligations, and the steps to verify each component after it is written.
What a GitLab backup covers and what it misses
A GitLab backup is only as complete as its inventory. The gitlab-backup tool archives most application data, but the secrets file, gitlab.rb and TLS certificates sit outside it and must be saved separately. Confirm the exact scope for your version in the official backup and restore documentation before you rely on it.
Git repositories
Repositories hold the Git data GitLab stores on Gitaly, including branches, tags and full commit history. The gitlab-backup tool includes repositories in its archive, so this is the component teams most often expect to be covered. Check that every repository storage path is included for your version, and confirm whether wiki and design repositories fall within the same scope.
PostgreSQL database
PostgreSQL holds the metadata that makes repositories usable: users, projects, groups, issues, merge requests, pipeline records and permissions. Repositories restored without the database cannot be mapped back to people or projects. The gitlab-backup tool includes a database dump, but large instances often add database-level backups with point-in-time recovery, so confirm that both routes restore to the same state.
Artifacts, LFS objects and uploads
Job artifacts, Git LFS objects, uploads and packages hold large binary content. Many instances store this content in object storage, which changes what the gitlab-backup tool archives. Confirm for your version whether object-stored content is included in the archive or must be protected through the storage provider's versioning or replication, and verify the answer with a restore test.
Secrets file
The secrets file, gitlab-secrets.json in the configuration directory, holds the keys GitLab uses to encrypt database values such as CI variables and two-factor authentication data. Without it, restored encrypted values can become unreadable. The gitlab-backup tool does not include this file, so copy it to a protected location after every change, store it apart from the backup archive, and restrict who can read it.
Configuration file (gitlab.rb)
The main configuration file, gitlab.rb, sets the external URL, storage paths, email, authentication and backup options. The gitlab-backup tool does not archive it, so keep it under version control alongside any custom files you maintain for the instance. A rebuilt host with a different configuration can break storage paths or connections, so record every change you make.
TLS certificates and private keys
TLS certificates and their private keys let users and runners reach the instance over HTTPS. They are stored on the host, typically under the configuration directory, and the gitlab-backup tool does not include them. Save the full certificate chain and keys securely, record expiry dates, and confirm before cutover that a rebuilt host can present the same certificate or a reissued one.
Which backup approach fits your instance
This table compares four ways to protect a self-managed GitLab instance and shows when each one fits and what it costs to run. Read each row for the instance size or recovery need it targets, then check the operational cost before you commit. Geo adds a standby copy for disaster recovery, but it is not a substitute for point-in-time backups.
| Option | When it fits | Operational cost |
|---|---|---|
| gitlab-backup alone (Linux package, single node) | A single-node Linux package instance with a modest data set, where a scheduled gitlab-backup run to local or attached storage meets your recovery needs. Confirm the backup window and restore time with your own data volume. | Low. Cron or a scheduler, disk space for archives, and staff time to test restores. Secrets and gitlab.rb must be saved separately because gitlab-backup does not include them. |
| gitlab-backup plus external storage and database backups | Larger instances where repositories, artifacts, uploads and PostgreSQL data grow, and where object storage and database-level backups are already part of your platform standards. | Moderate. Object storage capacity and egress, PostgreSQL backup tooling and its retention, scripts that coordinate both, and staff time for restore drills across components. |
| Filesystem or volume snapshots coordinated with the application | Environments where the platform team already runs storage snapshots and can pause or quiesce GitLab writes, so that Git data, database and configuration are captured at a consistent point. Confirm snapshot consistency steps with the GitLab backup documentation before relying on them. | Moderate to high. Snapshot tooling and licensing, snapshot storage and retention, coordination scripts for application quiescing, and specialist time to validate restores on the same storage layer. |
| Geo as a continuously synchronized secondary site | Organizations that need a warm standby in another region to shorten recovery from site loss. Geo is available in Premium and Ultimate for self-managed GitLab and replicates continuously, so accidental deletions or corruption replicate too. | High. A second full environment, cross-region network transfer, Premium or Ultimate licensing, and ongoing staff time for failover testing. Geo complements backups and does not replace them. |
How to set up GitLab backups in order
This sequence takes a self-managed GitLab instance from unknown backup coverage to a tested, off-host backup routine with alerting. Each step produces a check you can verify before moving on. Confirm the exact order, downtime and consistency requirements against the documentation for your installed version before you run anything in production.
Inventory every data location and its owner
Before configuring anything, list where GitLab keeps data: Git repositories, the PostgreSQL database, uploads and artifacts, container and package registries, LFS objects, Redis, and the configuration and secrets files on the host. For each location, record who owns it, where it lives (local disk, NFS, object storage or a managed service) and whether gitlab-backup covers it. The gitlab-backup tool does not capture everything, so gaps found here drive the later steps. This step is done when the inventory lists every location, its owner and its backup method.
Back up configuration and the secrets file separately
Copy the configuration and secrets files, such as gitlab.rb and gitlab-secrets.json on Linux package installs, to a controlled location on their own schedule. Treat them as sensitive: they hold the keys needed to decrypt data inside a backup, so restricting access and logging reads matters. Confirm the file paths for your installation method in the documentation for your version. This step is done when a recent copy of both files is stored in the controlled location and you have confirmed that a restricted group can read it.
Configure the gitlab-backup run and its destination
Set the backup path and any backup options in the GitLab configuration, then run gitlab-backup create manually as the platform's backup user. Review which components the run includes and excludes, because some data types need separate handling. Check the destination has enough free space for the archive and that file permissions allow the backup process to write. This step is done when a manual run finishes without errors and produces a timestamped archive in the destination directory.
Add object storage and PostgreSQL protection where needed
If the topology stores artifacts, uploads, LFS objects or registry data in object storage, or runs PostgreSQL on separate nodes, decide how those components are protected. Object storage often needs its own versioning, replication or snapshot policy, and the database may need a native backup tool with point-in-time recovery. Confirm with the documentation which components gitlab-backup covers in your topology and which need external tooling. This step is done when every component in the inventory has a named protection method and an owner for it.
Set retention and copy backups off the host
Define how many backup archives to keep and for how long, and set the cleanup behavior so old archives are removed predictably. Copy each archive, along with the configuration and secrets copies, to a separate system or storage account so that losing the GitLab host does not remove the backups. Choose retention values that match your recovery requirements and any policy your organization has, and confirm how your storage tier bills for retained data. This step is done when a backup archive appears in the off-host location and the retention job has been tested against a sample of older files.
Schedule the first full backup
Create a scheduled job, such as a cron entry or a systemd timer, that runs gitlab-backup create at the interval your recovery requirements call for. Pair it with the scheduled copy of configuration and secrets, and with the off-host transfer. Keep the schedule outside of peak working hours where possible, and confirm the job runs under the correct user with the environment variables it needs. Check the documentation for your version on whether the backup needs downtime or a consistent quiet period. This step is done when the scheduled job has run once and the resulting archive is recorded in the off-host location.
Confirm each step with a closing check
Verify the setup with three checks: a listed backup archive with the expected timestamp and size, a stored and readable secrets file in the controlled location, and an alert that fires when a backup job fails or does not produce a new archive within the expected window. Route the alert to a monitored channel with a named owner. Record the results in your runbook. A backup that has never been restored is unverified, so schedule a restore test as the next task. This step is done when all three checks pass and the alert has been triggered once in a test.
What drives the effort of GitLab backup and restore work
This table lists the factors that change how much work a GitLab backup and restore program takes, with a way to keep each one under control. Read it as a checklist for scoping: each row names the driver, what it changes, and the choice that usually reduces the work. Most of the effort comes from scope and frequency, so agree those early in writing.
| Driver | Why it changes effort | How to keep it down |
|---|---|---|
| Users and repositories | More projects, merge requests and CI artifacts increase backup size, run time and the number of items a restore test must check. | Confirm the instance size and reference architecture first, then size backup windows and restore checks from that inventory rather than assumptions. |
| Total data volume | Repositories (Gitaly), database rows and uploaded files grow together, so backup and restore time grows with the largest component. | Set a clear data inventory and rely on incremental or scheduled patterns the backup tool supports; confirm supported options for your version in the official documentation. |
| Object storage size and provider | Artifacts, LFS objects and packages often live in object storage that is backed up separately, and each provider has its own snapshot, versioning and cost behavior. | Decide per data type whether object storage is protected by provider features, a second bucket or the backup tool, and document that choice in one place. |
| PostgreSQL topology | A single database is simple to dump; a Patroni cluster or external database needs coordinated backups, replica handling and clear ownership of the database snapshot. | Standardize on one database backup method across environments and script its verification rather than building a custom process per cluster. |
| High availability layout and node count | Each Gitaly, database, Redis or application node may hold state or config, so backups must cover every node that matters and the consistency between them. | Map which nodes hold unique data and back up only those, then test that the restored layout matches the documented topology. |
| Linux package or Kubernetes deployment | Linux package installs keep secrets and gitlab.rb on the host; Kubernetes stores state in external services and secrets in cluster objects, which changes what is saved separately. | Pick one deployment method per environment, write a list of configuration and secrets locations for it, and version that list with the runbook. |
| Air-gapped transfer limits | Isolated networks mean backups must be moved on approved media or transfer paths, which adds handling steps and limits how large or frequent copies can be. | Agree transfer size and frequency with the security team early, keep backups as compact as the business allows, and rehearse the transfer as part of restore tests. |
| Retention and off-site copy requirements | Longer retention and separate off-site copies multiply storage, access control and deletion work, and each copy must be checked. | Set retention by business need and legal requirement, and limit off-site copies to the data classes that need them. |
| Compliance evidence needs | Assessors may ask for backup schedules, job logs, encryption settings, access records and restore results, which means someone must collect and keep them. | Generate evidence from the backup and restore scripts (logs, checksums, dated test reports) so it is produced during routine operation, not rebuilt for each audit. |
| Restore test frequency and scope | Each test consumes staff time and environment capacity, and larger scope (full instance versus selected projects) takes longer to run and review. | Script restore tests in a non-production environment, agree a fixed frequency and a limited scope that meets recovery goals, and record results each run. |
How backup and restore differ by deployment model
A single-node Linux package instance keeps repositories, PostgreSQL data, uploads and most runtime state on one server, so the gitlab-backup tool can usually capture the application data in one run. The Linux package bundles PostgreSQL, Redis and Sidekiq, which means one host holds nearly every stateful part of the instance. The backup still leaves out secrets and configuration files, so those must be saved separately.
Points to check:
- Secrets and config: Copy /etc/gitlab/gitlab-secrets.json and /etc/gitlab/gitlab.rb to protected storage on a schedule, because the database backup cannot decrypt data without them.
- Version match: Confirm the restore target runs the same GitLab version as the backup, and plan the restore on a host with the same package version.
- Storage location: Decide whether backups go to local disk, object storage or both, and make sure the backup is not stored only on the instance it protects.
- Downtime: Confirm with your team how long GitLab must be stopped for a full backup and whether that window matches your working hours.
- Restore test: Restore to a separate host at least periodically to prove the archive, secrets and configuration work together.
High availability reference architectures, which GitLab generally recommends for 3,000 or more users, spread state across several components: Gitaly Cluster with Praefect for repositories, PostgreSQL with Patroni, Redis Sentinel and Consul. Each stateful component holds part of the instance, so a backup must capture every component at a consistent point. Taking a database backup at one moment and repository data at another can produce an archive that restores but does not match.
Points to check:
- Repository storage: Confirm how Gitaly Cluster repositories are captured and whether your backup procedure covers every storage node that holds data.
- Database consistency: Confirm how PostgreSQL under Patroni is backed up, including which node is the source and how failover during the backup is handled.
- Redis and Consul: Confirm which of these hold data you need to restore and which can be rebuilt from configuration.
- Coordination window: Agree a backup sequence in writing so that all components are captured against the same instance state.
- Version rules: Confirm that every node in the restored cluster runs the GitLab version that produced the backup.
Confirm each of these with your architecture document and the current GitLab reference architecture guidance before you rely on the procedure.
In the Cloud Native Hybrid architecture, stateless GitLab components run on Kubernetes while stateful services such as PostgreSQL and Redis run on virtual machines or managed services. Because the stateful services are outside the cluster, the cluster itself is not a complete backup source. Persistent volumes, cluster manifests and Helm values alone do not cover the data, and the databases and object stores must be backed up through their own mechanisms.
Points to check:
- Scope outside the cluster: Back up the external PostgreSQL, Redis and Gitaly data using the tools or managed snapshots for those services, not only the Kubernetes objects.
- Object storage: Confirm how artifacts, LFS objects, packages and registry data are stored and whether they are in object storage that has its own retention and versioning.
- Kubernetes state: Keep Helm values, secrets and chart versions under version control so the release can be rebuilt.
- Managed services: Confirm the backup features, retention and restore steps of any managed database with your provider.
- Version rules: Confirm the chart, image and application versions match the backup, and that the restore order is documented.
Ask your implementation partner to confirm the exact backup source list for your layout before you schedule the first backup.
An air-gapped GitLab instance runs on an isolated network with no route to the internet, so backups and restore sources must cross the isolation boundary by approved media or a controlled transfer path. The backup itself is only useful if it can be moved out, verified and brought back in without weakening the boundary. GitLab documents running self-managed instances in offline environments, but the transfer process is set by your own security policy.
Points to check:
- Transfer path: Define the approved media, the chain of custody and who may carry backups across the boundary.
- Integrity checks: Record checksums for backup archives and secrets files before transfer and verify them on arrival.
- Restore sources: Keep the matching GitLab package or image for the backup version inside the isolated network, since the target cannot download it.
- Secrets handling: Treat secrets and configuration files as sensitive, encrypt them in transit and store them under the same controls as the database.
- Restore test: Rehearse a restore inside the isolated network so that the transfer process is tested as well as the archive.
Confirm the required approvals and media rules with your security team, because they determine how often backups can be moved.
Restore tests that prove a GitLab backup works
A GitLab backup has no value until a restore from it has been run, checked and recorded. The restore test should prove that a recovered instance can serve the work the business depends on: repositories with complete history, open merge requests with their discussions, CI artifacts that jobs can still download, registry contents that pipelines can still pull, and users who can sign in with their group memberships intact. Plan the test as a rehearsal of your real recovery, not as a backup file check, because the gaps usually appear in the restored state rather than in the archive itself.
Run the restore into a separate, isolated instance built at the same GitLab version as the source. Matching versions matter because the backup tool restores database and repository data in a form tied to the release that created it, and the upgrade path rules still apply to the test host. Restore the configuration and secrets files you back up separately, such as the gitlab-secrets file and the gitlab.rb configuration, because without the matching secrets, encrypted values such as CI variables and two-factor data will not decrypt. Then check each area in turn: sample repositories and compare commit counts and tags against production, open a few merge requests and confirm their diffs and comments load, download a CI artifact from a recent successful job, pull a container image and a package from the registry, and review a sample of users and group roles against a current export.
Confirm that logins work with the restored secrets rather than assuming they will. Sign in as a test user through the password path and, where you use them, through your LDAP, SAML or OAuth 2.0 provider, and confirm that personal access tokens and runner registration behave as expected. A restored instance that accepts a password but cannot decrypt stored tokens or variables is a failed restore, even though the backup job reported success.
The test environment must fail safely, and you should prove that before any restore is started. Disconnect it from production CI runners by confirming it cannot reach the runner registration endpoints or any runner that serves production projects, and do not register production runners to it. Disable or redirect outbound webhooks, system hooks and integrations, and route or block outbound mail so that restored notifications cannot reach real users or trigger production deployments. Confirm that the isolated network cannot reach production databases, object storage buckets or identity providers in write mode. Then test the failure path: if the restore stops partway, production must be unchanged, which you verify by checking that production services, backup jobs and retention still run as before and that the failed test host can be destroyed without side effects.
Run restore tests on a fixed schedule that you set against your recovery objectives, and repeat them after any GitLab upgrade, change to storage or secrets handling, or change to the backup job. Keep a written record of each test: the backup file and its timestamp, the source and target versions, the checks run and their results, the time the restore took, the people involved, and any defects with their owners and closure dates. Your own restore runbook is the acceptance artifact. A test passes when the runbook, followed by someone other than its author, produces a working instance and the record shows it. Ask any implementation partner to deliver the runbook and test record in your environment, and confirm with your auditors which evidence they will accept.
How to protect backups and secrets
A GitLab backup is only as safe as the storage, keys and administrators around it. The cards below cover the controls that decide whether a backup can be read, altered or deleted by someone who should not have that power. Work through them together, because a well-locked backup bucket does not help if the secrets file sits unprotected beside it.
Control access to backups and secrets
Treat the backup archive and the secrets file as equally sensitive. The secrets file holds the keys a restored instance needs to decrypt stored secrets such as CI/CD variables and tokens, so a copy of the database without it is incomplete, and a copy of it alone is a credential store. Restrict read access to named service accounts and a short list of people, and check who can list, download or copy these files from the host and from object storage.
Encrypt backups in transit and at rest
Encrypt backup archives where they are stored and on every path they travel, including copies sent to off-site or secondary storage. Confirm which encryption the backup target applies by default, who manages the keys, and whether keys are stored apart from the data they protect. Also confirm that transfers to remote storage use TLS and that the rotation process for encryption keys is documented and tested.
Separate backup and application administrators
Assign backup administration to people or service identities who do not hold routine GitLab administrator rights, and the reverse. A GitLab administrator who can also delete backup copies can hide an incident, and a backup operator who can change application settings can alter what gets restored. Record which accounts can run gitlab-backup, read the secrets file, change retention and delete archives, and review that list on a schedule.
Use immutable or versioned storage
Store backup copies in a way that prevents ransomware or a compromised administrator from overwriting or deleting them. Object storage with object lock or versioning, or write-once media, keeps earlier copies recoverable even when an attacker has write access. Confirm with your storage vendor how retention locks work, whether they can be shortened by an administrator, and how restores are performed from a locked copy.
Harden hosts and configuration
Apply the GitLab hardening guidance for gitlab.rb and operating system settings to the hosts that run backups and hold the secrets file. The guidance covers application settings, configuration files and the operating system, and it is a work in progress that GitLab says should be rolled out gradually. Plan changes in stages, test each one in a non-production instance, and record which settings were applied and when.
Remove backups when retention ends
Define how long each backup type is kept, then delete expired archives from the primary host, the object store and every off-site copy. Leftover archives outlive the retention decision and keep sensitive data and old secrets available. Verify deletion by listing storage after a retention run, check that lifecycle rules are applied to all copies, and confirm that deleted secrets files are also removed from places where old versions were kept.
What to monitor, document and rehearse after go-live
The first thing to put in place after go-live is alerting on the backup pipeline itself. A backup job that fails quietly, or that stops running after a cron entry is changed or a host is rebuilt, leaves you with no recent recovery point and no warning. Alert on failed gitlab-backup runs, on backup archives that do not appear in the expected location at the expected time, and on any step that writes the backup but never completes. If you run object storage or a separate PostgreSQL backup process for a large instance, those jobs need their own alerts, because a successful archive on one side does not prove the other side is current. Ask your team to confirm which job writes which artifact, and to confirm that a missing artifact produces a page rather than a log line. Storage needs two regular checks: remaining capacity on the backup target and whether retention is removing what it should. Retention that deletes too aggressively can remove the only copy of a restore point you need for an audit or an incident review, while retention that never runs fills the volume until new backups fail. Track free space against the growth you observe between backups, and review the retention setting whenever repository size or CI artifact volume changes materially. Also record which backup target holds the secrets and configuration files that the backup tool does not include, since those must be retrievable independently of the archive. Documentation is what makes a restore possible for someone other than the person who built the system. Keep a change record that notes the GitLab version, the edition, and every configuration change that affects a restore, such as the external URL, storage paths, object storage endpoints, database host or topology, and the contents of the configuration and secrets files. Each upgrade and each storage or database topology change should add an entry. Without that record, a restore test may succeed against a configuration that differs from production, and the mismatch will only surface during an actual incident. Rehearse restores on a schedule tied to the platform's own release cadence. GitLab requires upgrades to pass through required upgrade stops at versions x.2, x.5, x.8 and x.11, so the upgrade paths documentation is the reference for when to schedule a restore test: after each required stop, and after any change to storage or database topology. A rehearsal should restore into a separate environment, confirm that repositories, CI configuration, users and attachments are present, and log the time taken and the problems found. Treat the first rehearsal after each stop as the check that the backup still matches the software you are running. Keep the runbook current with the same discipline. Operating tasks such as alert review, capacity checks, change logging and restore rehearsal are often the first to lapse once the project is handed over, because none of them blocks daily work until something fails. A named owner, a calendar of rehearsals and a review date on the runbook help, and an ongoing support retainer is one way to keep these tasks scheduled and reviewed by someone who knows the environment. Confirm with any provider exactly which of these tasks the retainer covers and how restore tests are reported back to you.
Questions teams ask about GitLab backup and restore
What does GitLab backup and restore cost?
The cost depends on scope, which is agreed in writing before work starts, so no price is published and a quote follows from that scope. The main components are planning the backup design, configuring the gitlab-backup tool and the separately saved secrets and configuration files, setting up storage targets, scheduling and monitoring, writing a runbook, and running restore tests in a restore environment. Cost rises with the number of nodes, the size of repositories and object storage, the number of PostgreSQL instances, the number of restore tests, and whether the work includes disaster recovery design. Ask any provider to split the quote into one-time build work and any recurring retainer for monitoring, test cycles or upgrades, and to state which environment the restore tests run in and who pays for its infrastructure.
How long does a GitLab backup and restore project take?
Duration is set by the instance, not by the backup tool itself. The main drivers are the topology (a single Linux package server is simpler than a multi-node setup with separate PostgreSQL, Gitaly and object storage), the volume of data that must be backed up and restored, how many storage targets and retention rules are needed, how quickly access and a restore environment are provided, and how many full restore rehearsals the scope includes. A project with clear access on day one and a restore environment ready moves faster than one waiting on infrastructure decisions. The timeline should appear in the written scope with each milestone and the client dependencies behind it.
Can our own team run GitLab backups without outside help?
Yes. A capable platform team can run GitLab backups in-house if it has a written runbook, dedicated backup storage with appropriate retention, monitoring that alerts on failed or missing backups, and a restore path that has been tested end to end. The hard part is rarely the first backup. It is keeping the secrets and configuration files saved, confirming that object storage and PostgreSQL backups line up for large instances, and proving that a restore works on a version that matches the source. Teams that choose to do this themselves should still rehearse a restore on a separate environment before they rely on it.
What do we need to provide for a GitLab backup and restore engagement?
Expect to provide the following before work starts:
- Administrative access to the GitLab servers, database hosts and object storage used by the instance
- Storage targets for backups, with capacity and retention requirements and encryption policy
- The exact GitLab version, installation method and topology, including whether PostgreSQL, Redis and Gitaly are separate
- A restore environment that matches the production version and is isolated from it
- A named owner on your side who can approve changes and make decisions during testing
Without a restore environment and a named owner, the restore tests that prove the design cannot be completed.
Does GitLab Geo replace regular backups?
No. GitLab Geo provides a warm-standby secondary site in another region that is continuously synchronized for disaster recovery, and it is available in the Premium and Ultimate tiers for self-managed GitLab. Replication protects against site loss, but it does not give you point-in-time recovery from a bad change, an accidental deletion or data corruption, because those problems replicate too. Regular backups stored separately, with tested restores, remain necessary alongside any Geo deployment. Confirm the replication scope and failover steps with the GitLab documentation for your version before deciding how the two protections fit together.
How often should we test a GitLab restore?
Test restores on a schedule that your recovery objectives justify, and rehearse them after any significant change such as a version upgrade, a storage migration or a topology change. Many teams start with a full restore rehearsal at setup, then repeat it on a regular cadence and record the time taken and any manual steps. Each test should restore into an isolated environment, verify repositories, merge requests, CI configuration and user access, and confirm that the saved secrets and configuration files work with the restored data. Ask your provider how each test is documented and who signs off the result.
Which parts of GitLab must be backed up separately from the gitlab-backup output?
The gitlab-backup tool captures much of the instance data, but the official documentation describes files that must be saved separately, including the secrets file and configuration files such as gitlab.rb and gitlab-secrets.json. Without the secrets, encrypted values in the database may not be readable after a restore. Large instances also need coordination between PostgreSQL backups, object storage and Git repository data so that the pieces match. Confirm the current list of separately saved items for your installed version in the official backup and restore documentation before writing your runbook.
How DeployOpen works on this
DeployOpen plans and implements GitLab backup and restore inside your own infrastructure, covering the gitlab-backup tool, the secrets and configuration files that must be saved separately, and restore procedures your team can run. Engagements are fixed-scope, with the scope, deliverables and timeline agreed in writing before work starts.
How we scope
- We inventory your GitLab installation method, data locations and any external object storage or PostgreSQL services that hold instance data.
- The written scope names which backup targets are covered, including repositories, database, uploads, registry, secrets and configuration files.
- We confirm recovery expectations with your team, such as how far back restores must reach and who approves a restore during an incident.
How we build
- We configure scheduled backup jobs and storage locations, then verify that each backup run completes and produces the expected archives.
- We document which secrets and configuration files, such as gitlab-secrets.json and gitlab.rb, are saved separately and how they are protected.
- We run restore tests on an isolated instance and record the steps, timings and any gaps found against the written scope.
How we hand over
- Your team receives a runbook covering backup schedules, retention settings, monitoring checks and the step-by-step restore procedure.
- We walk your operators through a live restore test so they can repeat the process without DeployOpen present.
- Handover documentation records the agreed scope, test results and open items so later reviewers can trace what was delivered.
How we support
- Ongoing support, periodic restore testing and updates to backup procedures after GitLab upgrades are available as a retainer.
- We review backup jobs and restore procedures when you change storage, move to a new GitLab version or adjust your recovery targets.
- Confirm with us in writing which support hours, response terms and test frequency a retainer includes before you sign.

