Azure DevOps cost vs self-hosted GitLab and Gitea

Azure DevOps charges per seat, parallel job and storage gigabyte, while self-hosted GitLab, Gitea or Forgejo moves that spend to servers, upgrades, support and staff time. This page shows how to weigh both sides with your own numbers.

On this page

Does Azure DevOps cost less than self-hosting GitLab or Gitea?

The answer depends on user count, pipeline volume and the staff time you would spend running the platform, not on the license line alone. The software license for GitLab Free, Gitea and Forgejo is zero, so the comparison is really between what Microsoft charges under your agreement and what your own servers, storage, upgrades, backups and support cost. GitLab lists Premium at 29 US dollars per user per month billed annually on its pricing page, and Ultimate is custom priced. Azure DevOps charges per user and per parallel job, and those rates depend on your Microsoft agreement, so read your own order form or ask your Microsoft account team for the rates that apply to your seat count and any Artifacts storage above the included allowance.

Self-hosting usually costs more in people time than in software. Plan for the servers or virtual machines, the database and object storage, high availability, backups and restore tests, and the upgrade path. GitLab requires upgrades to pass through required upgrade stops, for example 18.2, 18.5, 18.8 and 18.11, so someone must schedule and test each hop. GitLab's reference architectures also recommend a high availability design for 3,000 or more users, which adds components to run. Gitea and Forgejo are lighter to install, but the same operational duties apply to them.

Self-hosting tends to cost less when seat counts are large, when CI volume is heavy, or when paid parallel jobs and per-user fees dominate the bill. In those cases a fixed infrastructure and staffing cost can undercut per-seat pricing. Before deciding, ask for a written quote from Microsoft that breaks out seats, parallel jobs and Artifacts storage for the next term, then estimate your own infrastructure and staff hours against the same period. Confirm the infrastructure figures in your own environment, because they vary with the number of users and the CI workload.

Which cost components sit on each side

This table sets each Azure DevOps cost component beside its self-hosted counterpart for GitLab, Gitea or Forgejo, and notes whether it is paid once or recurs. Read it as a checklist of what to price on each side, since the self-hosted column moves cost from licences to servers, staff and support. Most of the difference shows up in staff time, upgrades and high availability rather than in software fees.

Cost componentAzure DevOps (Services or Server)Self-hosted GitLab, Gitea or ForgejoOne-time or recurring
Seats or user licensesPer-user Basic and Basic + Test Plans seats billed to the organizationGitLab Free, Premium and Ultimate tiers are per user for paid tiers; Gitea and Forgejo carry no per-seat software feeRecurring
Parallel CI capacityPaid parallel jobs for hosted pipelines; self-hosted agents need no parallel job purchaseRunners and build servers you provision; GitLab Runner and Gitea or Forgejo runners consume your own hardwareRecurring
Package and artifact storageArtifacts storage billed above the included free allowance; confirm current rates in Microsoft's pricingObject or disk storage for registries and packages, sized by your own retention rulesRecurring
Advanced security and scanning add-onsAdvanced Security billed per committer; confirm current terms with MicrosoftGitLab Ultimate is custom priced and needed for application security and compliance features; Gitea Enterprise and GitLab support are quoted, not listedRecurring
Azure DevOps Server licensingServer licences plus client access licences, with upgrades governed by the Modern Lifecycle PolicyNo server licence fee for Community Edition tiers; confirm current subscription terms for paid tiersMostly one-time purchase, with recurring maintenance or subscription where applicable
Servers and storageIncluded in Services; customer-hosted for ServerVirtual machines, Gitaly or repository storage, databases and load balancers you run, sized by user count and API loadRecurring
Backups and disaster recoveryLargely handled by Microsoft for Services; Server backups are your responsibilityBackup tooling, off-site copies and periodic restore tests you own, plus a Geo or standby site if requiredRecurring, with a one-time setup
High availabilityManaged by the vendor for Services; Server needs its own redundant tiersRedundant nodes, PostgreSQL and Redis clustering and failover testing; GitLab documents an HA strategy for 3,000 or more usersRecurring, with a one-time design
Upgrades and required stopsVendor-managed for Services; Server upgrades follow Microsoft's lifecycle policiesStaff time for planned upgrades, including GitLab required upgrade stops and Forgejo or Gitea version stepsRecurring
Support contractsIncluded in the Azure DevOps subscription or Microsoft support plansVendor support from GitLab, CommitGo for Gitea, or a partner; quoted per agreementRecurring
Implementation and migrationYour team or a partner, for example to move pull requests and work itemsPlatform build, importers, hardening and cut-over; scoped and quoted before work startsOne-time
Internal staff timeAdministration of projects, pipelines and permissionsPlatform administration, on-call, security patching and capacity planning in your own teamRecurring

What moves the cost comparison most

Six inputs decide whether a self-hosted GitLab, Gitea or Forgejo instance costs less than Azure DevOps over time. Each one moves the cost of the self-hosted side and the Azure DevOps side in different directions, so check them against your own numbers before reading any total.

User count

Azure DevOps charges per paid user, so seat cost rises with headcount. Self-hosted cost grows more slowly, but GitLab's reference architectures start at 1,000 users and the docs generally recommend a high availability strategy at 3,000 or more users. Above that point, plan for more servers, a load balancer and database redundancy, and ask your vendor which architecture applies to your count.

Pipeline and runner volume

Azure Pipelines bills parallel jobs, so more concurrent builds raise the license line. Self-hosted CI shifts that cost to runner hosts, which you size, patch and scale yourself. Measure peak concurrent jobs and build minutes per day, then price runner capacity for those peaks rather than averages.

Repository and artifact size

Azure Artifacts charges for storage above its free allowance, so large feeds raise recurring cost there. On self-hosted forges, repository and package storage becomes disk, backup and replication capacity. Large binary history inflates backup windows and restore times, so measure your largest repositories and package feeds before sizing storage.

Data residency requirements

If your policy requires data to stay in a specific region or on your own premises, a self-hosted forge may be the only option that meets it, which removes the hosting question from the comparison. Azure DevOps keeps customer data in the geography chosen for the organization but stores tokens and SSH keys in a US datacenter. Confirm this with Microsoft's data location documentation before you rely on it.

Availability targets

A higher uptime target means redundant application nodes, replicated Git storage and tested failover, which add servers, licenses for managed databases and staff on call. Azure DevOps Services carries that availability burden for you. Write down your required recovery objectives first, then cost the self-hosted redundancy needed to meet them.

Existing Linux and Kubernetes skills

Teams already running Linux and Kubernetes can absorb forge operations into current on-call and patching work. Teams without those skills will pay for training, consulting or hires. GitLab does not support running PostgreSQL and Redis inside Kubernetes, so a Kubernetes-only plan needs VMs or managed services for stateful parts. Inventory these skills before comparing staff time.

How to build the model with your own numbers

This sequence turns the component list into a three-year model built from your own seat counts, pipeline history, storage and quotes, so each side of the comparison rests on figures you can defend in a renewal discussion.

  1. Export current seat, pipeline and storage counts

    An administrator in the Azure DevOps organization settings exports the list of users with their access levels, including Basic and Basic + Test Plans assignments, and records how many committers use Advanced Security. Pipeline owners then record the number of parallel jobs the organization is licensed for, and the team lead notes Artifacts storage in GiB above the included allowance. Ask Microsoft's billing contact to confirm current per-unit rates for your geography and agreement type, since these are the figures your Azure DevOps line depends on. The step is done when you hold one sheet with user counts by license, parallel jobs, Artifacts storage and committer counts, each dated and tied to a named export.

  2. Map each user to a GitLab tier or Gitea model

    Work with each vendor to map your user list to the licensing model that applies. For GitLab, the pricing page gives Free at zero dollars and Premium at 29 US dollars per user per month billed annually, with Ultimate custom priced, so ask GitLab for a written quote covering the tier each team needs. For Gitea, ask CommitGo, Inc. which Gitea Enterprise terms apply, including its support scope. Separate users who need only Git hosting from users who need planning and security features, because that split usually decides the tier. The step is done when each user has one target tier or license model and the vendor quotes reference your exact user counts.

  3. Size runners and storage from job history

    Pull job history from Azure Pipelines for a representative period and calculate peak and average concurrent jobs, build duration and artifact size. Use those figures to size GitLab Runner or Gitea Actions runners and the object or block storage behind them, rather than copying the Azure DevOps parallel job count. Note which builds run on Microsoft-hosted agents and which need self-hosted agents, since that decides how much compute you must own. The step is done when you have a runner count, a concurrency target and a storage estimate per build type, each traced to the exported history.

  4. Price servers and backups from your own rates

    Price the GitLab reference architecture or Gitea deployment that matches your user count, using the rates from your cloud account or data center. The GitLab documentation sets reference architectures from 1,000 users up to 50,000 users and recommends a high availability strategy for 3,000 or more users, so confirm which size applies. Include PostgreSQL, Redis, Gitaly storage, load balancing, backup storage and a second site if you need recovery objectives. Run stateful components on VMs or managed services, because the GitLab reference architecture documentation does not support PostgreSQL and Redis inside Kubernetes. The step is done when you have a monthly infrastructure line and a backup line sourced from your own invoices or rate cards.

  5. Add upgrade windows and required upgrade stops

    Add a recurring line for upgrades and test environments. GitLab ships a minor release monthly on the third Thursday and 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. Plan one staging upgrade per stop, plus patch releases twice a month, and record the staff time each takes. For Forgejo, check the upgrade guide if you run Gitea 1.22 or earlier, because transparent upgrades pass through Forgejo v10.0.x first. The step is done when your model shows upgrade effort as a recurring line with a named owner and a count of upgrade paths in the next year.

  6. Price support and implementation as written quotes

    Collect written quotes for vendor support, implementation and migration work. Ask GitLab and CommitGo, Inc. for support terms matched to your severity needs, and ask DeployOpen for a fixed-scope quote based on a written scope agreed before work starts. DeployOpen does not publish prices, so the quote follows from the scope. Ask each provider to separate one-time migration work from annual support and retainers. The step is done when every support or services line in the model cites a signed or written quote with its scope attached.

  7. Run a three-year view with totals split

    Build a three-year table with two totals: one-time costs such as migration, data export and initial hardware, and recurring costs such as licenses, infrastructure, backup, support, upgrades and staff time. Keep the Azure DevOps column on the same basis, including the Azure DevOps Server option if you are weighing an on-premises renewal. Test how each figure moves when user count, parallel jobs or Artifacts storage change by a fixed amount, and state which assumption drives the result. The step is done when a reader can trace every total back to a dated export, a vendor quote or a rate card, and when the one-time and recurring totals are shown separately for each option.

How GitLab, Gitea and Forgejo change the cost profile

GitLab is open core. Its source repository licenses content outside the ee/ directory under the MIT Expat license, while ee/ content needs a paid subscription. The commercial tiers are priced per user, and the pricing page lists Free at 0 US dollars and Premium at 29 US dollars per user per month billed annually, with Ultimate priced on request. Your recurring cost therefore depends on which tier covers the features your teams use.

  • Support model: Premium adds advanced CI/CD and priority support, and Ultimate adds application security testing, supply chain security and compliance features, per the GitLab pricing page.
  • Release cadence: GitLab ships a minor release on the third Thursday of each month and patch releases twice a month, so someone must schedule upgrades regularly.
  • Required upgrade stops: Upgrades must pass through required stops, which since GitLab 17.5 fall at x.2, x.5, x.8 and x.11, so skipping a stop adds a multi-step project.
  • Maintenance window: Bug fixes go only to the current stable release, while security fixes also reach the previous two monthly releases, so staying current is the practical way to stay supported.
  • Feature coverage: GitLab covers Git hosting, merge requests, CI/CD, package registries and issues. It does not cover Azure Boards work item hierarchy or Test Plans as a direct equivalent, so confirm epics and test management needs during scoping.

Before quoting, confirm which tier each team needs and whether the ee/ features are covered by your subscription terms.

Costs teams forget on the self-hosted side

Self-hosting moves cost from the vendor invoice into your own staff time, infrastructure and risk controls. The cards below cover the operating work that a per-seat or per-job price hides, plus the commercial-side charges that still apply when you leave Azure DevOps.

Backup and restore testing

A GitLab or Gitea instance is only recoverable if restores have been rehearsed. Budget time for scheduled restores into a separate environment, checking repositories, database records, attachments and LFS objects, not just confirming that backup jobs finished. GitLab documents its own backup and restore procedure, so ask your team to name who runs the restore drill, how often, and what it costs in engineer hours each quarter.

Geo and disaster recovery replicas

Replicas for disaster recovery add a second full environment with its own compute, storage and network links, plus the effort to keep it in step with the primary. GitLab Geo is one documented option for secondary sites. Ask whether your recovery target is a warm standby, a cold restore from backup, or a read-only mirror, because each choice carries a different recurring infrastructure bill and a different recovery time you must accept.

Runner fleets and their patching

CI capacity is usually the largest recurring cost after staff. Each runner host needs operating system patches, container runtime updates, cache storage and autoscaling rules, and Azure Pipelines hosted agents no longer need any of that. Model the number of runners for peak pipeline load, the cloud or hardware cost to keep them available, and the monthly hours spent keeping images current.

Upgrade testing across upgrade stops

GitLab requires upgrades to pass through required upgrade stops, which in the current schedule fall at versions x.2, x.5, x.8 and x.11. Each stop is a staging rehearsal with database migrations, runner version checks and a validation of integrations before production. Monthly patch and minor releases add routine work on top, so plan a named test environment and a recurring slot for it, and confirm how many releases your team will track each year.

Monitoring and on-call coverage

Nobody is paged by Microsoft when a self-hosted forge stops accepting pushes. You need metrics and alerts for Git traffic, database health, storage growth, runner queues and certificate expiry, plus an on-call rota that covers the hours your developers work across time zones. Ask who holds the pager, what the escalation path is, and whether the on-call duty is already covered by existing platform staff or needs new hires or a retained support contract.

Training engineers who know only the Azure portal

Teams that have used Azure Repos, Boards and Pipelines for years will need to learn merge request conventions, pipeline syntax, runner tags and administration tools. This is a one-time cost in courses and lost productivity, but it recurs when new hires arrive. Estimate the training hours per role, pair administrators with the vendor documentation, and record the decision on which Azure DevOps habits you will keep and which you will retire.

Egress, licensing changes and migration effort

Leaving Azure DevOps has its own costs: data export time within API throughput limits, egress charges if you move large volumes out of Azure storage, and any Microsoft licensing change that affects Azure DevOps Server or Visual Studio subscriptions you keep for other purposes. Importers carry issues and history but may not carry Azure Repos pull requests with their reviews and comments, so budget engineering time to archive or recreate them. Ask Microsoft for the current egress and licensing terms in writing.

What is one-time and what recurs each year

The one-time costs of leaving Azure DevOps are the migration itself, the initial architecture, hardening and the integration of the new forge with your identity provider. Migration and setup are paid once, but they are often the largest single line in the first year, so price them separately from run costs. Ask any partner to split the quote into discovery, architecture, data migration, pipeline conversion, hardening and integration, because each has different drivers. Discovery should cover how many Azure Repos projects, pipelines, service connections and Artifacts feeds you actually use, since that count moves the effort more than the number of seats. Git history moves with a clone or mirror of each repository, but issues, pull requests, reviews and wikis need a platform importer. GitLab's import documentation covers Bitbucket Server, Gitea, GitLab and Git URLs, but it does not list Azure Repos as a source, so confirm what your Azure DevOps export can feed into it before you plan the work. Forgejo's dump-repo and restore-repo commands export issues, pull requests, releases, labels, milestones, comments and wikis from Git, GitHub, Gitea or GitLab, which means Azure DevOps data usually needs an intermediate step. Budget that conversion and reconciliation as a one-time cost, and check it against the export limits described in the Azure DevOps throughput documentation.

Recurring costs are the parts you keep paying every year. They include seats or subscriptions for any commercial tier you keep, such as GitLab Premium at 29 US dollars per user per month billed annually according to the GitLab pricing page, or Ultimate, which is custom priced. Server hosting, backup storage, and database and Redis capacity recur as well, and they grow with repository size and user count. Staff time recurs too: someone must patch, back up, restore-test and upgrade the platform. GitLab ships a major release yearly and a minor release monthly, and it requires stops at specific versions, so plan for regular upgrade windows and confirm the current maintenance schedule in the GitLab maintenance policy. Ask each vendor and integrator for a recurring cost model with the drivers named: user count, concurrent CI jobs, storage growth, support tier and upgrade frequency. For the Azure DevOps side, confirm what your current bill covers for Basic seats, parallel jobs, Artifacts storage and Advanced Security per committer. Then compare that with the open-source side, where the license cost may be zero but support, staff and infrastructure are not. Confirm with each option whether commercial support is needed, since Gitea offers commercial support through CommitGo and GitLab offers paid tiers.

Questions buyers ask before pricing a move

How much does self-hosted GitLab or Gitea cost to run compared with Azure DevOps?

The honest answer is that the cost depends on the components you run, so compare line by line rather than by a single total. Azure DevOps charges per user for Basic and Basic + Test Plans seats, per parallel job for pipelines, per GiB for Artifacts storage above the included allowance, and per committer for Advanced Security. A self-hosted forge replaces the seat and feature charges with software you can run at no license fee on the Gitea side, or with a GitLab subscription if you need Premium or Ultimate features. What you then pay for is the infrastructure (servers, storage, backups, load balancing), the people who run and upgrade it, and any support contract. Ask your team to price each of these in your own environment and compare the recurring totals over the same period. The Azure DevOps Server on-premises option has its own licensing, so include it in the comparison if you run it today.

How long does a migration take, and what drives the duration?

No single duration applies to every estate, and no researched figure is available to quote here. The main drivers are the number of repositories and their total size, how much pull request, review and work item history you need to keep, how many pipelines must be rewritten, and how many integrations and package feeds depend on the current setup. Git history moves with a clone or mirror, but issues, pull requests and reviews need a platform importer, and Gitea has no Azure DevOps importer, so those records may need a separate export and re-creation step. Ask for a written scope that lists each of these items, then agree on a timeline based on that inventory and a test cut-over.

What does the work need from our own team?

Expect the work to need platform engineers, a people lead for identity and access, and someone who understands your pipelines and release process. The platform side covers installing and configuring the forge, connecting it to your identity provider, setting up backups and monitoring, and deciding how runners or CI agents are provisioned. The application side covers branch protection rules, pipeline conversion from azure-pipelines.yml to the target CI syntax, and updating credentials and webhooks. Your team also owns decisions that no vendor can make for you, such as access model, retention rules and who approves changes. Confirm the time your staff can commit before a timeline is agreed.

Can we do the migration ourselves?

Yes, many teams do, especially for a small number of repositories and a Git-only scope. The limits are the skills and time available, not the tools. Gitea and GitLab both document installation methods and import paths, and Forgejo documents a command-line dump and restore flow for repositories with issues and pull requests. The harder parts are usually the pipeline conversion, identity integration, and the cut-over itself, where a mistake can break builds. If your team does part of the work, agree in writing which steps you own and which you buy in, and keep a rollback plan for each step.

What should we confirm in a quote before we sign?

Ask for a written, fixed scope that names the forge, version, deployment method, number of users and repositories, and which Azure DevOps components move (Repos, Pipelines, Boards, Artifacts or Test Plans). Confirm what is excluded, such as Boards work items or Test Plans, and who handles them. Ask how backups, restore testing, upgrades and security hardening are covered, and whether ongoing support is a separate retainer. Request the assumptions behind each line item, including the infrastructure you are expected to provide. DeployOpen does not publish a price list, and a quote follows from the written scope, so the scope is the thing to get right first.

Does GitLab Free cover our needs?

It depends on which features your teams use today. GitLab's pricing page lists GitLab Free at 0 US dollars, and all three tiers are available for self-managed installations. The page places advanced CI/CD and priority support in Premium at 29 US dollars per user per month billed annually, and application security testing, software supply chain security, vulnerability management and compliance features in Ultimate, which is custom priced. Map each feature your teams rely on, such as protected branches, approvals, advanced pipeline features, or scanners, against the tier that includes it. Confirm the current tier listing on the pricing page before you budget, because tier contents can change.

What happens to our cost model at the next GitLab upgrade stop?

GitLab requires upgrades to pass through required stops, and since GitLab 17.5 these fall at versions x.2, x.5, x.8 and x.11, with examples such as 18.2, 18.5, 18.8, 18.11, 19.2, 19.5, 19.8 and 19.11. Each stop is a planned change window, so budget staff time and a test environment for it rather than treating upgrades as routine. GitLab ships a minor release monthly and maintains a limited set of stable lines, so an installation that falls behind moves into a harder upgrade. Recurring cost therefore includes regular upgrade effort, test capacity and any support contract. Ask your provider to plan the upgrade calendar and to show what each stop involves in your environment.

When the self-hosted total cost wins and when it does not

Self-hosted GitLab or Gitea tends to win on total cost when the organization has many users, heavy pipeline load and a platform team that already runs stateful infrastructure. In that situation, the per-seat charge for Basic or Basic + Test Plans is multiplied across a large population, while the self-managed costs are largely fixed: servers, storage, backups, upgrades and a share of an engineer's time. Parallel jobs and Artifacts storage are where the arithmetic moves fastest, because build runners and package storage grow with pipeline volume rather than headcount. Ask Microsoft's sales team or your reseller to price the same user count, parallel job count and Artifacts volume you expect in three years, then compare that against your own infrastructure and staff estimates. GitLab's reference architectures begin at 1,000 users, and the documentation generally recommends a high availability strategy at 3,000 or more users, so the cost of running that resilience is part of the comparison, not an afterthought.

The commercial service tends to be cheaper for small teams without spare operations capacity. A self-hosted forge needs someone to patch it, restore it from backup, rotate its certificates and plan each upgrade, and that work does not disappear because the team is small. GitLab's maintenance policy describes a monthly minor release, twice-monthly patch releases and required upgrade stops, so an unattended instance will fall behind quickly. Gitea and Forgejo carry lighter operational footprints, but they still need the same backup, monitoring and security work. If no one on the team has that time, the staff cost of running the platform can exceed the licence savings. Confirm this with a written list of who will perform each recurring task and how many hours per month it realistically takes.

The on-premises branch of Azure DevOps has its own cost factor. Microsoft announced on October 7, 2025 that Azure DevOps Server drops the year from its name and moves from the Fixed Lifecycle Policy to the Modern Lifecycle Policy, under which customers who stay current receive continuous support. If your plan is to keep a server on an older release and upgrade rarely, that model may require you to upgrade more often than you have budgeted for. Put the upgrade cadence into your comparison: a self-managed Azure DevOps Server, a self-managed GitLab and a self-managed Gitea each impose recurring upgrade work, and the question is which of those cycles your team can sustain.

How DeployOpen scopes a fixed-price implementation

DeployOpen plans and implements self-hosted open-source platforms inside your own cloud accounts, data centers or air-gapped networks. For Azure DevOps cost comparisons, we start from a written scope that names the components in play, so the cost comparison is built from your actual seat counts, pipeline volume and retention needs.

How we scope

  • We inventory which Azure Repos, Boards, Pipelines and Artifacts components your teams use today, with seat and parallel job counts.
  • We record Artifacts storage volumes, Advanced Security usage and any Azure DevOps Server licensing that a comparison must cover.
  • Engagements are fixed-scope, so deliverables and timelines are agreed in writing before any implementation work starts.

How we build

  • We size the self-hosted GitLab, Gitea or Forgejo environment, including servers, storage, database and backup components.
  • We build the cost model by component so each line shows who pays for it, whether it is one-time or recurring, and what drives it.
  • We test migrations of sample repositories and pipelines in a non-production environment before any cut-over is planned.

How we hand over

  • We document the architecture, backup and restore procedures, upgrade path and the cost model so your staff can review them.
  • We provide a list of gaps, such as Boards or Test Plans functionality, so decisions are made with the trade-offs visible.
  • We prepare the controls and evidence your compliance assessors will need, while independent auditors issue any formal reports.

How we support

  • Ongoing support, upgrades and continuous testing are available as retainers after handover.
  • A retainer can cover platform upgrades along the vendor's documented upgrade path and periodic backup restore tests.
  • Ask for the support scope, response expectations and upgrade responsibilities to be written into the quote before you sign.

Sources and further reading

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.