How to plan a GitLab 17 to 18 upgrade without guessing the path
If your self-managed GitLab instance is on 17.x and must reach 18.x, the upgrade has to pass through GitLab's required upgrade stops, and the database must already be at PostgreSQL 16.5 or later before you start. For GitLab 18, the stops that matter are 18.2, 18.5, 18.8 and 18.11, so the work is a sequence of planned hops with checks between them, not a single version bump. Skipping a stop or assuming your current PostgreSQL version is acceptable is the most common way an upgrade goes wrong.
The path matters because GitLab 18 does not support PostgreSQL 14, and each required stop carries its own migrations that must complete before the next hop. Start by recording your exact current version, your installation method (Linux package, Helm chart, Operator, Docker or source) and whether the database is bundled, external, or part of a Geo or high availability setup. The GitLab 18 upgrade notes state that automatic database upgrades apply only to single-node Linux package installs, so Geo, HA and external database deployments need a manual PostgreSQL upgrade planned as its own step. Confirm that layout with your team before anything else is scheduled.
Finally, check the GitLab upgrade paths documentation for the stops that apply to your starting point, then confirm which patch releases to avoid along the way. The GitLab 18 upgrade notes advise against upgrading to 18.11.0 or 18.11.1 if CI jobs pull images with CI_JOB_TOKEN, so review your pipelines for that pattern. Write the path down as a dated list of hops, each with a backup taken beforehand, a named owner and a rollback decision, and treat any hop that cannot be completed as a stop in the plan rather than a reason to skip ahead.
What changes between GitLab 17 and 18 and what each change asks of you
This table lists the GitLab 18 changes that affect a 17.x instance and the action each one requires before you start. Read each row as a gate: confirm the row's condition against your deployment, then complete the action before moving to the next upgrade step.
| Change | Impact | Action needed |
|---|---|---|
| PostgreSQL 14 no longer supported | GitLab 18 does not support PostgreSQL 14, so an instance on it cannot upgrade directly. | Confirm your database version, then reach at least PostgreSQL 16.5 before the GitLab 18 upgrade. |
| git_data_dirs removed in the Linux package at 18.0 | The git_data_dirs setting for Gitaly storage no longer works in the Linux package at 18.0. | Find every git_data_dirs entry in gitlab.rb and move Gitaly storage to the current configuration before upgrading. |
| Required upgrade stops at 18.2, 18.5, 18.8 and 18.11 | Upgrades must pass through these versions in order, so skipping a stop is not supported. | Plan each hop through the stops and check the upgrade paths documentation for the path from your current version. |
| Advisory against 18.11.0 and 18.11.1 with CI_JOB_TOKEN | GitLab advises against these versions if CI jobs pull images using CI_JOB_TOKEN. | Search pipelines for CI_JOB_TOKEN image pulls and choose a later 18.11 patch release if any exist. |
| Automatic database upgrades only for single-node Linux package installs | Only single-node Linux package installs get automatic database upgrades. Geo, HA and external databases need a manual upgrade. | Identify your topology first. If it is Geo, HA or external, schedule and run the PostgreSQL upgrade manually. |
Why PostgreSQL 16.5 is the first gate
GitLab 18 does not support PostgreSQL 14, so the database must reach at least PostgreSQL 16.5 before the GitLab application moves to 18. Treat this as the first gate in the plan, ahead of any application upgrade work. Start by confirming the current PostgreSQL version and the topology: whether the database is the bundled one in the Linux package, a single external server, or a Geo, high availability or external cluster. That answer decides both the path and who carries the work. The GitLab 18 upgrade notes set the requirement and the automatic upgrade boundary.
Two kinds of PostgreSQL change are involved and they are not the same operation. A minor update (for example, moving within the 16 line) replaces executables and needs a restart, because minor releases do not change the internal storage format. A major upgrade (for example, from 14 or 15 to 16) changes the storage format and uses pg_dumpall and restore, pg_upgrade, or logical replication. Logical replication can keep downtime to several seconds, but it adds moving parts and needs its own rehearsal. Confirm which of these your team has already run in production and how long a restore took on a copy of your data.
Check the support window before choosing the target. PostgreSQL 16 is supported until November 9, 2028, so landing on 16.5 or later gives the database a supported horizon beyond the GitLab 18 cycle, while a 14 or 15 target would expire sooner. Automatic database upgrades apply only to single-node Linux package installs. Geo, high availability and external database deployments need a manual PostgreSQL upgrade, and that work belongs in the change plan with a named owner and a rollback point. Ask your database team to confirm the exact target version against the PostgreSQL versioning policy before the GitLab schedule is fixed.
What to prepare before touching the 17.x instance
Six preparation tasks sit between a healthy 17.x instance and a safe move to GitLab 18. Together they establish a restore point you have tested, a clear picture of configuration and CI dependencies, and a rehearsal environment and window agreed with the people who depend on GitLab.
Prove the backup restores
A backup file that has never been restored is an assumption, not a restore point. Run the GitLab backup task, then restore it to a separate instance built on the same version and topology, and confirm repositories, issues, pipelines and registry content come back. Read the backup and restore procedures for the secrets files, which the archive does not contain and which you must copy separately. Without them, encrypted CI variables and two-factor data cannot be recovered.
Inventory gitlab.rb and git_data_dirs
Review every setting in gitlab.rb and note any git_data_dirs entries for Gitaly storage. GitLab 18.0 removed that setting in the Linux package, so each storage path must be moved to the current storage configuration before the upgrade. Record which settings are hand-edited, which were copied from older guides, and which are set on each node in a multi-node instance. Store the reviewed file under version control so the change can be diffed later.
Find CI jobs using CI_JOB_TOKEN
GitLab advises against upgrading to 18.11.0 or 18.11.1 if CI jobs pull images with CI_JOB_TOKEN. Search pipeline definitions, included templates and project variables for jobs that authenticate to the registry with that token. Group the results by project and owner so each team can confirm its jobs work before the 18.11 stop is scheduled. Flag jobs that pull from other projects, since those depend on access rules that may change.
Build a test environment that matches
Create a non-production instance with the same install method, operating system, PostgreSQL topology, Gitaly layout and external services as production. Restore a recent backup into it and run the full upgrade there first. Include Geo, high availability or an external database in the rehearsal if production uses them, because those deployments need manual database steps that a single-node test would skip. Time each step and keep the notes with the runbook.
Review integrations and runner versions
List every integration that calls GitLab, including SSO providers, chat, issue trackers, secrets managers, Kubernetes clusters and webhooks, and confirm each still matches the target version's documented behavior. Inventory each GitLab Runner, its executor and its version, because the Runner documentation advises keeping major and minor versions aligned with GitLab. Plan Runner upgrades in the same change window so jobs are not left on an unsupported pairing.
Set the window and communication plan
Decide the maintenance window, the rollback decision point and who can approve a rollback before the upgrade begins. Notify developers, release managers and support teams in advance, and state which pipelines and deployments will pause. Name one owner for the go or no-go call and agree on the status messages users will see during downtime. A written plan lets the team stop cleanly if a restore check or a CI test fails.
The upgrade sequence from 17.x through each 18.x required stop
This sequence moves a self-managed GitLab instance from 17.x to 18.11 through a verified backup, a PostgreSQL floor of 16.5, configuration changes for Gitaly storage and a check at every required stop. Each stop gives the team a known state to return to.
Confirm the current version and upgrade path
Record the exact GitLab version, the installation method, the database topology and every node or Geo site in scope. Then read the GitLab upgrade paths documentation and list each required stop between your version and 18.11. Confirm the list against your environment, including any external PostgreSQL, Redis or Gitaly nodes. This step is complete when a written path exists and everyone signing off on the change has reviewed it. The current version recorded here is the reference for every rollback decision that follows.
Take a verified backup before any change
Create a full GitLab backup and store it outside the instance, including the secrets file and configuration files that the standard backup does not fully cover. Take an infrastructure snapshot of the application and database hosts if your platform supports it. Restore the backup to a separate test host, or confirm that your team has done so before, and check that repositories and the database load correctly. This step is complete when a restore has been tested. The verified backup is the rollback point for every later step.
Upgrade PostgreSQL to at least 16.5
GitLab 18 does not support PostgreSQL 14, so the database must reach at least 16.5 before the 18.x path begins. Single-node Linux package installs can let GitLab upgrade the bundled database automatically. Geo, high availability and external database deployments need a manual PostgreSQL upgrade, scheduled with the database owner. Choose pg_upgrade, dump and restore, or logical replication based on your downtime tolerance and topology. The step is complete when the database reports 16.5 or later and GitLab starts and passes its health checks. If it fails, restore the database from the backup in the previous step.
Reach the 17.x stop and clear git_data_dirs
Upgrade through the required 17.x stop that leads to 18.2, using the version your path listed in the first step. Before this stop, confirm that all batched background migrations show as finished, because the next hop depends on them. Also remove the git_data_dirs setting for Gitaly storage from configuration, since GitLab 18.0 removed it in the Linux package. Replace it with the current Gitaly storage configuration and verify repository access. The step is complete when migrations are finished, the instance is healthy and repositories load. Roll back to the prior package and configuration if either check fails.
Upgrade through 18.2 and 18.5
Upgrade to 18.2 first, then confirm background migrations have finished and check instance health, including sign-in, a Git push and a pipeline run. Repeat the same pass for 18.5. Do not move to the next version until the current stop is verified, because each required stop depends on the migrations that the previous one completed. Keep the pre-upgrade backup until the upgrade to 18.11 is verified. Record the version, time and check results for each stop. The step is complete when the instance runs 18.5 with migrations finished and the checks pass. Roll back by restoring the backup and reinstalling the previous version, since database migrations generally cannot be reversed in place.
Upgrade to 18.8 and 18.11 with CI_JOB_TOKEN checks
Upgrade to 18.8, verify migrations and health, then upgrade to 18.11. GitLab advises against upgrading to 18.11.0 or 18.11.1 if CI jobs pull images using CI_JOB_TOKEN. Before this stop, search your pipelines for that token in image pulls and, if it appears, move to a later 18.11 patch release confirmed in the GitLab 18 upgrade notes. Run a test pipeline that pulls an image to confirm the behavior. The step is complete when the instance runs 18.11 or later, migrations are finished and a test pipeline pulls its images successfully. Roll back to the 18.8 backup point if the pipeline check fails.
Align GitLab Runner versions
Upgrade each GitLab Runner so its major and minor version matches the GitLab version on the instance, as the Runner documentation advises. Work through the fleet by executor type, starting with a non-production runner to confirm jobs complete. Check that registration and authentication still work after each upgrade. Confirm that Docker and autoscaling executors start jobs and clean up correctly. The step is complete when every runner reports the aligned version and a test job finishes on each executor type. Roll back an individual runner to its previous version if its jobs fail, and keep the server at 18.11 while you investigate.
Run post-upgrade checks and close the change
Run GitLab's health and consistency checks on the instance, review logs for errors from the 18.x stops and confirm that backups still complete with the new version. Test sign-in through your identity provider, repository access, merge request workflows, CI/CD pipelines and any integrations your teams rely on. For multi-node or Geo deployments, confirm each node and secondary site reports the same version. The step is complete when the checks pass, the backup job succeeds on 18.11 and the owners have signed off in writing. Keep the pre-upgrade backup until this sign-off is recorded.
Which patch releases to avoid and why
The one patch-level advisory you must check before choosing a target is for GitLab 18.11.0 and 18.11.1. GitLab advises against upgrading to either release if your CI jobs pull images using CI_JOB_TOKEN. To see whether you are exposed, search your pipeline definitions and project settings for jobs that authenticate to your container registry with that token, and note which projects pull images that way. If you find any, plan to land on a later 18.11 patch or on 18.11 only after confirming the registry behavior in a staging instance. Confirm the current wording of the advisory in the GitLab 18 upgrade notes, since it may be updated after this page is published.
The release model explains why patch selection needs care. Under the GitLab maintenance policy, bug fixes are backported only to the current stable release, while security fixes also reach the previous two monthly releases. An instance sitting on an older 18.x line will therefore receive security fixes for a while but not the bug fixes that may matter for your workload. This means a patch that looks safe on one line may be missing fixes that a newer patch carries, and the reverse is also true. Use the maintenance policy to decide how long a given 18.x release will keep receiving security fixes before you commit to a path.
Before you pin a target, read the release notes for every patch between your current version and the stop you plan to use, not only the final one. Look for upgrade warnings, changed defaults, removed settings, and background migration notes, and record which patches you ruled out and why. Then pin one tested version in your deployment configuration and run the upgrade against a restored copy of production, so the version you test is the version you ship. Keep the pinned version in change records, because it becomes the baseline for your next upgrade and for any rollback decision.
What makes a GitLab 17 to 18 upgrade take longer
Does a single-node Linux package install upgrade faster than Geo or HA?
Yes, in most cases. A single-node Linux package install is the simplest case because GitLab 18 can run the automatic database upgrade for it, while Geo, high availability and external database setups need a manual PostgreSQL upgrade. Each additional node, replica or secondary site adds components to order, verify and roll back, and Geo adds replication checks and secrets that must match across sites. Ask any partner to confirm which of these applies to your topology before agreeing a schedule.
Why does PostgreSQL 16.5 matter for the timing of a GitLab 18 upgrade?
GitLab 18 does not support PostgreSQL 14, so an instance on an older database must first reach at least PostgreSQL 16.5 before the GitLab 18 upgrade can proceed. If your database is still on PostgreSQL 14 or older, the database hop becomes its own piece of work with its own backup and rollback point. Check the installed PostgreSQL version early, because it often sets the first date in the plan.
How does the git_data_dirs removal affect the upgrade effort?
GitLab 18.0 removed the git_data_dirs setting for Gitaly storage in the Linux package, so any instance that still defines it in gitlab.rb must migrate that configuration to the current storage settings before or during the upgrade. The effort depends on how many storage paths are defined and how much custom configuration sits alongside them. Review every storage entry in /etc/gitlab/gitlab.rb and confirm the target format in the GitLab 18 upgrade notes before scheduling the change.
Do custom gitlab.rb settings add time to the upgrade?
They can. Every custom setting in /etc/gitlab/gitlab.rb is a potential conflict with a changed or removed key, and each one needs to be compared against the GitLab 18 notes and tested in staging. Heavily customized files, especially those with hand-written overrides for Gitaly, Nginx, or object storage, take longer to review than default files. Keep the file under version control so the reviewer can see exactly what changed.
How much does the size of repositories and data change the upgrade window?
Data size mainly affects the backup, the restore rehearsal and the time needed to run database and background migrations on a large instance. Large repositories, many projects, and big object stores extend the backup and restore steps, which must complete before any change is made. Measure the repository storage, database size and object storage footprint on your own instance, then ask for a rehearsal on a copy that matches production.
Why does the size of the CI and runner estate affect the upgrade?
Jobs running during an upgrade can fail, and some images pulled by CI jobs can break after the change. GitLab advises not upgrading to 18.11.0 or 18.11.1 if CI jobs pull images with CI_JOB_TOKEN, so a large runner fleet with many pipelines needs an inventory of which jobs use that pattern. The larger the estate, the longer the pipeline audit, the freeze window and the runner version alignment check take.
How do integrations and authentication providers lengthen the work?
Each integration, such as an issue tracker, secrets manager, Kubernetes cluster or chat system, and each authentication provider, such as SAML, LDAP, OAuth 2.0, Kerberos or SCIM, needs a post-upgrade test against its configuration. Count the providers in the Admin area and list the external systems that receive webhooks or tokens from GitLab. The more connections you have, the more test cases and the more coordination with the owners of those systems.
How do the required stops and background migrations change the plan?
Your instance must pass through the 18.x required upgrade stops, which are 18.2, 18.5, 18.8 and 18.11, so the number of hops depends on the version you start from. Between stops, batched background migrations must finish before the next upgrade, and each stop adds a validation point. Check the migration status in the Admin area before each hop and confirm the upgrade path in the GitLab upgrade paths documentation.
How DeployOpen scopes and delivers a GitLab 17 to 18 upgrade
DeployOpen plans, builds, tests and documents self-managed GitLab upgrades inside your own infrastructure, starting with a written scope that fixes the path through the required stops. Engagements are fixed-scope, so the scope, deliverables and timeline are agreed in writing before any work starts.
How we scope
- Inventory your current GitLab version, install method, node layout and PostgreSQL version before agreeing the path to 18.
- Confirm whether automatic database upgrades apply or whether Geo, HA or external databases need a manual PostgreSQL 16.5 upgrade.
- Record which Gitaly storage settings, runners and CI jobs use CI_JOB_TOKEN so the 18.11.0 and 18.11.1 advisory is checked.
How we build
- Rehearse each stop from 17 through 18.2, 18.5, 18.8 and 18.11 on a restored copy of production data.
- Replace git_data_dirs settings for Gitaly storage with the 18.0 configuration and validate repository access after each hop.
- Run a tested backup and restore before each stop, with the rollback point and PostgreSQL migration steps written down.
How we hand over
- Deliver a runbook with exact upgrade commands, checkpoints, pre-upgrade checks and rollback steps for each required stop.
- Document the results of the rehearsal, including background migration status and any patch releases to avoid along the way.
- Walk your operations and platform team through the runbook so they can repeat the procedure for later GitLab releases.
How we support
- Support the production cutover window and verify the instance against the agreed checklist before closing the engagement.
- Offer ongoing support, upgrades and continuous testing as a retainer if you want DeployOpen to carry the next stops.
- Ask for the support boundaries, response expectations and retainer terms in writing as part of the quote.

