GitLab server requirements: CPU, memory, storage and databases

A practical baseline for sizing self-managed GitLab hardware, storage and databases, with the reference architecture and version checks to confirm before you buy or provision anything.

On this page

What GitLab server requirements decide before you provision

Sizing a self-managed GitLab instance starts from three inputs: how many users you will have, how many API requests per second they will generate, and how much CI/CD load your pipelines will place on the platform. GitLab publishes reference architectures ranging from 1,000 users at 20 API requests per second to 50,000 users at 1,000 API requests per second, and those published shapes are the defensible starting point for a hardware and database baseline. Pick the closest reference architecture to your forecast, then adjust for your own repository sizes, runner fleet and growth.

Several components carry most of the requirements, and each one scales differently. The application nodes handle web and API traffic, Sidekiq processes background jobs, Gitaly serves Git repository data and is sensitive to local disk performance, PostgreSQL holds metadata and needs the most careful capacity planning, Redis supports caching and job queues, and object storage holds artifacts, LFS objects, uploads and other large files. Gitaly storage should be local, fast disk rather than NFS, a point covered in the storage section. Ask your team which component will hit its limit first, because that answer determines where the money and effort go.

Treat any figure you read here as a starting point, not a final spec. GitLab revises its requirements with each release, and the database and Redis versions that a given GitLab release supports are listed in its installation documentation for that exact version. Before you order hardware or sign a managed database contract, confirm the vCPU, memory, storage and version numbers against the docs for the release you plan to install, and record that check in your build decision log so an auditor or future operator can see which baseline you used.

Which reference architecture fits your user count

The smallest published reference architecture is sized for 1,000 users and about 20 API requests per second. At this scale, a single-node or small multi-node layout is usually discussed first, and the main sizing question is whether your daily load stays close to the published request rate. Teams with heavy CI activity, large monorepos or frequent automated API calls should not assume a user count alone decides the size.

  • Published load point: The reference architecture for this tier is defined by 1,000 users and 20 API requests per second.
  • Single-node starting point: Smaller organizations often begin with one virtual machine, which keeps backups and upgrades simple.
  • CI and automation load: Pipeline volume, webhooks and bot traffic can exceed what the user count suggests.
  • Storage growth: Repository size and job artifacts grow over time and should be planned separately from compute.
  • Upgrade effort: A single node still requires planned maintenance windows and required upgrade stops.

Confirm the specification table for your chosen GitLab release and measure your current API request rate before copying any vCPU or memory figure.

How Gitaly, PostgreSQL and Redis hosting options compare

This table compares the four hosting choices for GitLab's stateful components: bundled Linux package services, separate VMs, managed database and cache services, and object storage. Read each row against your own operating model, because the operator keeps backups, patching and failover in most options. The main takeaway is that PostgreSQL and Redis cannot run inside Kubernetes under the Cloud Native Hybrid architecture, so Kubernetes deployments need VM or managed services for those components.

ComponentHosting optionWhen it fitsWhat the operator still owns
Gitaly storageBundled Linux package on the GitLab nodeSingle-node or small instances where one server holds Git data on local SSDDisk capacity, filesystem choice, backups of repository data and host patching
Gitaly storageDedicated Gitaly VMs with local SSDLarger instances that need repository storage separated from application loadNode sizing, Gitaly Cluster with Praefect at higher user counts, and failover testing
Gitaly storageNFS mountDiscouraged by GitLab for Gitaly, so treat it as a migration source rather than a targetPlan the move to local SSD and object storage, as described in the NFS migration topic
PostgreSQLBundled Linux package databaseSmall instances where one node carries the database with the applicationBackups, major version upgrades, tuning, patching and any replication or failover design
PostgreSQLSelf-managed PostgreSQL on separate VMs with PatroniHigh availability at larger scale, as the reference architectures describeCluster operations, failover drills, connection handling and backup verification
PostgreSQLManaged PostgreSQL service from a cloud providerTeams that want the provider to run instance operations and their admin model fits GitLab's requirementsProvider role setup, supported version limits per GitLab release, backups and GitLab upgrade compatibility
PostgreSQL in KubernetesStateful PostgreSQL inside KubernetesNot supported for GitLab under the Cloud Native Hybrid architectureUse VMs or a managed service for PostgreSQL even when the stateless components run on Kubernetes
RedisBundled Linux package RedisSmall single-node instancesPersistence settings, memory headroom, patching and restart behavior
RedisRedis Sentinel on separate VMsHigh availability deployments that follow the reference architecturesSentinel quorum, failover testing and version alignment with GitLab
RedisManaged Redis serviceTeams that want the provider to run the service, subject to confirming GitLab support for that service and versionConfirm supported configuration with GitLab, plus access controls, maintenance windows and monitoring
Redis in KubernetesStateful Redis inside KubernetesNot supported for GitLab under the Cloud Native Hybrid architectureUse VMs or a managed service for Redis in that architecture
Object storageCloud object storage or a compatible S3 serviceArtifacts, LFS, uploads, packages and other object types that move off local diskBucket policies, lifecycle rules, encryption keys, backup scope and confirming provider support per data type

Why burstable instances and NFS are discouraged for GitLab

Burstable instance types and NFS-backed Gitaly storage are discouraged for self-managed GitLab because both can look adequate in a quick test and then fail under sustained load. Burstable instances accumulate CPU credits while idle and spend them under load. Once the credits are gone, the instance is held to its baseline performance. A GitLab instance serving Git over SSH and HTTPS, running CI pipelines through Runners and processing Sidekiq background jobs rarely stays idle for long. The result is throttled Git operations, slow web requests and queued jobs that appear to come from GitLab itself when the cause is the instance type. Ask your cloud provider how credit accrual and baseline performance work for the exact instance family you plan to use, and check whether the sizing you chose holds through a full working day of pipeline activity.

Gitaly is the component that performs repository reads and writes, and it depends on fast, local file operations and reliable file locking. NFS adds network round trips to every operation and its locking semantics can differ from a local disk, which makes repository I/O slower and less predictable and can complicate concurrent access. For this reason the reference architectures call for local SSD storage for Gitaly, and object storage for data types such as job artifacts and LFS objects. Treat the storage type in the reference architecture documentation as the baseline for your sizing, and review the related guidance on moving off NFS before you build. Confirm current vendor guidance for your own storage platform, including how block volumes, file services and disk types behave under sustained I/O, rather than assuming a product is suitable because it is mounted as a POSIX file system.

How to size a GitLab deployment step by step

This sequence turns a user count and workload profile into a documented GitLab sizing decision, so the release, database versions, hosting model and storage design are settled before any infrastructure is ordered.

  1. Define users, API load and CI demand

    Start by writing down the number of named users, the expected concurrent activity, the rough API request rate and the CI/CD job volume you expect at peak. Your identity, security and platform teams should agree on these figures, since they drive every later choice. The step is done when you have a single signed-off sizing sheet that states the user count, the API load assumption and the pipeline volume, with the source of each estimate noted. Ask your GitLab partner or the reference architecture documentation to confirm which load band your numbers fall into.

  2. Choose the reference architecture

    Match your sizing sheet to the closest published GitLab reference architecture, which the documentation lists from 1,000 users at 20 API requests per second up to 50,000 users at 1,000 API requests per second. Note that GitLab generally recommends a high availability strategy at 3,000 or more users, which changes the component count significantly. The output is a named reference architecture and a list of the components it requires, including Gitaly, PostgreSQL, Redis, Sidekiq and the application nodes. Check the architecture page again before you commit, because the documented specifications change between releases.

  3. Confirm the GitLab release and database versions

    Select the GitLab release you will deploy, then check the maintenance policy and the upgrade paths documentation for the PostgreSQL and Redis versions that release supports. Also confirm the required upgrade stops if you will upgrade later from an older version. The output is a written release decision with its supported PostgreSQL and Redis versions recorded in the sizing document. If the release you want is not on a currently maintained line, stop here and choose again, because bug fixes are backported only to the current stable release and security fixes only to the previous two monthly releases.

  4. Select the hosting model for each component

    For each component, decide whether it runs on VMs, on a managed service, or in another supported arrangement. The reference architectures document states that PostgreSQL and Redis are not supported inside Kubernetes, and the Cloud Native Hybrid architecture keeps stateful services on VMs or managed services. Record the decision per component, including whether managed PostgreSQL and managed Redis meet the version and extension requirements for your chosen release. Confirm each provider's support matrix with the vendor before you rely on it.

  5. Size Gitaly local SSD storage

    Estimate Gitaly storage from your repository inventory, including the total size of existing repositories, expected growth over the planning period, and headroom for repository maintenance and backups staged on the same host. Use local SSD block storage for Gitaly, and avoid NFS, since the documentation discourages it for this data. Also review burstable instance types, which the documentation discourages for production components. The output is a Gitaly volume plan with capacity, IOPS expectations and a growth review date. Verify the plan with a test restore of a representative repository set.

  6. Plan object storage and backup capacity

    List the data types that belong in object storage, such as artifacts, LFS objects, uploads, package and container registry data, and CI job logs where the configuration supports it. Size each bucket or container from current usage and retention rules, then size backup targets separately so backups do not compete with live data. The output is a storage table that maps each data type to a bucket, its retention setting and its backup location. Confirm which object storage providers GitLab tests and which it documents from the community before you commit to a provider.

  7. Validate with a test instance

    Build a non-production instance at the chosen release with the planned component layout, then load it with a representative sample of repositories and a synthetic CI workload that approximates your peak. Measure CPU, memory, disk latency and database connection use during the run, and compare the results with the reference architecture targets. The step closes when the test results support the sizing sheet, or when you have revised the sheet and rerun the test. Keep the test report with the sizing record, since it becomes the baseline for later capacity reviews and upgrade planning.

Security considerations for the server baseline

Sizing a GitLab server is also a security decision. Each component you size, from the database and Redis to Gitaly and runners, adds an attack surface and a data store that needs protection. The cards below cover the controls that should be designed in alongside the CPU, memory and storage numbers.

Restrict database and Redis access

PostgreSQL and Redis hold credentials, session data and project metadata, so they should accept connections only from the application and Sidekiq tier. When you size these services separately, define the network paths, firewall rules and authentication for each one before the build starts. Confirm that no database port is reachable from user networks or runner subnets, and review the setting each time you add a node.

Encrypt Gitaly and object storage

Gitaly volumes hold every repository, and object storage holds job artifacts, LFS objects and package data. Plan encryption at rest for both, either through the disk and bucket encryption your cloud or data center provides or through a key management service you operate. Ask your storage team how keys are rotated and who can read the volumes outside GitLab.

Separate backup storage

Backups contain the same repositories and database contents as production, so storing them on the same volumes or under the same credentials removes the protection a restore depends on. Keep backup targets in a separate account or failure domain with write-only access for the GitLab service account. Confirm the procedure for restoring the secrets file alongside the data, as described in the backup documentation.

Apply hardening in stages

The operating system and GitLab hardening guidance covers application settings, CI/CD, gitlab.rb and the host itself. GitLab describes this guidance as a work in progress to be rolled out gradually. Apply changes in a staging instance first, record each setting in version control, and test sign-in, pipelines and backups after each stage so that a security change does not become an outage.

Isolate runner hosts from core servers

Runners execute code from pipelines, and that code can be untrusted. Run runner hosts on separate networks from the Gitaly, database and Redis tier, and give them only the credentials their jobs need. Avoid placing runners on the GitLab application hosts, and confirm the executor type and isolation model with your runner design before you size the fleet.

Confirm access and secrets scope

Administrative access to the Linux package host, the gitlab-secrets.json file and the database role determines who can read everything above. Limit operating system accounts to named administrators, keep secrets out of shared configuration repositories, and confirm which team can rotate the database password. Review these access lists at each sizing change, since new nodes and roles add paths to the data.

Questions teams ask before sizing GitLab

How much hardware and effort does sizing a self-managed GitLab instance take?

Sizing starts from measured usage, not a fixed server profile. The reference architectures published by GitLab range from 1,000 users at 20 API requests per second to 50,000 users at 1,000 API requests per second, so your user count, API load and CI activity decide which tier of CPU, memory and storage you need. Effort depends on how much usage data you already have. Teams with clean metrics from their current Git host need less discovery time. Ask for the sizing inputs to be listed in the written scope before work starts, including which components (Gitaly, PostgreSQL, Redis, Sidekiq) will be measured and which are assumed.

What drives the cost of running GitLab up or down?

The main drivers are user count, CI load, and the availability design you require. GitLab recommends a high availability strategy for 3,000 or more users, which adds Gitaly Cluster with Praefect, PostgreSQL with Patroni, Redis Sentinel and Consul, and each extra node carries compute, storage and operations time. A disaster recovery requirement adds a second site. GitLab Geo, available in the Premium and Ultimate tiers, provides a warm-standby secondary site that is continuously synchronized. Subscription cost depends on the tier. The GitLab pricing page lists Free at 0 US dollars, Premium at 29 US dollars per user per month billed annually, and Ultimate as custom priced. Infrastructure is one-time setup plus recurring cloud or hardware cost.

Can a small team size and run GitLab without outside help?

A small team can do it if it has someone comfortable with Linux administration, PostgreSQL, backups and upgrades, and time to test under realistic load. Single-node installs from the Linux package are documented and bundle PostgreSQL, Redis and Sidekiq, so a small instance is a manageable project. The harder part is the ongoing work: required upgrade stops, monthly minor releases, backup restore testing and monitoring. Be honest with yourself about who owns those tasks after go-live. A partner can cover the sizing and build, a retainer can cover upgrades and support, or your team can keep all of it in-house.

What does the work need from our team before validation starts?

You need to provide usage data, a growth forecast and the constraints that shape the architecture. Usage data includes current repository size, number of active users, peak API request rates, and CI job volume and duration. The growth forecast should cover the next planned hiring and project waves. Network constraints include whether the instance must run offline or in an air-gapped network, which GitLab documents separately. Identity constraints include the authentication method, such as SAML, LDAP or SCIM, and whether Kerberos or smart card access is required. Confirm also which cloud accounts, data centers or hardware you can use, because that sets the database and object storage options.

How long does sizing validation usually take?

The duration depends on your environment, so confirm it against your own inputs rather than a generic figure. Validation time grows with the number of systems in scope, the quality of your usage data, and whether you need load testing on the target hardware. Approval steps inside your organization, such as security review of the chosen database or object storage service, often take longer than the technical work. Ask for the validation plan to list each step, the people needed from your side, and the dates on which your input is expected.

What should we ask for in a fixed-scope quote for GitLab sizing?

Ask for a written scope that names the deliverables, the environments covered and the acceptance criteria. Good quotes state which GitLab release and edition are assumed, which reference architecture or sizing method is used, and which components are measured under load. They should list what is one-time, such as design, build and validation, and what recurs, such as upgrades and support. Ask how changes to user count or CI load after sign-off are handled, what the client must provide and by when, and which tests prove the sizing. Fixed-scope engagements are agreed in writing before work starts, so make sure every assumption appears in that document.

Which GitLab release should we size against, and how often does it change?

Size against a release that is currently maintained and plan for upgrades from day one. GitLab ships a major release yearly, a minor release on the third Thursday of each month, and patch releases twice a month, and it currently maintains 19.5, 19.4 and 19.3. 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. Database and Redis version support also changes by release, so confirm the exact PostgreSQL and Redis versions for your target release with GitLab's documentation before you choose the hardware.

How upgrade stops change the database and runtime baseline

A sizing record for self-managed GitLab is only accurate for the release it was written against. Between required upgrade stops, the PostgreSQL and Redis versions that GitLab expects can change, so the baseline should be tied to a named target release rather than to whatever version is running today. Since GitLab 17.5, required upgrade stops fall at x.2, x.5, x.8 and x.11, for example 18.2, 18.5, 18.8, 18.11 and 19.2, 19.5, 19.8 and 19.11. Check the upgrade path for both your current release and your target release before you commit to a database engine or version, and record the result next to the CPU, memory and storage figures.

GitLab ships a minor release on the third Thursday of each month, patch releases twice a month and a major release yearly. The maintenance policy backports bug fixes only to the current stable release, while security fixes also go to the previous two monthly releases. That means an instance that falls behind a stop can be left without fixes for ordinary defects, and a database or Redis version that was supported at install time may no longer be the one a current release needs. Plan the target release as a supported version from the start, and set a review point for each upcoming stop so the database and runtime baseline is revisited before the upgrade window, not during it.

Ask your implementation partner or your own platform team to confirm three things in writing: the PostgreSQL and Redis versions required by the target release, whether a managed database service offers those versions in your region, and whether the upgrade path to that release passes through a stop that requires a database major version change. Where a stop changes the database, the work includes a backup taken before the change, a tested restore and time for the database upgrade itself, so these items belong in the upgrade plan and the sizing record together.

What DeployOpen scopes before any hardware is ordered

Sizing a self-managed GitLab instance starts with written decisions, not servers. The four deliverables below connect the user and CI load forecast to the layout, database and storage choices, and the checks that prove the build matches the plan. Engagements are fixed-scope, with deliverables and timelines agreed in writing before work starts. DeployOpen does not publish prices; a quote follows from the written scope.

Written requirements worksheet

A worksheet records named users, concurrent active users, API request rate, repository count and largest repository size, CI job volume and peak concurrency, and the availability target. It also records which GitLab release line will be installed and the upgrade stops it must cross. Without these inputs, any CPU or memory figure is a guess. Ask the vendor or your team to confirm the forecast numbers before anything is sized.

Sized reference layout

The layout maps the worksheet to a published reference architecture or a documented variant, then names the node count, vCPU and memory per role, and whether Gitaly, PostgreSQL, Redis and Sidekiq share hosts. It states the cloud or data center target and whether stateful services run on VMs or managed services. Confirm that the chosen layout matches the GitLab version you will deploy, since requirements change between releases.

Database and storage plan

This plan sets the PostgreSQL and Redis versions for the target release, the Gitaly storage type on local disks rather than NFS, and where object storage holds artifacts, LFS, uploads and packages. It covers backup targets and restore timing, and whether the database is self-managed or a managed service with the extensions GitLab needs. Ask for the version matrix in writing and confirm each entry against the release notes before purchase.

Validation checklist

The checklist is the acceptance test for the sizing: load test results against the forecast API rate, disk latency and free space on Gitaly volumes, database connection limits, Redis memory headroom, and a restore test from a recent backup. It also confirms that runners are version-aligned with GitLab and that upgrade stops are scheduled. Each item needs a named owner and a pass condition agreed before the build starts.

How DeployOpen scopes and delivers GitLab sizing

DeployOpen plans, implements, hardens, documents and supports self-hosted GitLab inside your own cloud accounts, data centers or air-gapped networks. For server requirements, we start from your user count, CI load and storage profile, then turn them into a written sizing baseline that your team can review and approve before any hardware is ordered.

How we scope

  • Engagements are fixed-scope, with sizing inputs, deliverables and timelines agreed in writing before work starts.
  • We collect user counts, peak CI job volume, repository size and growth expectations to define the sizing baseline.
  • Scope names the target GitLab release, the PostgreSQL and Redis versions that release supports, and the installation method.

How we build

  • We size vCPU, memory and Gitaly storage against the published reference architecture closest to your workload.
  • We check PostgreSQL and Redis versions against the GitLab release you plan to run, and flag any version limits before build.
  • We test burstable instance choices and NFS storage assumptions, and document why each recommendation was made.

How we hand over

  • You receive a written sizing record covering hardware, storage layout, database and Redis versions, and the upgrade stops in your plan.
  • Documentation explains how to monitor CPU, memory, disk and database load so you can recognize when capacity needs to grow.
  • Your team is walked through the sizing decisions, the trade-offs behind them and the questions to raise with GitLab or your cloud provider.

How we support

  • Ongoing support, upgrades and continuous testing are available as retainers after handover.
  • When GitLab releases change version requirements, we review the sizing baseline against the new release before you upgrade.
  • Retainer scope, response expectations and review cadence are confirmed in writing with the quote.

Talk to our team.

Tell us what you're working on, whether it's a deployment, an audit, a security test or a cyber range. You'll speak with an engineer who can help you scope it.

  • 30-minute call: free, with no obligation.
  • NDA on request: we can sign before you share details.
  • Clear next steps: a scope and plan after the call.