How GitLab high availability removes single points of failure at scale
GitLab high availability means every stateful component that holds your source code, merge request data and CI/CD state has redundant copies, so a single server failure does not stop engineers from pushing code or merging changes. It is the pattern GitLab's documentation recommends once an organization reaches roughly 3,000 users. If your engineering organization depends on self-managed GitLab for source control, merge requests and pipelines and cannot accept a single-server outage, this is the layout to plan for before user growth forces an emergency redesign. GitLab's reference architectures run from 1,000 users at 20 API requests per second up to 50,000 users at 1,000 API requests per second. The docs generally recommend a high availability strategy for 3,000 or more users, built from four components: Gitaly Cluster with Praefect for Git repository storage, PostgreSQL with Patroni for the database, Redis Sentinel for cache and queue state, and Consul for service discovery. Confirm the exact node counts and sizing for your user count and request rate against the reference architecture page for your target release, because those specifications change between versions.
The difficulty is not in installing each component. It is that several stateful services must fail over independently and still agree on the state of the system. A Praefect failover that succeeds while the database is mid-failover can leave repository metadata out of step with the data on disk. Routing and health checks sit in front of all of this: your load balancer must send traffic only to nodes that are actually ready, and the health check definitions must match what GitLab considers healthy. Decide early who owns the load balancer configuration and how failed nodes are detected and drained. Upgrades add another layer. Each node in a multi-node layout must be upgraded in a defined order, and the required upgrade stops (such as x.2, x.5, x.8 and x.11 for current releases) apply to every node. Plan a staging environment that mirrors the production topology, and rehearse the rolling upgrade sequence before doing it on production. Confirm the zero-downtime upgrade procedure for your exact topology with GitLab before you schedule the first change window.
High availability is not disaster recovery. HA keeps the instance running through failures inside one site. GitLab Geo, available in the Premium and Ultimate tiers for self-managed GitLab, provides a warm-standby secondary site in another region that is continuously synchronized, and it is the tool for recovering from loss of the whole site. Ask your team to state separately which failures the HA design must survive and which ones the Geo site must cover, and to write down the recovery objectives for each. Teams that treat one as a substitute for the other usually discover the gap during an incident. Finally, HA does not replace backups. Replication copies a corruption or an accidental deletion to every node within seconds. Keep independent backups with the gitlab-backup tool, save the secrets and configuration files separately, and test restores on a regular schedule. Ask your implementation partner to show the restore procedure running against your HA topology, not only against a single test server.
Which GitLab components need redundancy and why
A highly available GitLab instance removes single points of failure from each layer that holds state or routes traffic. The cards below cover the components the reference architectures typically make redundant for 3,000 or more users, what each one protects against, and what each one depends on, so you can check the design against your own user count and network.
Gitaly Cluster with Praefect
Gitaly stores the Git repositories themselves. In Gitaly Cluster, Praefect sits in front of several Gitaly nodes and routes requests so that repository copies are kept on more than one node, which protects against loss or outage of a single storage server. It depends on a Praefect database and on enough Gitaly nodes to hold the replicas your design requires. Confirm the replication factor and node count against the reference architecture for your user count, and test what happens to pushes and clones while one node is down.
PostgreSQL with Patroni
PostgreSQL holds users, projects, merge requests, issues and CI metadata, so every web and API request depends on it. Patroni manages a primary and standby nodes and promotes a standby when the primary fails, which protects against database server loss. It depends on a distributed coordination store, which in GitLab's design is Consul, and on a connection layer that follows the current primary. Verify failover time and how the application reconnects after promotion.
Redis Sentinel for cache and queue state
Redis holds cached data and the state for background job queues, and losing it can disrupt request handling and Sidekiq processing. Redis Sentinel monitors Redis nodes and promotes a replica when the primary becomes unavailable, which protects the application from a single Redis failure. It depends on at least three Sentinel processes spread across hosts so that a quorum can agree on failover. Confirm the Sentinel layout and how GitLab is configured to connect through Sentinel rather than to a fixed Redis address.
Consul for service discovery and failover coordination
Consul tracks which nodes are healthy and which PostgreSQL node is primary, so other components can find working services without fixed addresses. It protects against a failed node being left in rotation and supports Patroni's leader decisions. It depends on a quorum of Consul server agents, which need to survive the loss of a single host and should not share a failure domain with the nodes they monitor. Check the number of Consul servers and their placement against the reference architecture.
Load balancer in front of application nodes
The load balancer distributes web, API and Git HTTP or SSH traffic across the application nodes and stops sending requests to nodes that fail health checks. Without a redundant pair or managed service, it becomes the single entry point for every user. It depends on health check endpoints provided by GitLab, correct TLS termination, and session or connection handling that your identity and Git clients expect. Confirm which ports and health paths your chosen design requires and test a node removal during a live Git push.
Application nodes and their stateless design
The application nodes run the Rails web, API, Sidekiq and related services. Because they hold no repository or database state of their own, they are simpler to add, replace and scale than the stateful layers, and losing one usually leaves users with a retry rather than data loss. They still depend on shared configuration, secrets and the stateful services above, so every node must carry identical gitlab.rb and secret files. Exact node counts for each component must be confirmed against the current GitLab reference architecture page for your target user count, because those counts change between releases.
Which high availability decisions shape cost and operations
This table compares the main high availability decisions for self-managed GitLab, from architecture size and install method to database ownership, disaster recovery and licence tier. Read each row for when the option fits and what your team takes on to run it. The main takeaway is that these choices are linked: the database and the tier you choose often shape operations as much as node count does.
| Option | When it fits | What it costs you operationally |
|---|---|---|
| Reference architecture size | Chosen from user count and API request load, from 1,000 users at 20 requests per second up to 50,000 users at 1,000 requests per second. | Each step up adds nodes, storage and components to patch, back up and monitor. Confirm the current sizing guidance with GitLab before fixing hardware. |
| Linux package multi-node on VMs | Teams that already run virtual machines and want the most mature, scalable installation method, with bundled PostgreSQL, Redis and Sidekiq. | Your team runs every node, including OS patching, the upgrade sequence across nodes and per-node backup coverage. |
| Cloud Native Hybrid | Organizations with a Kubernetes platform that want stateless GitLab services scheduled there. | Stateful PostgreSQL and Redis stay on VMs or managed services, so you operate two platforms and the connections between them. |
| Self-operated Patroni and Consul, or external managed PostgreSQL or Redis | Teams with database operators who want full control, or who already run managed PostgreSQL or Redis they trust for other workloads. | Self-operated clusters need failover testing, version tracking and skilled on-call cover. Confirm supported external configurations with GitLab before you commit. |
| Geo as a warm-standby site | Disaster recovery across regions, using a secondary site continuously synchronized from the primary. Available in Premium and Ultimate. | You run, sync and test a second full site. Geo supplements in-site high availability and does not replace it. |
| Premium or Ultimate tier | Premium adds advanced CI/CD and priority support. Ultimate adds security testing, software supply chain, vulnerability management and compliance features. | The tier sets licence spend and which features your teams can rely on. Confirm feature availability for your deployment before the design is frozen. |
How to build GitLab high availability in an order you can test
Each stage builds one layer, and each ends with a check that proves it works before the next layer depends on it. The sequence finishes with failover drills, so the team knows how the instance behaves before users are moved onto it.
Confirm user count and API load
Start by confirming the number of users and the sustained API request rate the instance must serve, then select the matching reference architecture from GitLab's reference architectures documentation. The range runs from 1,000 users at 20 API requests per second to 50,000 users at 1,000 API requests per second, and the docs generally recommend a high availability strategy at 3,000 or more users. Platform engineering and the business owner should agree these figures together, and the choice should rest on measured peaks as well as headcount. The check is a signed-off architecture record that names the reference architecture, the expected peak load and the growth planned over the life of the layout.
Plan network, DNS, certificates and load balancing
The network team and platform engineers map the subnets, DNS names and certificates each component needs, and draft the load balancer plan for the application nodes. Confirm which components talk to which, which ports stay closed between tiers, and how certificates renew without a manual step. Decide where the load balancer sits and who owns its configuration. The check is a reviewed network diagram and a DNS and certificate inventory that a second engineer can use to build every node without asking questions.
Build Consul and the Patroni PostgreSQL cluster
Build the Consul cluster that Patroni and related services use for coordination, then build the PostgreSQL cluster managed by Patroni. The Linux package bundles PostgreSQL, Redis and Sidekiq, so on multi-node layouts the bundled services must be disabled or externalized as the reference architecture for your size requires. Start the nodes and let Patroni elect a leader, then confirm that exactly one node reports as leader and the replicas stream from it. The check is a deliberate restart of the current leader that produces a new leader and a test table with no lost writes.
Build the Redis Sentinel set
Build the Redis Sentinel set that tracks a primary and its replicas, and confirm primary selection before anything depends on it. Apply the same rule as the database tier: the Redis service bundled in the Linux package is turned off on these nodes, and the layout follows the reference architecture. Start the Sentinel quorum, then check that every Sentinel reports the same current primary and that each replica points at that primary. The check is a stopped primary that Sentinel replaces, followed by a query from each Sentinel that returns the same new primary.
Build Gitaly Cluster with Praefect
Build Gitaly Cluster with Praefect in front of the Gitaly storage nodes, and configure the application so that it addresses Praefect and never an individual storage node. Confirm the Praefect database and storage requirements in the reference architecture documentation for your version before you build. Create a test repository, push commits to it, and confirm that the writes are replicated to the other storage nodes. Then stop one storage node and confirm that reads and writes continue through Praefect. The check is a repository whose commits appear on every storage node after the test and a clone that succeeds while one node is down.
Install application nodes with shared configuration
Install the GitLab application nodes using the same Linux package version on each, and distribute one gitlab.rb and one set of secrets to all of them. The secrets file must be identical on every node and stored and backed up separately from the configuration. Point each node at the externalized PostgreSQL, Redis, Gitaly and object storage endpoints from the earlier steps. Plan the Runner version to match GitLab's version as well. The check is a diff of the rendered configuration across all nodes that shows no differences, plus a successful connection test from every node to each backing service.
Put the load balancer in front of application nodes
Place the load balancer in front of the application nodes and configure health checks against the endpoint that the reference architecture documentation specifies for your GitLab version. Confirm the exact health check path before you set it, and remove any node that fails the check from rotation. Then test by stopping the application service on one node and confirming that requests route only to the remaining healthy nodes. The check is a traffic log or request trace that shows no requests reaching the node that failed its health check.
Run failover drills for each stateful layer
Run a controlled failover drill for each stateful layer in turn: the Consul and PostgreSQL leader, the Redis primary, and the Praefect storage nodes. Record the recovery time, what users saw during the event, and whether any write was lost. Repeat each drill until the result matches the design, then move users onto the instance. Keep the drill runbook so the team can repeat the tests after upgrades. The check is a written drill report signed by the platform owner, with each failed drill rerun after its fix.
Single node, reference high availability and Cloud Native Hybrid compared
A single node runs GitLab on one server, with the application, database, cache and Git storage on the same host. It suits smaller user populations where the cost of a second site or cluster is hard to justify, and where a planned outage for maintenance or restore is acceptable to the business. The trade-off is that there is no in-site redundancy: a host failure, disk failure or failed upgrade takes GitLab down until the node is recovered from backup.
What changes in operations:
- Upgrades and patches are applied to one host, and a failed upgrade is recovered by restoring the host or backup, so a tested restore procedure matters more than in any other model.
- Backups run against the single host and must be scheduled, monitored and restore-tested on a regular basis.
- Capacity planning is simpler, but growth eventually forces a move to a multi-node layout, which is a migration rather than a configuration change.
- Your team patches the operating system, the GitLab package and any runners, with no separate patch path for each component.
Before choosing this model, confirm with GitLab and your own user data the expected user count and API load against the reference architectures, the acceptable recovery time after a host failure, and the upgrade stops you will need to pass through over the planned life of the instance.
The reference high availability architecture on virtual machines spreads GitLab across several nodes so that the failure of one node does not stop the service. GitLab's documentation generally recommends this strategy for 3,000 users or more, using Gitaly Cluster with Praefect for Git storage, PostgreSQL with Patroni, Redis Sentinel and Consul for coordination. The layout is documented in detail, so the work is mainly to size, build and verify it against the reference.
What changes in operations:
- Each service role (application, Gitaly, database, Redis, load balancer) runs on its own machines, which adds components to monitor, patch and back up.
- Upgrades use the documented zero-downtime path for multi-node setups, and the team must still plan for required upgrade stops.
- Your team owns the load balancer, network paths, storage and the failover behavior of each cluster, not only the GitLab package.
- Failover is tested as a routine exercise, because a cluster that has never failed over in a test is not known to work.
Before choosing this model, confirm the user count and peak API request rate against the reference architecture size, the number of virtual machines and storage volumes your platform team can run, who will be on call for each cluster, and how GitLab's failover behavior will be tested after build. Ask for the reference architecture version your build targets.
Cloud Native Hybrid runs the stateless GitLab components on Kubernetes, while stateful services such as PostgreSQL and Redis run on virtual machines or managed services outside the cluster. GitLab's reference architecture documentation states that running PostgreSQL and Redis inside Kubernetes is not supported, so that rule sets the boundary of the design. This model suits organizations with an established Kubernetes platform and a team that already runs it well, but it adds a cluster to operate alongside the external data services.
What changes in operations:
- Stateless components are upgraded through Helm chart or Operator releases, which follow a different cadence and tooling from the Linux package.
- Stateful services are patched and backed up outside Kubernetes, so the team needs both Kubernetes and VM or managed database skills.
- Storage for Git repositories and object storage must be designed for the chosen Kubernetes and data layout, with clear ownership of each volume.
- Managed PostgreSQL or Redis services change who patches the database engine, so the responsibility split must be written down.
Before choosing this model, confirm with GitLab that the chosen chart or Operator version supports your intended external services, confirm which team owns each stateful service and its backups, and confirm whether your Kubernetes platform meets the resource needs for the target user count.
An air-gapped deployment uses the same topology as one of the models above, but on a network with no route to the internet. Packages, container images and other dependencies are transferred into the isolated environment on approved media, and updates arrive through the same offline process. GitLab documents running self-managed instances offline, with separate guidance for security scanners and GitLab Duo Self-Hosted, so the offline procedures must be confirmed for each feature you intend to run.
What changes in operations:
- Every update, including security patches, depends on a transfer process, so the lead time from release to production is longer and must be planned around the transfer schedule.
- Images and packages must be mirrored, verified and recorded in your change process before each upgrade.
- Features that normally fetch data online, such as some scanners and vulnerability databases, need their own offline update path.
- Your team carries the full patch burden for the operating system and every dependency inside the boundary.
Before choosing this model, confirm with GitLab which offline procedures apply to the features you plan to use, how license activation works without internet access, how often offline content is refreshed for scanners, and which topology you will combine with the offline environment.
What drives high availability effort and how to keep each driver down
This table lists the factors that change how much work a GitLab high availability build takes, how each one moves the design, and a concrete way to hold it down. Read each row as a lever you can set during scoping, before hardware or licenses are committed. The main takeaway is that environment count, identity scope and upgrade cadence usually add more recurring work than raw user count, so fix those in writing early.
| Driver | Effect on effort | How to keep it down |
|---|---|---|
| User count and API request load | Moves the GitLab reference architecture and node count. The docs generally recommend a high availability strategy from 3,000 users, so crossing that line changes the whole topology. | Confirm peak API request rate and active user count with the client before choosing a reference architecture. Size once against the documented tier instead of redesigning after rollout. |
| Repository size and storage layout | Affects Gitaly Cluster sizing, replication load and how long data movement takes during builds, restores and node replacement. | Measure total repository size and growth rate, separate large binary assets where possible, and agree a storage layout and migration window in the written scope. |
| Number of environments such as staging and production | Doubles the topology to build, configure and test, and every change must be proven in each environment. | Keep staging topology identical to production in node types, versions and load balancer rules. Build both from the same scripts so drift is reduced. |
| Identity integration with LDAP, SAML or SCIM | Adds configuration, group mapping and failure-path testing. Each provider and provisioning flow needs its own test cases. | Fix the identity scope in writing (which providers, which groups, whether SCIM is required). Test login, group sync and deprovisioning against a non-production tenant first. |
| Runner fleet and CI load | Shares some infrastructure with the instance, but runner capacity is usually planned as a separate workstream and can be scoped separately. | Keep runner design out of the core high availability fixed scope unless it is explicitly added. Agree runner versions aligned with GitLab and a separate capacity plan. |
| Compliance evidence requirements | Adds documentation, configuration baselines and control mapping work. DeployOpen prepares evidence, but independent auditors issue any assessment outcome. | Ask the compliance lead which control framework applies before build starts. Define the evidence list (configuration exports, backup test records, access reviews) up front and assign an owner for each item. |
| In-house experience with Patroni, Consul and Praefect | Drives training time, on-call readiness and how much vendor support the team will need after handover. | Assess the team's skills honestly. Plan knowledge transfer sessions and runbooks for failover, Praefect repair and Patroni switchover, and confirm what ongoing support covers. |
| Upgrade cadence and required upgrade stops | Adds rehearsal work each cycle, since the team must pass through required stops such as x.2, x.5, x.8 and x.11 and test background migrations. | Agree an upgrade cadence and a staging rehearsal step in the scope. Ask for a documented upgrade runbook and budget a recurring support arrangement if the client wants upgrades handled externally. |
Securing the high availability cluster's secrets, network paths and admin access
A highly available GitLab cluster has many nodes, each holding credentials, certificates and network paths into the data tier. The controls below cover what each node must share, which ports each component should expose, how credentials are rotated and how administrators sign in and leave traces.
Keep secrets identical and backed up
The gitlab-secrets.json file (generated on the first node and used to encrypt database values and tokens) must match on every application node, or users will see decryption failures after failover. Store a copy outside the cluster in a controlled vault, and confirm that it is captured separately from the gitlab-backup archive. Check each node's copy against a stored checksum after every configuration change.
Segment the data tier network
PostgreSQL, Redis, Consul and Gitaly listen on ports that should be reachable only from the nodes that use them. Map each component's client and peer traffic before writing firewall or security group rules, including Consul gossip and Praefect connections. Test the rules from a node that should be blocked, not only from a permitted one, and record the port list in your change records.
Encrypt the load balancer and internal hops
Terminate TLS on the load balancer with certificates your team controls, and confirm which internal connections GitLab can encrypt in your chosen reference architecture. Internal TLS options differ by component and version, so confirm each one against the current documentation before enabling it. Plan certificate renewal and trust-store updates on every node as part of the same process.
Rotate database and Redis credentials in a window
The application nodes hold credentials for PostgreSQL, Patroni-managed replicas, Redis and Praefect. Changing one of them requires updating every node that uses it, so treat rotation as a planned change window with a rollback path rather than an ad hoc task. Confirm the exact order of credential changes with the current reference architecture guidance and rehearse the procedure in a non-production cluster.
Enforce administrator access and two-factor
Administrator accounts control every project and the instance settings, so they need the strongest sign-in controls. Enforce two-factor authentication for administrators and review the accounts holding admin rights each quarter. Confirm which identity provider settings apply to administrator sign-in, and check that sign-in events and changes to permissions reach your central log store.
Roll out hardening guidance in stages
GitLab's hardening guidance covers application settings, CI/CD, configuration files such as gitlab.rb, the operating system and a mapping to NIST SP 800-53 controls. GitLab describes this guidance as a work in progress to be rolled out gradually. Apply one area at a time to a staging cluster, confirm each setting against the current hardening page before changing it, and record the result for your control evidence.
How to prove failover works and what to monitor, back up and upgrade afterwards
Failover is proven only when a test stops a node under load and the team records what happened. For each stateful layer in the high availability design, which means Gitaly Cluster with Praefect, PostgreSQL with Patroni, Redis Sentinel and Consul, stop one node while a load generator drives traffic. Before the test, write down the expected outcome for that component: either service continues without user-visible errors, or a leader or primary election completes within a window your application owners have agreed. Run one layer at a time so each result can be traced to a single cause. Hold the load at the target API request rate for your size. The GitLab reference architectures documentation lists rates from 20 requests per second at 1,000 users up to 1,000 requests per second at 50,000 users, so confirm the figure for your chosen architecture before testing.
Testing failover alone does not prove recovery. Restore a recent backup into a separate, isolated environment and confirm the instance works. The restore must use the same gitlab.rb configuration and the gitlab-secrets.json file from the source instance, because encrypted data such as CI/CD variables and two-factor secrets cannot be read without them. After the restore, check sign-in, a repository clone, a push, a merge request, a CI/CD pipeline run and access to object storage. Also verify that every Runner registered to the instance is at the same major and minor version as GitLab. The Runner documentation advises keeping these aligned, and a mismatch found during an incident is a poor time to discover it.
Rehearse the upgrade on staging using a copy of production data and the same topology. GitLab requires upgrades to pass through required upgrade stops, which since GitLab 17.5 fall at versions x.2, x.5, x.8 and x.11, for example 18.2, 18.5, 18.8 and 18.11. Plan the path from your current version to the target version, then run each stop in order. At every stop, record the duration, any background migrations still running, errors in the logs, and the state of each node in the cluster. Repeat the failover checks after the final stop to confirm that high availability still works on the new version. The rehearsal output is your evidence for the production change window, so store it with the topology and runbook records.
After the first successful test, the work becomes operational. Monitor each stateful layer separately: PostgreSQL and Patroni, Redis and Sentinel, Consul, and Praefect with its Gitaly storage nodes. Alert on replication lag and on leader changes, because a frequent leader change often points to a network or resource problem before users notice one. Back up the PostgreSQL database, the repositories and the secrets files on schedules you have tested, and keep the backup copies outside the failure domain of the primary cluster. Maintain a topology document that names every node, its role and its network placement, and write a runbook for each failover path. A Geo secondary site is a separate disaster recovery design with its own replication and promotion steps, so test it on its own schedule and do not treat it as proof of in-site high availability.
Questions teams ask before building GitLab high availability
Do we need high availability for GitLab below 3,000 users?
Not always, but the GitLab reference architecture documentation generally recommends a high availability strategy from 3,000 users upward. Below that size, the question is how much unplanned downtime your engineering teams and release pipelines can absorb. Map the cost of an hour without source control, code review or CI/CD against the cost of the extra nodes, the database and storage clustering, and the operational work. A single well-backed-up instance with a tested restore procedure may meet your tolerance. If your tolerance is low, or your user count is growing toward the recommended threshold, plan for high availability before the growth arrives, because retrofitting it onto a running instance is harder than building it in from the start.
What does a GitLab high availability build cost?
The cost comes from four components: the servers and storage sized for your reference architecture, the GitLab subscription tier if you choose a paid one, the internal time your team spends, and the fixed-scope services fee if you hire a partner. Infrastructure and licenses recur, while design, build and the first cutover are largely one-time. GitLab Premium is listed at 29 US dollars per user per month billed annually on the GitLab pricing page, and Ultimate is custom priced. Ask any partner for a written quote that separates one-time work, recurring infrastructure, subscription fees and ongoing support, and state which environments (production, staging, disaster recovery) are included.
How long does a GitLab high availability project take?
Duration depends on the scope and the number of environments, the identity and network decisions still open, the storage platform you use, and how much testing your change process requires. There is no fixed timeline that applies across organizations. Ask for a written plan that lists the phases, the environments built, the failover tests included and the dependencies on your side, such as network changes, certificates and approvals. A plan that cannot state the environments and test cases is not yet specific enough to compare.
Can our own team build GitLab high availability without a partner?
Yes, if the team already has working experience with PostgreSQL replication and failover, Consul service discovery, Redis Sentinel and storage clustering, and if it can write and test a runbook. The hard part is rarely the first install. It is the failover tests, the backup and restore drills, and the upgrade procedure that must work across multiple nodes. Assess these skills honestly, name an owner for each component, and decide whether the team will also operate the system after go-live. Teams that lack one of these skills often bring in a partner for design review or the first build, then run the platform themselves.
What does the GitLab high availability work need from our team?
Expect to provide access to your cloud accounts or data center, the network design decisions (subnets, load balancer, DNS and certificates), identity details for single sign-on or directory integration, a change window for cutover, and a named owner who can approve decisions quickly. Storage, backup targets and retention rules also need an owner. Missing decisions in these areas are the most common reason a fixed-scope project waits, so confirm them before the work starts and record them in the written scope.
Can Kubernetes host PostgreSQL and Redis for GitLab?
No, according to the GitLab reference architectures documentation, running stateful components such as PostgreSQL and Redis inside Kubernetes is not supported. The Cloud Native Hybrid architecture runs stateless GitLab components on Kubernetes and keeps stateful services on virtual machines or managed services. If your platform team prefers Kubernetes, plan the database, Redis and Gitaly storage outside the cluster, and confirm the supported layout in the current documentation for your version before you commit to a design.
Is GitLab Geo the same as high availability?
No. High availability keeps one GitLab site running through the failure of individual nodes, usually within the same location. GitLab Geo provides a warm-standby secondary site in another region that is continuously synchronized, so you can recover after a site-level disaster. Geo is available in the Premium and Ultimate tiers for self-managed GitLab, according to the GitLab Geo documentation. Most organizations that need both plan high availability for day-to-day resilience and Geo for disaster recovery, and they should set recovery time and recovery point targets for each before choosing the tier.
Which GitLab tier do we need for high availability?
The answer depends on the features you need, not on user count alone. High availability itself is a deployment pattern, so confirm which features your teams require, such as advanced CI/CD, priority support, Geo, security scanning or compliance features, against the GitLab pricing page before you decide. The pricing page lists advanced CI/CD and priority support for Premium, and application security testing, software supply chain security, vulnerability management and compliance features for Ultimate. Check the current tier details for your version, because feature placement can change between releases.
How DeployOpen scopes, builds and hands over a high availability GitLab
DeployOpen plans, implements, hardens, documents and supports self-hosted GitLab inside your own infrastructure, including multi-node high availability layouts. Engagements are fixed-scope, with scope, deliverables and timelines agreed in writing before work starts.
How we scope
- Confirm the user count and API request rate to choose a matching GitLab reference architecture before design begins.
- Decide between Linux package and Cloud Native Hybrid layouts, since stateful services such as PostgreSQL and Redis run on VMs or managed services.
- Record in writing which components are in scope: Gitaly Cluster with Praefect, Patroni, Redis Sentinel, Consul and load balancing.
How we build
- Stand up the stateful tiers first, then add stateless GitLab application nodes and verify each component independently.
- Test failover for each component, such as a Patroni leader switch or Praefect node loss, and record the observed behavior.
- Configure backups for the database, repositories and secrets files, and run a restore test on a separate environment.
How we hand over
- Deliver architecture diagrams, configuration records, network and port maps, and the failover and restore runbooks in your repositories.
- Walk your operations team through routine tasks such as node replacement, backup checks and running a multi-node upgrade.
- Document the upgrade path, including required upgrade stops at x.2, x.5, x.8 and x.11, so your team can plan future changes.
How we support
- Ongoing support, upgrades and continuous testing are available as a retainer, scoped separately from the initial build.
- Confirm with us which patch and minor release cadence your retainer covers, and how security fixes are applied to your instance.
- Agree in writing who handles incident response for node failures, and which parts of your environment remain your team's responsibility.

