[{"data":1,"prerenderedAt":1302},["ShallowReactive",2],{"/blog/git-fetch-performance":3,"navigation-en-us":514,"banner-en-us":942,"footer-en-us":952,"blog-post-authors-en-us-Jacob Vosmaer":1197,"blog-related-posts-en-us-git-fetch-performance":1212,"blog-promotions-en-us":1238,"next-steps-en-us":1292},{"id":4,"title":5,"authors":6,"body":8,"category":493,"date":494,"description":495,"extension":496,"externalUrl":497,"faq":497,"featured":498,"heroImage":499,"meta":500,"navigation":501,"path":502,"seo":503,"slug":507,"stem":508,"tags":509,"template":512,"updatedDate":497,"__hash__":513},"blogPosts/en-us/blog/git-fetch-performance.md","How we made Git fetch performance improvements in 2021, part 1",[7],"Jacob Vosmaer",{"type":9,"value":10,"toc":478},"minimark",[11,15,25,33,38,41,62,67,82,101,109,112,149,152,159,163,185,192,196,205,214,221,228,232,244,276,282,287,291,294,417,421,424,427,431,446,474],[12,13,14],"p",{},"In this post we look back on a series of projects from the Scalability\nteam that improved GitLab server-side efficiency for serving Git fetch\ntraffic. In the benchmark described below we saw a 9x reduction in\nGitLab server CPU utilization. Most of the performance comes from the\nGitaly pack-objects cache, which has proven very effective at reducing\nthe Gitaly server load caused by highly concurrent CI pipelines.",[12,16,17,18,24],{},"These changes are not user-visible but they benefit the stability and\navailability of GitLab.com. If you manage a GitLab instance\nyourself you may want to ",[19,20,23],"a",{"href":21,"rel":22},"https://docs.gitlab.com/administration/gitaly/configure_gitaly/#pack-objects-cache",[],"enable the pack-objects\ncache","\non your instance too.",[12,26,27,28,32],{},"We discuss how we achieved these improvements in ",[19,29,31],{"href":30},"/blog/git-fetch-performance-2021-part-2/","part 2",".",[34,35,37],"h2",{"id":36},"background","Background",[12,39,40],{},"Within the GitLab application, Gitaly is the component that acts as a\nremote procedure call (RPC) server for Git repositories. On\nGitLab.com, repositories are stored on persistent disks attached to\ndedicated Gitaly servers, and the rest of the application accesses\nrepositories by making RPC calls to Gitaly.",[12,42,43,44,49,50,58,59,61],{},"In 2020 we encountered several incidents on GitLab.com caused by the fact that\nour Gitaly server infrastructure ",[19,45,48],{"href":46,"rel":47},"https://gitlab.com/gitlab-com/gl-infra/production/-/issues/3013",[],"could not\nhandle","\nthe Git fetch traffic generated by CI on our own main repository,\n",[19,51,54],{"href":52,"rel":53},"https://gitlab.com/gitlab-org/gitlab",[],[55,56,57],"code",{},"gitlab-org/gitlab",". The only reason the situation at the time worked\nwas because we had a custom CI caching solution for\n",[55,60,57],{}," only, commonly referred to as the \"CI pre-clone\nscript\".",[63,64,66],"h3",{"id":65},"the-ci-pre-clone-script","The CI pre-clone script",[12,68,69,70,75,76,81],{},"The CI pre-clone script was an implementation of the ",[19,71,74],{"href":72,"rel":73},"https://www.kernel.org/best-way-to-do-linux-clones-for-your-ci.html",[],"clone bundle CI\nfetching\nstrategy",".\nWe had originally set up the CI pre-clone script one year earlier, in\n",[19,77,80],{"href":78,"rel":79},"https://gitlab.com/gitlab-org/gitlab/-/issues/39134",[],"December 2019",".\nIt consisted of two parts.",[83,84,85,92],"ol",{},[86,87,88,89,91],"li",{},"A CI cron job that would clone ",[55,90,57],{},", pack up the\nresult into a tarball, and upload it to a known Google Cloud\nStorage bucket.",[86,93,94,95,97,98,100],{},"A shell script snippet, stored in the ",[55,96,57],{}," project settings, that was\ninjected into each ",[55,99,57],{}," CI job. This shell script\nwould download and extract the latest tarball from the known URL.\nAfter that the CI job did an incremental Git fetch, relative to the\ntarball contents, to retrieve the actual CI pipeline commit.",[12,102,103,104,106,107,32],{},"This system was very effective. Our CI pipelines run against shallow\nGit clones of ",[55,105,57],{},", which require over 100MB of data to\nbe transfered per CI job. Because of the CI pre-clone script, the\namount of Git data per job was closer to 1MB. The rest of the data was\nalready there because of the tarball. The amount of repository data\ndownloaded by each CI job stayed the same, but only 1% of this data\nhad to come from a Gitaly server. This saved a lot of computation and\nbandwidth on the Gitaly server hosting ",[55,108,57],{},[12,110,111],{},"Although this solution worked well, it had a number of downsides.",[83,113,114,117,122,127,130,140,146],{},[86,115,116],{},"It was not part of the application and required per-project manual\nset-up and maintenance.",[86,118,119,120,32],{},"It did not work for forks of ",[55,121,57],{},[86,123,124,125,32],{},"It had to be maintained in two places: the project that created the\ntarball and the project settings of ",[55,126,57],{},[86,128,129],{},"We had no version control for the download script; this was just\ntext stored in the project's CI settings.",[86,131,132,133,136,137,139],{},"The download script was fragile. We had one case where we added an\n",[55,134,135],{},"exit"," statement in the wrong place, and all ",[55,138,57],{},"\nbuilds started silently using stale checkouts left behind by other\npipelines.",[86,141,142,143,145],{},"In case of a Google Cloud Storage outage, the full uncached traffic\nwould saturate the Gitaly server hosting ",[55,144,57],{},". Such\noutages are rare but they do happen.",[86,147,148],{},"A user who would want to copy our solution would have to set up\ntheir own Google Cloud Storage bucket and pay the bills for it.",[12,150,151],{},"The biggest issue really was that one year on, the CI pre-clone script\nhad not evolved from a custom one-off solution into an easy to use\nfeature for everyone.",[12,153,154,155,32],{},"We solved this problem by building the pack-objects cache, which we\nwill describe in more detail in the next blog post. Unlike the CI pre-clone script,\nwhich was a separate component, the pack-objects cache sits inside\nGitaly. It is always on, for all repositories and all users on\nGitLab.com. If you run your own GitLab server you can also use the\npack-objects cache, but you do have to ",[19,156,158],{"href":21,"rel":157},[],"turn it on\nfirst",[34,160,162],{"id":161},"performance-comparison","Performance comparison",[12,164,165,166,168,169,180,181,184],{},"To illustrate what has changed we have created a benchmark. We set up a GitLab\nserver with a clone of ",[55,167,57],{}," on it, and we configured a\nclient machine to perform 20 simultaneous shallow clones of the same commit using Git HTTP.",[170,171,172],"sup",{},[19,173,179],{"href":174,"ariaDescribedBy":175,"dataFootnoteRef":177,"id":178},"#user-content-fn-ssh",[176],"footnote-label","","user-content-fnref-ssh","1"," This\nsimulates having a CI pipeline with 20 parallel jobs. The pack data is\nabout 87MB so in terms of bandwidth, we are transferring ",[55,182,183],{},"20 * 87 = 1740MB"," of data.",[12,186,187,188,191],{},"We did this experiment with two GitLab servers. Both were Google\nCompute Engine ",[55,189,190],{},"c2-standard-8"," virtual machines with 8 CPU cores and\n32GB RAM. The operating system was Ubuntu 20.04 and we installed\nGitLab using our Omnibus packages.",[63,193,195],{"id":194},"before","Before",[197,198,199,202],"ul",{},[86,200,201],{},"GitLab FOSS 13.7.9 (released December 2020)",[86,203,204],{},"Default Omnibus configuration",[12,206,207,208,213],{},"The 30-second ",[19,209,212],{"href":210,"rel":211},"https://www.brendangregg.com/FlameGraphs/cpuflamegraphs.html",[],"Perf flamegraph"," below was captured at 99Hz across all CPU's.",[12,215,216],{},[217,218],"img",{"alt":219,"src":220},"Flamegraph of GitLab 13.7 performance","https://res.cloudinary.com/about-gitlab-com/image/upload/v1782398316/blog/Content%20Images/git-fetch-2021/before.jpg",[12,222,223,224],{},"Source: ",[19,225,227],{"href":220,"rel":226},[],"SVG",[63,229,231],{"id":230},"after","After",[197,233,234,237],{},[86,235,236],{},"GitLab FOSS 14.6.1 (released December 2021)",[86,238,239,240,243],{},"One extra setting in ",[55,241,242],{},"/etc/gitlab/gitlab.rb",":",[245,246,250],"pre",{"className":247,"code":248,"language":249,"meta":177,"style":177},"language-ruby shiki shiki-themes github-light","gitaly['pack_objects_cache_enabled'] = true\n","ruby",[55,251,252],{"__ignoreMap":177},[253,254,257,261,265,268,272],"span",{"class":255,"line":256},"line",1,[253,258,260],{"class":259},"sgsFI","gitaly[",[253,262,264],{"class":263},"sYBdl","'pack_objects_cache_enabled'",[253,266,267],{"class":259},"] ",[253,269,271],{"class":270},"sD7c4","=",[253,273,275],{"class":274},"sYu0t"," true\n",[12,277,278],{},[217,279],{"alt":280,"src":281},"Flamegraph of GitLab 14.6 performance with\ncache","https://res.cloudinary.com/about-gitlab-com/image/upload/v1782398315/blog/Content%20Images/git-fetch-2021/after.jpg",[12,283,223,284],{},[19,285,227],{"href":281,"rel":286},[],[63,288,290],{"id":289},"analysis","Analysis",[12,292,293],{},"Server CPU profile distribution:",[295,296,297,311],"table",{},[298,299,300],"thead",{},[301,302,303,307,309],"tr",{},[304,305,306],"th",{},"Value",[304,308,195],{},[304,310,231],{},[312,313,314,326,340,354,367,381,395,406],"tbody",{},[301,315,316,320,323],{},[317,318,319],"td",{},"Benchmark run time",[317,321,322],{},"27s",[317,324,325],{},"7.5s",[301,327,328,334,337],{},[317,329,330,333],{},[55,331,332],{},"git"," profile samples",[317,335,336],{},"18 552",[317,338,339],{},"923",[301,341,342,348,351],{},[317,343,344,347],{},[55,345,346],{},"gitaly"," samples (Git RPC server process)",[317,349,350],{},"1 247",[317,352,353],{},"331",[301,355,356,362,364],{},[317,357,358,361],{},[55,359,360],{},"gitaly-hooks"," samples (pack-objects cache client)",[317,363],{},[317,365,366],{},"258",[301,368,369,375,378],{},[317,370,371,374],{},[55,372,373],{},"gitlab-workhorse"," samples (application HTTP frontend)",[317,376,377],{},"1 057",[317,379,380],{},"237",[301,382,383,389,392],{},[317,384,385,388],{},[55,386,387],{},"nginx"," samples (main HTTP frontend)",[317,390,391],{},"474",[317,393,394],{},"251",[301,396,397,400,403],{},[317,398,399],{},"Total CPU busy samples",[317,401,402],{},"21 720",[317,404,405],{},"2 328",[301,407,408,411,414],{},[317,409,410],{},"CPU utilization during benchmark",[317,412,413],{},"100%",[317,415,416],{},"40%",[63,418,420],{"id":419},"conclusion","Conclusion",[12,422,423],{},"Compared to GitLab 13.6 (December 2020), GitLab 14.6 (December 2021) plus the\npack-objects cache makes the CI fetch benchmark in this post run 3.6x faster.\nAverage server CPU utilization during the benchmark dropped from 100%\nto 40%.",[12,425,426],{},"Stay tuned for part 2 of this blog post, in which we will go over the\nchanges we made to make this happen.",[34,428,430],{"id":429},"related-content","Related content",[197,432,433,439],{},[86,434,435],{},[19,436,438],{"href":21,"rel":437},[],"Gitaly pack-objects cache documentation",[86,440,441],{},[19,442,445],{"href":443,"rel":444},"https://gitlab.com/groups/gitlab-com/gl-infra/-/epics/652",[],"Epic to improve Git SSH efficiency in GitLab",[447,448,451,456],"section",{"className":449,"dataFootnotes":177},[450],"footnotes",[34,452,455],{"className":453,"id":176},[454],"sr-only","Footnotes",[83,457,458],{},[86,459,461,462,466,467],{"id":460},"user-content-fn-ssh","As of GitLab 14.6, Git HTTP is 3x more CPU-efficient on the server than Git SSH. We are working on ",[19,463,465],{"href":443,"rel":464},[],"improving the efficiency of Git SSH in GitLab",". We prioritized optimizing Git HTTP because that is what GitLab CI uses. ",[19,468,473],{"href":469,"ariaLabel":470,"className":471,"dataFootnoteBackref":177},"#user-content-fnref-ssh","Back to reference 1",[472],"data-footnote-backref","↩",[475,476,477],"style",{},"html pre.shiki code .sgsFI, html code.shiki .sgsFI{--shiki-default:#24292E}html pre.shiki code .sYBdl, html code.shiki .sYBdl{--shiki-default:#032F62}html pre.shiki code .sD7c4, html code.shiki .sD7c4{--shiki-default:#D73A49}html pre.shiki code .sYu0t, html code.shiki .sYu0t{--shiki-default:#005CC5}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":177,"searchDepth":479,"depth":479,"links":480},2,[481,485,491,492],{"id":36,"depth":479,"text":37,"children":482},[483],{"id":65,"depth":484,"text":66},3,{"id":161,"depth":479,"text":162,"children":486},[487,488,489,490],{"id":194,"depth":484,"text":195},{"id":230,"depth":484,"text":231},{"id":289,"depth":484,"text":290},{"id":419,"depth":484,"text":420},{"id":429,"depth":479,"text":430},{"id":176,"depth":479,"text":455},"engineering","2022-01-20","Our Scalability team tackled a server CPU utilization issue. Here's the first part of a detailed look at performance improvements we made for Git fetch.","md",null,false,"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749663397/Blog/Hero%20Images/logoforblogpost.jpg",{},true,"/en-us/blog/git-fetch-performance",{"title":5,"description":495,"ogTitle":5,"ogDescription":495,"noIndex":498,"ogImage":499,"ogUrl":504,"ogSiteName":505,"ogType":506,"canonicalUrls":504},"https://about.gitlab.com/blog/git-fetch-performance","https://about.gitlab.com","article","git-fetch-performance","en-us/blog/git-fetch-performance",[332,510,511],"production","performance","BlogPost","_74Mn-Eyp0M6_hyKj7LI0ZF6mUcdZCiYcAfDqhFCjq8",{"logo":515,"freeTrial":520,"sales":525,"login":530,"items":535,"search":862,"minimal":893,"duo":912,"switchNav":921,"pricingDeployment":932},{"config":516},{"href":517,"dataGaName":518,"dataGaLocation":519},"/","gitlab logo","header",{"text":521,"config":522},"Get free trial",{"href":523,"dataGaName":524,"dataGaLocation":519},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com&glm_content=default-saas-trial/","free trial",{"text":526,"config":527},"Request a demo",{"href":528,"dataGaName":529,"dataGaLocation":519},"/sales/?contact-topic=request-demo","sales",{"text":531,"config":532},"Sign in",{"href":533,"dataGaName":534,"dataGaLocation":519},"https://gitlab.com/users/sign_in/","sign in",[536,565,665,670,784,840],{"text":537,"config":538,"menu":540},"Platform",{"dataNavLevelOne":539},"platform",{"type":541,"columns":542},"cards",[543,549,557],{"title":537,"description":544,"link":545},"The intelligent orchestration platform for DevSecOps",{"text":546,"config":547},"Explore our Platform",{"href":548,"dataGaName":539,"dataGaLocation":519},"/platform/",{"title":550,"description":551,"link":552},"GitLab Duo Agent Platform","Agentic AI for the entire software lifecycle",{"text":553,"config":554},"Meet GitLab Duo",{"href":555,"dataGaName":556,"dataGaLocation":519},"/gitlab-duo-agent-platform/","gitlab duo agent platform",{"title":558,"description":559,"link":560},"Why GitLab","See the top reasons enterprises choose GitLab",{"text":561,"config":562},"Learn more",{"href":563,"dataGaName":564,"dataGaLocation":519},"/why-gitlab/","why gitlab",{"text":566,"left":501,"config":567,"menu":569},"Product",{"dataNavLevelOne":568},"solutions",{"type":570,"link":571,"columns":575,"feature":644},"lists",{"text":572,"config":573},"View all Solutions",{"href":574,"dataGaName":568,"dataGaLocation":519},"/solutions/",[576,600,623],{"title":577,"description":578,"link":579,"items":584},"Automation","CI/CD and automation to accelerate deployment",{"config":580},{"icon":581,"href":582,"dataGaName":583,"dataGaLocation":519},"AutomatedCodeAlt","/solutions/delivery-automation/","automated software delivery",[585,589,592,596],{"text":586,"config":587},"CI/CD",{"href":588,"dataGaLocation":519,"dataGaName":586},"/solutions/continuous-integration/",{"text":550,"config":590},{"href":555,"dataGaLocation":519,"dataGaName":591},"gitlab duo agent platform - product menu",{"text":593,"config":594},"Source Code Management",{"href":595,"dataGaLocation":519,"dataGaName":593},"/solutions/source-code-management/",{"text":597,"config":598},"Automated Software Delivery",{"href":582,"dataGaLocation":519,"dataGaName":599},"Automated software delivery",{"title":601,"description":602,"link":603,"items":608},"Security","Deliver code faster without compromising security",{"config":604},{"href":605,"dataGaName":606,"dataGaLocation":519,"icon":607},"/solutions/application-security-testing/","security and compliance","ShieldCheckLight",[609,613,618],{"text":610,"config":611},"Application Security Testing",{"href":605,"dataGaName":612,"dataGaLocation":519},"Application security testing",{"text":614,"config":615},"Software Supply Chain Security",{"href":616,"dataGaLocation":519,"dataGaName":617},"/solutions/supply-chain/","Software supply chain security",{"text":619,"config":620},"Software Compliance",{"href":621,"dataGaName":622,"dataGaLocation":519},"/solutions/software-compliance/","software compliance",{"title":624,"link":625,"items":630},"Measurement",{"config":626},{"icon":627,"href":628,"dataGaName":629,"dataGaLocation":519},"DigitalTransformation","/solutions/visibility-measurement/","visibility and measurement",[631,635,639],{"text":632,"config":633},"Visibility & Measurement",{"href":628,"dataGaLocation":519,"dataGaName":634},"Visibility and Measurement",{"text":636,"config":637},"Value Stream Management",{"href":638,"dataGaLocation":519,"dataGaName":636},"/solutions/value-stream-management/",{"text":640,"config":641},"Analytics & Insights",{"href":642,"dataGaLocation":519,"dataGaName":643},"/solutions/analytics-and-insights/","Analytics and insights",{"title":645,"type":570,"items":646},"GitLab for",[647,653,659],{"text":648,"config":649},"Enterprise",{"icon":650,"href":651,"dataGaLocation":519,"dataGaName":652},"Building","/enterprise/","enterprise",{"text":654,"config":655},"Small Business",{"icon":656,"href":657,"dataGaLocation":519,"dataGaName":658},"Work","/small-business/","small business",{"text":660,"config":661},"Public Sector",{"icon":662,"href":663,"dataGaLocation":519,"dataGaName":664},"Organization","/solutions/public-sector/","public sector",{"text":666,"config":667},"Pricing",{"href":668,"dataGaName":669,"dataGaLocation":519,"dataNavLevelOne":669},"/pricing/","pricing",{"text":671,"config":672,"menu":674},"Resources",{"dataNavLevelOne":673},"resources",{"type":570,"link":675,"columns":679,"feature":773},{"text":676,"config":677},"View all resources",{"href":678,"dataGaName":673,"dataGaLocation":519},"/resources/",[680,713,740],{"title":681,"items":682},"Getting started",[683,688,693,698,703,708],{"text":684,"config":685},"Install",{"href":686,"dataGaName":687,"dataGaLocation":519},"/install/","install",{"text":689,"config":690},"Quick start guides",{"href":691,"dataGaName":692,"dataGaLocation":519},"/get-started/","quick setup checklists",{"text":694,"config":695},"Learn",{"href":696,"dataGaLocation":519,"dataGaName":697},"https://university.gitlab.com/","learn",{"text":699,"config":700},"Product documentation",{"href":701,"dataGaName":702,"dataGaLocation":519},"https://docs.gitlab.com/","product documentation",{"text":704,"config":705},"Best practice videos",{"href":706,"dataGaName":707,"dataGaLocation":519},"/getting-started-videos/","best practice videos",{"text":709,"config":710},"Integrations",{"href":711,"dataGaName":712,"dataGaLocation":519},"/integrations/","integrations",{"title":714,"items":715},"Discover",[716,721,726,731,735],{"text":717,"config":718},"Customer success stories",{"href":719,"dataGaName":720,"dataGaLocation":519},"/customers/","customer success stories",{"text":722,"config":723},"Blog",{"href":724,"dataGaName":725,"dataGaLocation":519},"/blog/","blog",{"text":727,"config":728},"Demo Hub",{"href":729,"dataGaName":730,"dataGaLocation":519},"/demo-hub/","demo hub",{"text":732,"config":733},"The Source",{"href":734,"dataGaName":725,"dataGaLocation":519},"/the-source/",{"text":736,"config":737},"Remote",{"href":738,"dataGaName":739,"dataGaLocation":519},"https://handbook.gitlab.com/handbook/company/culture/all-remote/","remote",{"title":741,"items":742},"Connect",[743,748,753,758,763,768],{"text":744,"config":745},"GitLab Services",{"href":746,"dataGaName":747,"dataGaLocation":519},"/services/","services",{"text":749,"config":750},"Contribute",{"href":751,"dataGaName":752,"dataGaLocation":519},"https://contributors.gitlab.com","contribute",{"text":754,"config":755},"Community",{"href":756,"dataGaName":757,"dataGaLocation":519},"/community/","community",{"text":759,"config":760},"Forum",{"href":761,"dataGaName":762,"dataGaLocation":519},"https://forum.gitlab.com/","forum",{"text":764,"config":765},"Events",{"href":766,"dataGaName":767,"dataGaLocation":519},"/events/","events",{"text":769,"config":770},"Partners",{"href":771,"dataGaName":772,"dataGaLocation":519},"/partners/","partners",{"config":774,"title":777,"text":778,"link":779},{"background":775,"textColor":776},"url('https://res.cloudinary.com/about-gitlab-com/image/upload/v1777322348/qpq8yrgn8knii57omj0c.png')","#000","What’s new in GitLab","Stay updated with our latest features and improvements.",{"text":780,"config":781},"Read the latest",{"href":782,"dataGaName":783,"dataGaLocation":519},"/whats-new/","whats new",{"text":785,"config":786,"menu":788},"Company",{"dataNavLevelOne":787},"company",{"type":570,"columns":789},[790],{"items":791},[792,797,803,805,810,815,820,825,830,835],{"text":793,"config":794},"About",{"href":795,"dataGaName":796,"dataGaLocation":519},"/company/","about",{"text":798,"config":799,"footerGa":802},"Jobs",{"href":800,"dataGaName":801,"dataGaLocation":519},"/jobs/","jobs",{"dataGaName":801},{"text":764,"config":804},{"href":766,"dataGaName":767,"dataGaLocation":519},{"text":806,"config":807},"Leadership",{"href":808,"dataGaName":809,"dataGaLocation":519},"/company/team/e-group/","leadership",{"text":811,"config":812},"Handbook",{"href":813,"dataGaName":814,"dataGaLocation":519},"https://handbook.gitlab.com/","handbook",{"text":816,"config":817},"Investor relations",{"href":818,"dataGaName":819,"dataGaLocation":519},"https://ir.gitlab.com/overview/default.aspx","investor relations",{"text":821,"config":822},"Trust Center",{"href":823,"dataGaName":824,"dataGaLocation":519},"/security/","trust center",{"text":826,"config":827},"AI Transparency Center",{"href":828,"dataGaName":829,"dataGaLocation":519},"/ai-transparency-center/","ai transparency center",{"text":831,"config":832},"Newsletter",{"href":833,"dataGaName":834,"dataGaLocation":519},"/company/contact/#contact-forms","newsletter",{"text":836,"config":837},"Press",{"href":838,"dataGaName":839,"dataGaLocation":519},"/press/","press",{"text":841,"config":842,"menu":843},"Contact us",{"dataNavLevelOne":787},{"type":570,"columns":844},[845],{"items":846},[847,852,857],{"text":848,"config":849},"Talk to sales",{"href":850,"dataGaName":851,"dataGaLocation":519},"/sales/","talk to sales",{"text":853,"config":854},"Support portal",{"href":855,"dataGaName":856,"dataGaLocation":519},"https://support.gitlab.com/hc/en-us","support portal",{"text":858,"config":859},"Customer portal",{"href":860,"dataGaName":861,"dataGaLocation":519},"https://customers.gitlab.com/customers/sign_in/","customer portal",{"close":863,"login":864,"suggestions":871},"Close",{"text":865,"link":866},"To search repositories and projects, login to",{"text":867,"config":868},"gitlab.com",{"href":533,"dataGaName":869,"dataGaLocation":870},"search login","search",{"text":872,"default":873},"Suggestions",[874,876,880,882,886,890],{"text":550,"config":875},{"href":555,"dataGaName":550,"dataGaLocation":870},{"text":877,"config":878},"Code Suggestions (AI)",{"href":879,"dataGaName":877,"dataGaLocation":870},"/solutions/code-suggestions/",{"text":586,"config":881},{"href":588,"dataGaName":586,"dataGaLocation":870},{"text":883,"config":884},"GitLab on AWS",{"href":885,"dataGaName":883,"dataGaLocation":870},"/partners/technology-partners/aws/",{"text":887,"config":888},"GitLab on Google Cloud",{"href":889,"dataGaName":887,"dataGaLocation":870},"/partners/technology-partners/google-cloud-platform/",{"text":891,"config":892},"Why GitLab?",{"href":563,"dataGaName":891,"dataGaLocation":870},{"freeTrial":894,"mobileIcon":899,"desktopIcon":904,"secondaryButton":907},{"text":895,"config":896},"Start free trial",{"href":897,"dataGaName":524,"dataGaLocation":898},"https://gitlab.com/-/trials/new/","nav",{"altText":900,"config":901},"Gitlab Icon",{"src":902,"dataGaName":903,"dataGaLocation":898},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203874/jypbw1jx72aexsoohd7x.svg","gitlab icon",{"altText":900,"config":905},{"src":906,"dataGaName":903,"dataGaLocation":898},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203875/gs4c8p8opsgvflgkswz9.svg",{"text":908,"config":909},"Get Started",{"href":910,"dataGaName":911,"dataGaLocation":898},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/get-started/","get started",{"freeTrial":913,"mobileIcon":917,"desktopIcon":919},{"text":914,"config":915},"Learn more about GitLab Duo",{"href":555,"dataGaName":916,"dataGaLocation":898},"gitlab duo",{"altText":900,"config":918},{"src":902,"dataGaName":903,"dataGaLocation":898},{"altText":900,"config":920},{"src":906,"dataGaName":903,"dataGaLocation":898},{"button":922,"mobileIcon":927,"desktopIcon":929},{"text":923,"config":924},"/switch",{"href":925,"dataGaName":926,"dataGaLocation":898},"#contact","switch",{"altText":900,"config":928},{"src":902,"dataGaName":903,"dataGaLocation":898},{"altText":900,"config":930},{"src":931,"dataGaName":903,"dataGaLocation":898},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1773335277/ohhpiuoxoldryzrnhfrh.png",{"freeTrial":933,"mobileIcon":938,"desktopIcon":940},{"text":934,"config":935},"Back to pricing",{"href":668,"dataGaName":936,"dataGaLocation":898,"icon":937},"back to pricing","GoBack",{"altText":900,"config":939},{"src":902,"dataGaName":903,"dataGaLocation":898},{"altText":900,"config":941},{"src":906,"dataGaName":903,"dataGaLocation":898},{"title":943,"titleMobile":944,"button":945,"config":950},"Duo Agent Platform delivers 400% ROI, per new Forrester Consulting study.","400% ROI: Forrester TEI for GitLab Duo",{"text":561,"config":946},{"href":947,"dataGaName":948,"dataGaLocation":949},"https://about.gitlab.com/blog/gitlab-duo-agent-platform-delivers-400-percent-roi/","forrester-tei-dap-banner","global-banner",{"layout":951,"disabled":498},"release",{"data":953},{"text":954,"source":955,"edit":961,"contribute":966,"config":971,"items":976,"minimal":1186},"Git is a trademark of Software Freedom Conservancy and our use of 'GitLab' is under license",{"text":956,"config":957},"View page source",{"href":958,"dataGaName":959,"dataGaLocation":960},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/","page source","footer",{"text":962,"config":963},"Edit this page",{"href":964,"dataGaName":965,"dataGaLocation":960},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/content/","web ide",{"text":967,"config":968},"Please contribute",{"href":969,"dataGaName":970,"dataGaLocation":960},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/CONTRIBUTING.md/","please contribute",{"twitter":972,"facebook":973,"youtube":974,"linkedin":975},"https://twitter.com/gitlab","https://www.facebook.com/gitlab","https://www.youtube.com/channel/UCnMGQ8QHMAnVIsI3xJrihhg","https://www.linkedin.com/company/gitlab-com",[977,1024,1078,1122,1154],{"title":666,"links":978,"subMenu":993},[979,983,988],{"text":980,"config":981},"View plans",{"href":668,"dataGaName":982,"dataGaLocation":960},"view plans",{"text":984,"config":985},"Why Premium?",{"href":986,"dataGaName":987,"dataGaLocation":960},"/pricing/premium/","why premium",{"text":989,"config":990},"Why Ultimate?",{"href":991,"dataGaName":992,"dataGaLocation":960},"/pricing/ultimate/","why ultimate",[994],{"title":995,"links":996},"Contact Us",[997,1000,1002,1004,1009,1014,1019],{"text":998,"config":999},"Contact sales",{"href":850,"dataGaName":529,"dataGaLocation":960},{"text":853,"config":1001},{"href":855,"dataGaName":856,"dataGaLocation":960},{"text":858,"config":1003},{"href":860,"dataGaName":861,"dataGaLocation":960},{"text":1005,"config":1006},"Status",{"href":1007,"dataGaName":1008,"dataGaLocation":960},"https://status.gitlab.com/","status",{"text":1010,"config":1011},"Terms of use",{"href":1012,"dataGaName":1013,"dataGaLocation":960},"/terms/","terms of use",{"text":1015,"config":1016},"Privacy statement",{"href":1017,"dataGaName":1018,"dataGaLocation":960},"/privacy/","privacy statement",{"text":1020,"config":1021},"Cookie preferences",{"dataGaName":1022,"dataGaLocation":960,"id":1023,"isOneTrustButton":501},"cookie preferences","ot-sdk-btn",{"title":566,"links":1025,"subMenu":1034},[1026,1030],{"text":1027,"config":1028},"DevSecOps platform",{"href":548,"dataGaName":1029,"dataGaLocation":960},"devsecops platform",{"text":1031,"config":1032},"AI-Assisted Development",{"href":555,"dataGaName":1033,"dataGaLocation":960},"ai-assisted development",[1035],{"title":1036,"links":1037},"Topics",[1038,1043,1048,1053,1058,1063,1068,1073],{"text":1039,"config":1040},"CICD",{"href":1041,"dataGaName":1042,"dataGaLocation":960},"/topics/ci-cd/","cicd",{"text":1044,"config":1045},"GitOps",{"href":1046,"dataGaName":1047,"dataGaLocation":960},"/topics/gitops/","gitops",{"text":1049,"config":1050},"DevOps",{"href":1051,"dataGaName":1052,"dataGaLocation":960},"/topics/devops/","devops",{"text":1054,"config":1055},"Version Control",{"href":1056,"dataGaName":1057,"dataGaLocation":960},"/topics/version-control/","version control",{"text":1059,"config":1060},"DevSecOps",{"href":1061,"dataGaName":1062,"dataGaLocation":960},"/topics/devsecops/","devsecops",{"text":1064,"config":1065},"Cloud Native",{"href":1066,"dataGaName":1067,"dataGaLocation":960},"/topics/cloud-native/","cloud native",{"text":1069,"config":1070},"AI for Coding",{"href":1071,"dataGaName":1072,"dataGaLocation":960},"/topics/devops/ai-for-coding/","ai for coding",{"text":1074,"config":1075},"Agentic AI",{"href":1076,"dataGaName":1077,"dataGaLocation":960},"/topics/agentic-ai/","agentic ai",{"title":1079,"links":1080},"Solutions",[1081,1083,1085,1090,1094,1097,1101,1104,1106,1109,1112,1117],{"text":610,"config":1082},{"href":605,"dataGaName":610,"dataGaLocation":960},{"text":599,"config":1084},{"href":582,"dataGaName":583,"dataGaLocation":960},{"text":1086,"config":1087},"Agile development",{"href":1088,"dataGaName":1089,"dataGaLocation":960},"/solutions/agile-delivery/","agile delivery",{"text":1091,"config":1092},"SCM",{"href":595,"dataGaName":1093,"dataGaLocation":960},"source code management",{"text":1039,"config":1095},{"href":588,"dataGaName":1096,"dataGaLocation":960},"continuous integration & delivery",{"text":1098,"config":1099},"Value stream management",{"href":638,"dataGaName":1100,"dataGaLocation":960},"value stream management",{"text":1044,"config":1102},{"href":1103,"dataGaName":1047,"dataGaLocation":960},"/solutions/gitops/",{"text":648,"config":1105},{"href":651,"dataGaName":652,"dataGaLocation":960},{"text":1107,"config":1108},"Small business",{"href":657,"dataGaName":658,"dataGaLocation":960},{"text":1110,"config":1111},"Public sector",{"href":663,"dataGaName":664,"dataGaLocation":960},{"text":1113,"config":1114},"Education",{"href":1115,"dataGaName":1116,"dataGaLocation":960},"/solutions/education/","education",{"text":1118,"config":1119},"Financial services",{"href":1120,"dataGaName":1121,"dataGaLocation":960},"/solutions/finance/","financial services",{"title":671,"links":1123},[1124,1126,1128,1130,1133,1135,1138,1140,1142,1144,1146,1148,1150,1152],{"text":684,"config":1125},{"href":686,"dataGaName":687,"dataGaLocation":960},{"text":689,"config":1127},{"href":691,"dataGaName":692,"dataGaLocation":960},{"text":694,"config":1129},{"href":696,"dataGaName":697,"dataGaLocation":960},{"text":699,"config":1131},{"href":701,"dataGaName":1132,"dataGaLocation":960},"docs",{"text":722,"config":1134},{"href":724,"dataGaName":725,"dataGaLocation":960},{"text":1136,"config":1137},"What's new",{"href":782,"dataGaName":783,"dataGaLocation":960},{"text":717,"config":1139},{"href":719,"dataGaName":720,"dataGaLocation":960},{"text":736,"config":1141},{"href":738,"dataGaName":739,"dataGaLocation":960},{"text":744,"config":1143},{"href":746,"dataGaName":747,"dataGaLocation":960},{"text":749,"config":1145},{"href":751,"dataGaName":752,"dataGaLocation":960},{"text":754,"config":1147},{"href":756,"dataGaName":757,"dataGaLocation":960},{"text":759,"config":1149},{"href":761,"dataGaName":762,"dataGaLocation":960},{"text":764,"config":1151},{"href":766,"dataGaName":767,"dataGaLocation":960},{"text":769,"config":1153},{"href":771,"dataGaName":772,"dataGaLocation":960},{"title":785,"links":1155},[1156,1158,1160,1162,1164,1166,1170,1175,1177,1179,1181],{"text":793,"config":1157},{"href":795,"dataGaName":787,"dataGaLocation":960},{"text":798,"config":1159},{"href":800,"dataGaName":801,"dataGaLocation":960},{"text":806,"config":1161},{"href":808,"dataGaName":809,"dataGaLocation":960},{"text":811,"config":1163},{"href":813,"dataGaName":814,"dataGaLocation":960},{"text":816,"config":1165},{"href":818,"dataGaName":819,"dataGaLocation":960},{"text":1167,"config":1168},"Sustainability",{"href":1169,"dataGaName":1167,"dataGaLocation":960},"/sustainability/",{"text":1171,"config":1172},"Diversity, inclusion and belonging (DIB)",{"href":1173,"dataGaName":1174,"dataGaLocation":960},"/diversity-inclusion-belonging/","Diversity, inclusion and belonging",{"text":821,"config":1176},{"href":823,"dataGaName":824,"dataGaLocation":960},{"text":831,"config":1178},{"href":833,"dataGaName":834,"dataGaLocation":960},{"text":836,"config":1180},{"href":838,"dataGaName":839,"dataGaLocation":960},{"text":1182,"config":1183},"Modern Slavery Transparency Statement",{"href":1184,"dataGaName":1185,"dataGaLocation":960},"https://handbook.gitlab.com/handbook/legal/modern-slavery-act-transparency-statement/","modern slavery transparency statement",{"items":1187},[1188,1191,1194],{"text":1189,"config":1190},"Terms",{"href":1012,"dataGaName":1013,"dataGaLocation":960},{"text":1192,"config":1193},"Cookies",{"dataGaName":1022,"dataGaLocation":960,"id":1023,"isOneTrustButton":501},{"text":1195,"config":1196},"Privacy",{"href":1017,"dataGaName":1018,"dataGaLocation":960},[1198],{"id":1199,"title":7,"body":497,"config":1200,"content":1202,"description":497,"extension":1206,"meta":1207,"navigation":501,"path":1208,"seo":1209,"stem":1210,"__hash__":1211},"blogAuthors/en-us/blog/authors/jacob-vosmaer.yml",{"template":1201},"BlogAuthor",{"name":7,"config":1203},{"headshot":1204,"ctfId":1205},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749659488/Blog/Author%20Headshots/gitlab-logo-extra-whitespace.png","Jacob-Vosmaer","yml",{},"/en-us/blog/authors/jacob-vosmaer",{},"en-us/blog/authors/jacob-vosmaer","8CR6ShwBsKxqGM4AAocQnzaLp61rqybzr4XSir9Y3Ag",[1213,1222,1230],{"title":1214,"description":1215,"heroImage":1216,"category":493,"date":1217,"authors":1218,"slug":1221,"externalUrl":497},"Confidential AI for GitLab Self-Hosted","Give developers AI coding agents in GitLab Duo without source code leaving a hardware-encrypted boundary — no GPUs needed.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1773866173/vte9qh8rriznvyclhkes.png","2026-08-06",[1219,1220],"Mathias Ewald","Martin Paloncy, Edgeless Systems","confidential-ai-for-gitlab-self-hosted",{"title":1223,"description":1224,"heroImage":1225,"category":493,"date":1226,"authors":1227,"slug":1229,"externalUrl":497},"Green DevOps: Why carbon measurement belongs in your CI/CD pipeline","CI/CD pipelines have a hidden carbon cost. Here's why measuring it matters, and how you can get started with Eco CI and Carmen in GitLab.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1765809212/noh0mdfn9o94ry9ykura.png","2026-07-09",[1228],"Lysanne Pinto","green-devops-carbon-measurement-cicd-pipeline",{"title":1231,"description":1232,"heroImage":1233,"category":493,"date":1234,"authors":1235,"slug":1237,"externalUrl":497},"How to build CI/CD observability at scale","This practical guide to GitLab pipeline analytics helps self-managed users gain operational insights using Prometheus and Grafana.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1774465167/n5hlvrsrheadeccyr1oz.png","2026-04-28",[1236],"Paul Meresanu","how-to-build-ci-cd-observability-at-scale",{"promotions":1239},[1240,1254,1266,1278],{"id":1241,"categories":1242,"header":1244,"text":1245,"button":1246,"image":1251},"ai-modernization",[1243],"ai","Is AI achieving its promise at scale?","Quiz will take 5 minutes or less",{"text":1247,"config":1248},"Get your AI maturity score",{"href":1249,"dataGaName":1250,"dataGaLocation":725},"/assessments/ai-modernization-assessment/","modernization assessment",{"config":1252},{"src":1253},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/qix0m7kwnd8x2fh1zq49.png",{"id":1255,"categories":1256,"header":1258,"text":1245,"button":1259,"image":1263},"devops-modernization",[1257,1062],"product","Are you just managing tools or shipping innovation?",{"text":1260,"config":1261},"Get your DevOps maturity score",{"href":1262,"dataGaName":1250,"dataGaLocation":725},"/assessments/devops-modernization-assessment/",{"config":1264},{"src":1265},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138785/eg818fmakweyuznttgid.png",{"id":1267,"categories":1268,"header":1270,"text":1245,"button":1271,"image":1275},"security-modernization",[1269],"security","Are you trading speed for security?",{"text":1272,"config":1273},"Get your security maturity score",{"href":1274,"dataGaName":1250,"dataGaLocation":725},"/assessments/security-modernization-assessment/",{"config":1276},{"src":1277},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/p4pbqd9nnjejg5ds6mdk.png",{"id":1279,"paths":1280,"header":1283,"text":1284,"button":1285,"image":1290},"github-azure-migration",[1281,1282],"migration-from-azure-devops-to-gitlab","integrating-azure-devops-scm-and-gitlab","Is your team ready for GitHub's Azure move?","GitHub is already rebuilding around Azure. Find out what it means for you.",{"text":1286,"config":1287},"See how GitLab compares to GitHub",{"href":1288,"dataGaName":1289,"dataGaLocation":725},"/compare/gitlab-vs-github/github-azure-migration/","github azure migration",{"config":1291},{"src":1265},{"header":1293,"blurb":1294,"button":1295,"secondaryButton":1300},"Start building faster today","See what your team can do with the intelligent orchestration platform for DevSecOps.\n",{"text":1296,"config":1297},"Get your free trial",{"href":1298,"dataGaName":524,"dataGaLocation":1299},"https://gitlab.com/-/trial_registrations/new?glm_content=default-saas-trial&glm_source=about.gitlab.com/","feature",{"text":998,"config":1301},{"href":850,"dataGaName":529,"dataGaLocation":1299},1786803759772]