When GitLab Maintenance Mode fits your change window
GitLab Maintenance Mode puts a self-managed instance into a read-only state, so users can still browse and clone projects but cannot push code, edit issues or make other changes that write data. That freeze keeps the data set stable while you upgrade, migrate or fail over. It is not an outage. The instance stays online, reads keep working and administrators control the state from the Admin Area. Use it when the risk is write drift during a window, not when the service must be unreachable to everyone.
Maintenance Mode fits work that needs a quiet database: upgrades that run database migrations, data moves between hosts and Geo failover, where the secondary site must take over without new writes landing on the old primary. Before the window, decide who keeps access (for example, administrators who must run the change), how CI pipelines and webhooks will behave, and how you will confirm that background jobs have finished. Read the current GitLab documentation on background job behavior, because the read-only state limits user writes and does not automatically stop every internal process.
Confirm the tier requirement for Maintenance Mode in the current GitLab documentation before you build a runbook around it, since editions and tiers change over time and the pricing page lists Premium and Ultimate features differently. If you run Geo, treat Maintenance Mode as one step in the failover runbook and check the GitLab Geo documentation for the exact sequence. Rehearse the full window on a staging instance and time it against your own backup and repository sizes, not against a generic estimate.
What users can still do in read-only mode
In read-only mode, developers can usually still clone, fetch and pull existing repositories, and browse code, commits and history in the web interface. The constraint is writes. Pushes and any change to repository state are expected to be refused until the instance returns to normal operation. Confirm the exact behavior for your version, including whether HTTPS and SSH are treated the same way and what error a blocked push returns, because developers and their tooling will hit it first.
- Clone and fetch: Existing repositories remain readable, so local work can continue against the last synced state.
- Pushes: Expect
git pushto fail. Commits made during the window stay local until writes resume. - Branch and tag changes: Creating or deleting branches and tags through Git should be assumed blocked.
- Local tooling: IDE integrations and credential helpers may show generic errors, so brief developers on what the message means.
- Unpushed work: Ask teams to keep a list of local commits to push after the window closes.
Test Git operations with a test account on a non-production project during your window to confirm each one.
Merge requests and issue discussions are where read-only mode is most visible to the team. Viewing diffs, reading threads and reviewing history typically remain available, while actions that write to the database, such as posting comments, approving or merging, are expected to be blocked. Maintainers should decide in advance whether reviews can be drafted offline and how merges that were already queued will be handled.
- Viewing: Merge requests, diffs, pipeline results and issue history stay readable.
- Comments and approvals: Posting comments, approvals and reviewer changes are expected to be refused.
- Merges: Merges will not complete during the window, including merges set to run when a pipeline succeeds. Confirm how queued merge requests behave in your version.
- Labels and milestones: Triage changes are writes and should be assumed blocked.
- Review backlog: Agree on a handoff list so reviewers know which items resume after the window.
Confirm which merge request actions are blocked in your version by testing each one on a sample merge request before the window opens.
Administrators keep read access to the Admin Area and can usually sign in, view settings and run the server-side commands that maintenance depends on. Configuration changes that write to the database are generally refused. This matters because the upgrade, backup and failover steps rely on a stable instance state, so administrators need a clear list of what they can and cannot change while the window is open.
- Admin access: Administrators can typically sign in and reach the Admin Area for status checks.
- Settings changes: Application setting changes are expected to be blocked, so schedule them before or after the window.
- User management: Creating, blocking or changing users may be refused, which can affect LDAP or SCIM sync jobs running in the background.
- Command-line tasks: Backup, upgrade and reconfigure commands run on the server rather than through the UI, and they are the steps your team controls directly.
- Background jobs: Confirm whether background job processing continues and how you will watch the queue while writes are blocked.
Run your runbook's admin steps on a staging instance at the same version to verify what remains available.
Pipelines need separate attention. Jobs that only read the repository and produce artifacts may behave differently from jobs that write back to GitLab, such as those that create releases, update environments or push to a registry through GitLab. Runners are separate services, so they may keep polling and starting jobs even while the web application is read-only, which can leave work half finished. Confirm this behavior for your version before the window opens.
- Pipeline creation: New pipelines triggered by pushes are expected to be blocked because pushes are refused.
- Running jobs: Jobs already in progress may finish, but status updates and artifact uploads may fail. Confirm this for your version.
- Runners: Runners can keep polling. Decide whether to pause them so jobs do not start against a partly unavailable instance.
- Deployments and releases: Jobs that write environment or release records may fail, so review deploy stages in advance.
- Scheduled pipelines: Schedules may trigger and fail, so review the schedule list before the window.
Pause runners and scheduled pipelines if your runbook calls for it, then confirm the result with a test pipeline.
Maintenance Mode settings and when each fits
This table compares the main ways an operator can turn Maintenance Mode on and off: the Admin area, the application settings API, and scripted or scheduled runs. Read each row for the trade-off that matters during a change window, then choose the method your runbook can repeat and audit. Confirm the Premium requirement and the options available for your exact version in the current documentation before the window opens, because both depend on tier and release.
| Method | How it is driven | Trade-off | When it fits |
|---|---|---|---|
| Admin area (UI) | An administrator changes the Maintenance Mode setting in the Admin area and saves it. | Clear record of who acted, but it depends on a person at a browser at the planned time. | A single planned upgrade on a small instance with an operator present throughout. |
| Application settings API | A token with admin rights sets the maintenance mode value through the settings API. | Repeatable and easy to include in a runbook, but the token is powerful and must be tightly protected. | Multi-step changes where the same enter and exit steps run across several environments. |
| Scripted or scheduled runs | A job wraps API calls with pre-checks, a timed entry and a verified exit step. | Removes manual timing errors, but a failed script can leave the instance read-only or in an unclear state without alerting. | Rehearsed Geo failover or migration windows where timing and post-change checks matter. |
| Rails console | An operator changes the setting directly on the instance through the application console. | Direct and independent of the UI and API, but bypasses guardrails and leaves a thinner audit trail. | Last-resort recovery when the UI and API are unavailable, ideally with vendor or partner support engaged. |
| Tier and version check | Confirm the Premium requirement, the entry and exit options and the user-facing messages for your release. | Documentation changes between releases, so a method that worked on one version may differ on another. | Before every change window, and again before any upgrade across a required upgrade stop. |
How background jobs and CI pipelines behave during maintenance
Maintenance mode blocks user writes, but it does not stop background work on its own. Before any cutover, operators need to decide what happens to the Sidekiq queues, which hold jobs that update the database, repositories, mirrors, notifications and cleanup tasks. Record queue sizes, scheduled sets and retry sets before the window opens, then watch them while the instance is in read-only mode. Jobs that try to write may fail, retry or wait, and any of these outcomes can leave data out of step after the cutover. Confirm the exact behavior for your target version in the maintenance mode documentation, and check the Background jobs monitoring page in the Admin area so the baseline is captured from your own instance.
CI/CD needs its own decision. Runners are separate processes that poll GitLab for work, so jobs can start during the window even when the instance cannot accept the writes that record their results. Status updates, logs, artifacts and cache uploads may be refused or delayed, and a job that finishes during the window may not report back cleanly. Scheduled pipelines can be created, skipped or run against an instance that cannot record them. Plan to pause scheduled pipelines, stop or pause the runner fleet for the window, and decide which in-flight jobs must finish first. The GitLab Runner documentation covers runner configuration, but the pause sequence should come from your own runbook.
None of this should be assumed to work because the documentation describes it. Rehearse the full sequence in a staging environment on the same GitLab and Runner versions, using a scheduled job, a protected-branch merge that would trigger a deployment, and a long-running pipeline. Measure how long the queues take to drain, confirm that no production deployment starts during the window, and check that no job runs twice after the cutover. If you run Geo, add the secondary site to the rehearsal, because queued work and replication lag interact. Write down the results as go or no-go criteria for the real window.
How to plan and run a maintenance window
This sequence takes a self-managed GitLab instance from planning to a verified return to normal service. Each step closes with a check you can perform and record, so the window ends with evidence that the upgrade, migration or Geo failover completed and that users can write again.
Confirm tier, version and upgrade path
Record the current GitLab version and edition from the instance, for example with
gitlab-rake gitlab:env:infoon Linux package installs. Confirm that your license tier includes Maintenance Mode, which requires Premium. Compare the current version with the required upgrade stops at x.2, x.5, x.8 and x.11 in the GitLab upgrade paths documentation, and check the maintenance policy for the versions still receiving fixes. The step is done when a written path lists every stop and the target version, signed off by the platform owner.Take and test a full backup
Run a full backup using the procedure for your install method, as described in the GitLab backup and restore documentation. Keep the configuration and secrets files that the backup task does not capture, including
gitlab.rbandgitlab-secrets.json. Confirm the task reports success and that the archive and its checksum appear in the storage location you expect. Restore the archive to a separate test instance of the same version, then check that sign-in, a sample repository and a pipeline work. The step is done when the restore has been rehearsed and the result is recorded.Announce the window and pause dependent work
Send written notice to users, team leads and the owners of integrations, including the CI/CD teams whose pipelines and deployments will stop during read-only operation. List every system that depends on GitLab, such as runners, webhooks, chat notifications, external identity providers and any Geo secondary site, and agree how each one will be paused or drained. Ask each owner to confirm in writing that no release freeze or change conflicts with the window. The step is done when every owner has acknowledged the notice and the dependency list is attached to the change record.
Enable Maintenance Mode and confirm read-only
Turn on Maintenance Mode in the Admin Area settings and enter a message that tells users when write access returns. Sign in as a standard user, not an administrator, and check that the banner appears and that web pages still load. Attempt a test push, a new comment and a merge request change, and confirm that each is refused with the expected message. Also confirm that read-only API calls succeed and that write calls fail. Compare results against the Maintenance Mode documentation for your version. The step is done when the standard user's test cases match the expected behavior and the results are logged.
Drain background jobs and runners
Wait for background work to finish before you change the database or repositories. Check the Sidekiq queues on the Admin Area monitoring pages, and run
gitlab-ctl statuson each node to confirm that services are running as expected. Pause runners so that no new jobs start, and confirm that jobs already running have finished or were cancelled by their owners. Background jobs may continue under Maintenance Mode, so confirm that behavior for your version before you rely on it. The step is done when queues are empty or understood, runners are paused, and no job is still writing to the instance.Run the upgrade, migration or Geo failover
Execute the change in the order of your written path, one required stop at a time, and do not skip a stop. For a Linux package install, run the package upgrade, then
gitlab-ctl reconfigureandgitlab-ctl statuson each node. For a Geo failover, promote the secondary only after the plan confirms that the primary cannot accept writes, following the Geo documentation for your version. Record the exact version reported after each stop. The step is done when every node reports the target version and the change record shows the stops in the planned sequence.Disable Maintenance Mode and run health checks
Turn off Maintenance Mode and confirm that the banner clears for a standard user. Check the readiness and liveness endpoints,
/-/readinessand/-/liveness, through your load balancer, and rungitlab-rake gitlab:checkon the instance. Test a clone, a push, a merge request and a pipeline on a non-critical project. If the window involved a Geo secondary, check its replication status. Restart runners and watch the first jobs complete. The step is done when all health checks pass and the test pipeline finishes, and the change owner then closes the window.
Security risks while writes are blocked
Maintenance Mode makes an instance read-only, but it does not make it safe by default. The controls below decide who can change the mode, who keeps access during the window, what gets recorded, and whether you can recover if the change goes wrong.
Administrator and break-glass access
Decide in advance which administrator accounts keep working while writes are blocked and how break-glass access is granted, logged and removed afterward. Confirm that a break-glass account is not tied to the same identity provider that the maintenance itself might disrupt. Test that you can sign in and reach the Admin Area before the window opens. GitLab's hardening guidance on application settings is the reference for tightening these accounts.
Who may enable or disable the mode
Limit the change to a named group of administrators who are authorized to put the instance into read-only state. Write the approval step into your change record, including who starts the window and who confirms it has ended. A forgotten mode left on overnight blocks developers and CI, so assign an owner for the disable step as well as the enable step.
Audit logging of the change
Record who turned Maintenance Mode on and off, the time of each action and the reason. Keep these entries alongside the instance's own logs and forward them to the system you use for security monitoring. Compare the audit trail with your change ticket after the window to confirm nothing happened outside the approved plan.
Pending CI jobs and secrets
Jobs that are already running, or that are queued, can still reach secrets and deploy targets during the window. Decide whether to pause pipelines, cancel jobs or let them finish, and check that runners are not left holding credentials for systems being changed. Review CI/CD variables and protected environments after the window, since a migration or restore can change which values are active.
A tested backup before the change
Take a backup immediately before enabling the mode and confirm it is complete and restorable. Include the secrets file, because a backup without it cannot restore encrypted values. Restore the backup to a separate environment at least once before relying on it for a maintenance change. Confirm the backup covers the object storage and repositories your upgrade or migration touches.
Using Maintenance Mode during Geo failover
The key point is that Maintenance Mode belongs in the failover sequence before a Geo secondary is promoted, because the primary must stop accepting writes before you can confirm that the secondary holds the data you expect. A Geo secondary is a warm standby in another region that is continuously synchronized for disaster recovery, as described in the GitLab Geo documentation. Replication is asynchronous, so any change made on the primary during an unplanned loss may not have reached the secondary. For a planned failover, putting the primary into read-only Maintenance Mode first narrows that gap, and it gives you a fixed point to compare replication status against before you promote anything.
Your decision is whether the primary is still reachable enough to be put into Maintenance Mode. If it is, run the planned sequence: stop writes, confirm the secondary has caught up on repositories, uploads and the database through the Geo status views in the Admin Area, then promote the secondary. If the primary is unreachable, you are running an unplanned failover, and Maintenance Mode cannot be applied, so the recovery point will be whatever the secondary last replicated. Plan for that case in advance, including how you will reconcile work that was not replicated and who approves accepting that data gap.
The promotion steps, the commands and the checks change between GitLab versions, so treat the Geo documentation for your exact version as the procedure of record and confirm it in a rehearsal on a non-production copy before you rely on it. Ask your team or partner to document the expected replication lag at the moment of cutover, the verification you will accept as "caught up," and the rollback path if promotion fails. Maintenance Mode setup and the Premium tier requirement for Geo are covered in the sibling sections, so confirm your edition before you plan the failover window.
Limits to confirm before relying on Maintenance Mode
Maintenance Mode looks simple on paper, but its behavior depends on your edition, your GitLab version, and how your instance is wired to other systems. The six items below are the questions to settle with GitLab or a partner before a planned window depends on the mode.
Tier entitlement for Maintenance Mode
Confirm that your subscription tier includes the Maintenance Mode feature before you schedule a window. Our reading of the supplied pricing information is that Premium is the tier that carries this requirement, so a Free instance cannot rely on it. Ask GitLab to confirm the entitlement for your exact license, and check that the license is active on the instance you plan to change.
Behavior on your exact version
Maintenance Mode options and the list of blocked actions can change between releases, so read the notes for the version you run now and the version you are moving to. Confirm which actions remain available to users and which background jobs keep running. Upgrades that cross a required upgrade stop also need their own window, so plan the mode around the full path.
External integrations and webhooks
Webhooks, CI triggers, mirrors and chat notifications may fail or queue while GitLab is read-only. Inventory every system that writes to GitLab or reads from it, including issue trackers, secrets managers and Kubernetes agents. Decide whether each integration should pause, retry or be disabled, and confirm with GitLab how queued events are handled once the mode is lifted.
Git over SSH during the window
Confirm whether Git pushes over SSH are rejected while Maintenance Mode is active and whether pulls and clones still succeed for your users. Automated jobs that clone repositories at runtime depend on this answer. Test the behavior on a non-production instance with your own SSH keys and your runner configuration, because client tools may report errors in different ways.
Container registry and package operations
Container registry pushes, package uploads and dependency proxy requests are write paths that may behave differently from repository reads. Confirm which of these remain available, and whether pipelines that publish images or packages will fail cleanly. Ask whether any registry storage operations are affected, and plan a check of registry health after the window closes.
Multi-node and Geo topology
On a multi-node or Geo deployment, confirm that the mode applies to every node that serves users and that the secondary site is not accepting writes in a way that conflicts with the primary. Ask how Maintenance Mode interacts with a planned Geo failover, and who has authority to switch the mode on each site. Verify this with GitLab support before a failover rehearsal.
Questions teams ask before running a GitLab maintenance window
Does GitLab Maintenance Mode require a Premium subscription?
Treat Maintenance Mode as a Premium-tier capability and confirm it against the feature availability for your exact GitLab version before you plan the window. The GitLab pricing page lists Premium at 29 US dollars per user per month billed annually, Free at 0 dollars and Ultimate as custom priced, and all three tiers are available for self-managed installations. If you run Free today, the tier decision is a licensing step that should be made before the window is scheduled, so it does not block the change on the day. Ask your GitLab account contact to confirm the tier that covers every feature your runbook uses.
How long does a GitLab maintenance window take?
The length depends on the change, the instance size and the upgrade path, so no single duration applies to every instance. The main drivers are the number of required upgrade stops between your current and target versions, the size of the backup and restore cycle, the number of nodes that must be updated, and the time needed for post-upgrade checks. Since GitLab 17.5, required upgrade stops fall at versions x.2, x.5, x.8 and x.11, so a multi-version jump can mean several sequential windows. Ask for a step-by-step runbook with a timed estimate for each stop, and confirm the figures in a test environment built from a recent backup.
What does a maintenance window need from our team?
Your team needs named owners for the GitLab instance, the database and storage, the runners and the user communication, and each owner must be available for the full window. Engineers must confirm a recent, restorable backup, agree the rollback decision point in advance, and hold change approval before the window opens. Users need notice that read-only mode will block pushes, merges and most writes, so developers can plan around it. Someone should also verify that CI/CD pipelines and scheduled jobs are paused or queued correctly, since background work continues while the instance is restricted.
Can our own team run a GitLab maintenance window?
Yes, many teams run planned upgrades with their own staff, provided they have the skills, time and rollback plan to do so safely. The work is manageable when the instance is installed with the Linux package, the team has rehearsed the upgrade in a non-production copy, and the required upgrade stops are scheduled in advance. A partner is most useful when the instance is multi-node, relies on Geo, uses external databases or object storage, or must meet a formal change-control process. DeployOpen plans, implements, upgrades, documents and supports self-hosted platforms in your own infrastructure, and most engagements are fixed-scope with agreed deliverables in writing.
What drives the cost of a planned GitLab change?
Cost follows the effort and risk of the change, and it has two parts: one-time planning, rehearsal and execution work, and recurring costs such as licenses, infrastructure and support retainers. The largest drivers are the number of upgrade stops, whether the instance is single-node or highly available, how complex the database and object storage layers are, and whether a Geo secondary must be kept in step. Licensing is a separate line item, and the GitLab pricing page lists Premium at 29 US dollars per user per month billed annually for self-managed installations. Testing scope, change-control evidence and the number of rehearsals also move the total up or down.
What should we ask for in a quote for a maintenance window?
Ask for a written scope that names the source and target GitLab versions, every required upgrade stop, and the instance topology covered. The quote should list deliverables such as the runbook, the rehearsal in a non-production environment, the backup and rollback verification, the maintenance-mode communication plan and post-change checks. Request the assumptions behind the schedule, the access and approvals your team must provide, and what happens if a stop fails. Also confirm which items are one-time and which recur, such as a retainer for later upgrades, and ask how changes outside the agreed scope are priced.
What keeps running while GitLab is in read-only mode?
Read-only mode stops most writes, so users can generally still read repositories and view issues and merge requests, but they cannot push, merge or change project data. Background jobs and CI/CD behavior need explicit checks in your runbook, because queued work, scheduled pipelines and runner jobs can still interact with the instance during the window. Confirm which API calls, webhooks and integrations are expected to fail or retry, and test them in a rehearsal. The exact behavior depends on the version, so verify it against GitLab's documentation for the release you are moving to.
How DeployOpen plans and runs GitLab maintenance windows
DeployOpen plans GitLab Maintenance Mode as part of a wider change, not as a single switch. We scope the read-only window, the work that runs inside it and the checks that confirm the instance is safe to reopen, then document and support the procedure in your own infrastructure.
How we scope
- The written scope names the window purpose, such as an upgrade, a migration or a Geo failover, and who may trigger it.
- We confirm your edition and tier, since Maintenance Mode and Geo depend on Premium or Ultimate.
- We list the background jobs, scheduled pipelines and integrations that must pause or be checked before the window opens.
- Engagements are fixed-scope, with deliverables and timelines agreed in writing before work starts.
How we build
- We write the runbook sequence: enable Maintenance Mode, drain or confirm jobs, take a backup, perform the change, then disable it.
- We test the procedure on a non-production instance that matches your installation method and topology.
- We confirm which user actions stay available in read-only mode and tell users in advance what they cannot do.
- We check the upgrade path against required upgrade stops before scheduling any version change inside the window.
How we hand over
- You receive a runbook with entry criteria, exit criteria, rollback steps and named owners for each step.
- We document the commands, configuration keys and logs your operators need, so the procedure is repeatable without us.
- We walk your operations and platform staff through a dry run and record the results in the handover pack.
- Evidence from each window, such as change tickets and backup confirmations, is kept in your systems of record.
How we support
- Ongoing support, upgrades and continuous testing are available as retainers for planned maintenance windows.
- We review the runbook after each window and update it for new GitLab releases and changed reference architectures.
- Quotes follow from the written scope, so you can ask us to separate one-time build work from recurring retainer support.

