[{"data":1,"prerenderedAt":1254},["ShallowReactive",2],{"/blog/git-fetch-performance-2021-part-2":3,"navigation-en-us":466,"banner-en-us":894,"footer-en-us":904,"blog-post-authors-en-us-Jacob Vosmaer":1149,"blog-related-posts-en-us-git-fetch-performance-2021-part-2":1164,"blog-promotions-en-us":1190,"next-steps-en-us":1244},{"id":4,"title":5,"authors":6,"body":8,"category":444,"date":445,"description":446,"extension":447,"externalUrl":448,"faq":448,"featured":449,"heroImage":450,"meta":451,"navigation":452,"path":453,"seo":454,"slug":458,"stem":459,"tags":460,"template":464,"updatedDate":448,"__hash__":465},"blogPosts/en-us/blog/git-fetch-performance-2021-part-2.md","Git fetch performance improvements in 2021, Part 2 ",[7],"Jacob Vosmaer",{"type":9,"value":10,"toc":433},"minimark",[11,21,26,44,48,60,88,94,97,118,125,128,140,149,155,158,161,171,174,191,195,201,213,219,222,228,231,237,240,243,258,261,267,276,285,288,294,298,301,319,332,344,353,378,382,385,395,399,402,406],[12,13,14,15,20],"p",{},"In ",[16,17,19],"a",{"href":18},"/blog/git-fetch-performance/","Part 1"," of this two-part series, we looked at how much server-side Git fetch performance, especially for CI, has improved in GitLab in 2021. Now, we will discuss how we achieved this.",[22,23,25],"h2",{"id":24},"recap-of-part-1","Recap of Part 1",[27,28,29,38,41],"ul",{},[30,31,32,33,37],"li",{},"In December 2019, we set up custom CI fetch caching automation for\n",[34,35,36],"code",{},"gitlab-org/gitlab",", which we internally called \"the CI pre-clone\nscript\".",[30,39,40],{},"In December 2020, we encountered some production incidents on GitLab.com,\nwhich highlighted that the CI pre-clone script had become critical\ninfrastructure but, at the same time, it had not yet matured beyond\na custom one-off solution.",[30,42,43],{},"Over the course of 2021, we built an alternative caching solution\nfor CI Git fetch traffic called the pack-objects cache. In Part 1,\nwe discussed a benchmark simulating CI fetch traffic which shows\nthat the pack-objects cache combined with other efficiency\nimprovements reduced GitLab server CPU consumption 9x compared to\nthe baseline of December 2020.",[22,45,47],{"id":46},"the-pack-objects-cache","The pack-objects cache",[12,49,50,51,53,54,59],{},"As discussed in Part 1, what we realized through the\nproduction incidents in December 2020 was that the CI pre-clone script\nfor ",[34,52,36],{}," had become a critical piece of infrastructure.\nAt the same time, it benefited only one Git repository on GitLab.com,\nand it was not very robust. It would be much better to have an\nintegrated solution that benefits all repositories. We achieved this\ngoal by building the ",[16,55,58],{"href":56,"rel":57},"https://docs.gitlab.com/administration/gitaly/configure_gitaly/#pack-objects-cache",[],"pack-objects cache",".",[12,61,62,63,66,67,72,73,78,79,84,85,87],{},"The name \"pack-objects cache\" refers to ",[34,64,65],{},"git pack-objects",", which is\nthe Git ",[16,68,71],{"href":69,"rel":70},"https://git-scm.com/docs/git-pack-objects",[],"subcommand"," that\nimplements the ",[16,74,77],{"href":75,"rel":76},"https://git-scm.com/book/en/v2/Git-Internals-Packfiles",[],"packfile"," compression algorithm. As this ",[16,80,83],{"href":81,"rel":82},"https://gitlab.com/gitlab-org/gitlab-git/-/commit/20b20a22f8f7c1420e259c97ef790cb93091f475",[],"Git commit message from Jeff King"," explains, ",[34,86,65],{}," is a good candidate for a CI fetch cache.",[89,90,91],"blockquote",{},[12,92,93],{},"You may want to insert a caching layer around\npack-objects; it is the most CPU- and memory-intensive\npart of serving a fetch, and its output is a pure\nfunction of its input, making it an ideal place to\nconsolidate identical requests.",[12,95,96],{},"The pack-objects cache is GitLab's take on this \"caching layer\". It\ndeduplicates identical Git fetch requests that arrive within a short\ntime window.",[12,98,99,100,102,103,105,106,111,112,117],{},"At a high level, when serving a fetch, we buffer the output of ",[34,101,65],{}," into a temporary file. If an identical request comes in,\nwe serve it from the buffer file instead of creating a new ",[34,104,65],{}," process. After 5 minutes, we delete the buffer file. If\nyou want to know more about how exactly the cache is implemented, you\ncan look at the implementation\n(",[16,107,110],{"href":108,"rel":109},"https://gitlab.com/gitlab-org/gitaly/-/blob/v14.6.3/internal/gitaly/service/hook/pack_objects.go",[],"1",",\n",[16,113,116],{"href":114,"rel":115},"https://gitlab.com/gitlab-org/gitaly/-/tree/v14.6.3/internal/streamcache",[],"2",").",[12,119,120],{},[121,122],"img",{"alt":123,"src":124},"Architecture diagram","https://res.cloudinary.com/about-gitlab-com/image/upload/v1782398319/blog/Content%20Images/git-fetch-2021/pack-objects-cache-architecture.jpg",[12,126,127],{},"Because the amount of space used by the cache files is bounded roughly\nby the eviction window (5 minutes) multiplied by the maximum network bandwidth\nof the Gitaly server, we don't have to worry about the cache using a\nlot of storage. In fact, on GitLab.com, we store the cache files on the\nsame disks that hold the repository data. We leave a safety margin of\nfree space on these disks at all times anyway, and the cache fits in\nthat safety margin comfortably.",[12,129,130,131,135,136,139],{},"Similarly, we also don't notice the increase disk input/output\noperations per second (IOPS) used by the cache on GitLab.com. There\nare two reasons for this. First of all, whenever we ",[132,133,134],"em",{},"read"," data from\nthe cache, it is usually still in the Linux page cache, so it gets\nserved from RAM. The cache barely does any disk read I/O operations.\nSecond, although the cache does do ",[132,137,138],{},"write"," operations, these fit\ncomfortably within the maximum sustained IOPS rate supported by the\nGoogle Compute Engine persistent disks we use.",[12,141,142,143,148],{},"This leads us to a disadvantage of the pack-objects cache, which is\nthat it really does write a lot of data to disk. On GitLab.com, we saw\nthe disk write throughput jump up by an order of magnitude. You can\nsee this in the graph below, which shows disk writes for a single\nGitaly server with a busy, large repository on it: (the GitLab ",[16,144,147],{"href":145,"rel":146},"https://gitlab.com/gitlab-com/www-gitlab-com",[],"company\nwebsite","). You can\nclearly see the number of bytes written to disk per second jump up when we\nturned the cache on.",[12,150,151],{},[121,152],{"alt":153,"src":154},"increased disk writes with cache enabled","https://res.cloudinary.com/about-gitlab-com/image/upload/v1782398317/blog/Content%20Images/git-fetch-2021/cache-disk-writes.jpg",[12,156,157],{},"This increase in disk writes is not a problem for our infrastructure because we have the\nspare capacity, but we were not sure we could assume the same for all\nother GitLab installations in the world. Because of this, we decided\nto leave the pack-objects cache off by default.",[12,159,160],{},"This was a difficult decision because we think almost all GitLab\ninstallations would benefit from having this cache enabled. One of the\nreasons we are writing this blog post is to raise awareness that this\nfeature is available, so that self-managed GitLab administrators can\nopt in to using it.",[12,162,163,164,167,168,170],{},"Again, on the positive side, the cache did not introduce a new\npoint of failure on GitLab.com. If the ",[34,165,166],{},"gitaly"," service is running,\nand if the repository storage disk is available, then the cache is\navailable. There are no external dependencies. And if ",[34,169,166],{}," is not\nrunning, or the repository storage disk is unavailable, then the whole\nGitaly server is unavailable anyway.",[12,172,173],{},"And finally, cache capacity grows naturally with the number of Gitaly\nservers. Because the cache is completely local to each Gitaly server,\nwe do not have to worry about whether the cache keeps working as we\ngrow GitLab.com.",[12,175,176,177,111,181,185,186,190],{},"The pack-objects cache was introduced in GitLab 13.11. In GitLab 14.5,\nwe made it a lot more efficient by optimizing its transport using Unix\nsockets\n(",[16,178,110],{"href":179,"rel":180},"https://gitlab.com/gitlab-org/gitaly/-/merge_requests/3758",[],[16,182,116],{"href":183,"rel":184},"https://gitlab.com/gitlab-org/gitaly/-/merge_requests/3759",[],"). If\nyou want to ",[16,187,189],{"href":56,"rel":188},[],"try out the pack-objects cache"," on\nyour self-managed GitLab instance, we recommend that you upgrade to\nGitLab 14.5 or newer first.",[22,192,194],{"id":193},"improved-rpc-transport-for-git-http","Improved RPC transport for Git HTTP",[12,196,197,198,200],{},"After we built the pack-objects cache, we were able to generate a much\nhigher volume of Git fetch responses on a single Gitaly server.\nHowever, we then found out that the RPC transport between the HTTP\nfront-end (GitLab Workhorse) and the Gitaly server became a\nbottleneck. We tried disabling the CI pre-clone script of\n",[34,199,36],{}," in April 2021 but we quickly had to turn it back\non because the increased volume of Git fetch data transfer was slowing\ndown the rest of Gitaly.",[12,202,203,204,206,207,212],{},"The fetch traffic was acting as a noisy neighbor to all the other\ntraffic on ",[34,205,36],{},". For each GitLab.com Gitaly server, we\nhave a request latency\n",[16,208,211],{"href":209,"rel":210},"https://sre.google/sre-book/service-level-objectives/",[],"SLI",". This is\na metric that observes request latencies for a selection of RPCs that\nwe expect to be fast, and it tracks how many requests for these RPCs\nare \"fast enough\". If the percentage of fast-enough requests drops\nbelow a certain threshold, we know we have a problem.",[12,214,215,216,218],{},"When we disabled the pre-clone script, the network traffic to the\nGitaly server hosting ",[34,217,36],{}," went up, as expected. What\nwent wrong was that the percentage of fast-enough requests started to\ndrop. This was not because the server had to serve up more data: The\nRPCs that serve the Git fetch data do not count towards the latency\nSLI.",[12,220,221],{},"Below you see two graphs from the day we tried disabling the CI\npre-clone script. First, see how the network traffic off of the Gitaly\nserver increased once we disabled the CI pre-clone script. This is\nbecause instead of pulling most of the data from object storage, and\nonly some of the data from Gitaly, the CI runners now started pulling\nall of the Git data they needed from Gitaly.",[12,223,224],{},[121,225],{"alt":226,"src":227},"network peaks","https://res.cloudinary.com/about-gitlab-com/image/upload/v1782398318/blog/Content%20Images/git-fetch-2021/no-script-network-annotated.png",[12,229,230],{},"Now consider our Gitaly request latency SLI for this particular\nserver. For historical reasons, we call this \"Apdex\" in our dashboards.\nRecall that this SLI tracks the percentage of fast-enough requests from\na selection of Gitaly RPCs. The ideal number would be 100%. In the\ntime window where the CI pre-clone script was disabled, this graph\nspent more time below 99%, and it even dipped below 96% several times.",[12,232,233],{},[121,234],{"alt":235,"src":236},"latency drops","https://res.cloudinary.com/about-gitlab-com/image/upload/v1782398318/blog/Content%20Images/git-fetch-2021/no-script-latency-annotated.png",[12,238,239],{},"Even though we could not explain what was going on, the latency SLI dips\nwere clear evidence that disabling the CI pre-clone script slowed down\nunrelated requests to this Gitaly server, to a point which is\nunacceptable. This was a setback for our plan to replace the CI pre-clone script.",[12,241,242],{},"Because we did not want to just give up, we set aside some time to try\nand understand what the bottleneck was, and if it could be\ncircumvented. The bad news is that we did not come up with a\nsatisfactory answer about what the bottleneck is. But the good news is\nthat we were able to circumvent it.",[12,244,245,246,251,252,257],{},"By building a simplified ",[16,247,250],{"href":248,"rel":249},"https://gitlab.com/gitlab-com/gl-infra/scalability/-/issues/1046",[],"prototype alternate RPC\ntransport",",\nwe were able to find out that with the pack-objects cache, the\nhardware we run on and Git itself were able to serve up much more\ntraffic than we were able to get out of GitLab. We ",[16,253,256],{"href":254,"rel":255},"https://gitlab.com/gitlab-com/gl-infra/scalability/-/issues/1024",[],"never got to the\nbottom","\nof what was causing all the overhead but a likely suspect is the fact\nthat gRPC-Go allocates memory for each message it sends, and with Git\nfetch traffic we send a lot of messages. Gitaly was spending a lot of\ntime doing garbage collection.",[12,259,260],{},"We then had to decide how to improve the situation. Because we were\nuncertain if we could fix the apparent bottleneck in gRPC, and because\nwe were certain that we could go faster by not sending the Git fetch data\nthrough gRPC in the first place, we chose to do the latter. We created\nmodified versions of the RPCs that carry the bulk of the Git fetch\ndata. On the surface, the new versions are still gRPC methods. But\nduring a call, each will establish a side channel, and use that for\nthe bulk data transfer.",[12,262,263],{},[121,264],{"alt":265,"src":266},"side channel diagram","https://res.cloudinary.com/about-gitlab-com/image/upload/v1782398319/blog/Content%20Images/git-fetch-2021/sidechannel.png",[12,268,269,270,275],{},"This way we avoided making major changes to the structure of Gitaly:\nit is still a gRPC server application. Logging, metrics,\nauthentication, and other middleware work as normal on the optimized\nRPCs. But most of the data transfer happens on either Unix sockets (for localhost RPC calls) or ",[16,271,274],{"href":272,"rel":273},"https://github.com/hashicorp/yamux/",[],"Yamux streams"," (for the regular RPC calls).",[12,277,278,279,284],{},"Because we have 6x more Git HTTP traffic than Git SSH traffic on\nGitLab.com, we decided to initially only optimize the transport for\nGit HTTP traffic. We are still working on ",[16,280,283],{"href":281,"rel":282},"https://gitlab.com/groups/gitlab-com/gl-infra/-/epics/652",[],"doing the same for Git\nSSH"," because, even though Git HTTP efficiency is more important for\nGitLab.com than that of Git SSH, we know that for some self-managed\nGitLab instances it is the other way around.",[12,286,287],{},"The new server-side RPC transport for Git HTTP was released in GitLab\n14.5. There is no configuration required for this improved transport.\nRegardless of whether you use the pack-objects cache on your GitLab\ninstance, Gitaly, Workhorse, and Praefect all use less CPU to handle\nGit HTTP fetch requests now.",[12,289,290,291,293],{},"The payoff for this work came in October 2021 when we disabled the CI\npre-clone script for ",[34,292,36],{},", which did not cause any\nnoisy neighbor problems this time. We have had no issues since then\nserving the Git fetch traffic for that project.",[22,295,297],{"id":296},"improvements-to-git-itself","Improvements to Git itself",[12,299,300],{},"Aside from the pack-objects cache and the new RPC transport between\nWorkhorse and Gitaly, we also saw some improvements because of changes\nin Git itself. We discovered a few inefficiencies which we\nreported to the Git mailing list and helped get fixed.",[12,302,303,304,306,307,312,313,318],{},"Our main repository ",[34,305,36],{}," has hundreds of thousands of ",[16,308,311],{"href":309,"rel":310},"https://git-scm.com/book/en/v2/Git-Internals-Git-References",[],"Git\nreferences",". Looking at CPU profiles, we ",[16,314,317],{"href":315,"rel":316},"https://gitlab.com/groups/gitlab-com/gl-infra/-/epics/400",[],"noticed"," that a lot of Git\nfetch time was spent on the server iterating over these references.\nThese references were not even being sent back to the client; Git was\njust scanning through all of them on the server twice for each CI job.",[12,320,321,322,326,327,331],{},"In both cases, the problem could be fixed by doing a scan over a\nsubset instead of a scan across all references. These two problems got fixed\n(",[16,323,110],{"href":324,"rel":325},"https://gitlab.com/gitlab-org/gitlab-git/-/commit/b3970c702cb0acc0551d88a5f34ad4ad2e2a6d39",[],", ",[16,328,116],{"href":329,"rel":330},"https://gitlab.com/gitlab-org/gitlab-git/-/commit/be18153b975844f8792b03e337f1a4c86fe87531",[],") in Git 2.31.0, released in March 2021.",[12,333,334,335,337,338,343],{},"Later on, we found a different problem, also in the reference-related\nworkload of Git fetch. As part of the fetch protocol, the server sends\na list of references to the client so that the client can update its\nlocal branches etc. It turned out that for each reference, Git was\ndoing 1 or 2 ",[34,336,138],{}," system calls on the server. This led to ",[16,339,342],{"href":340,"rel":341},"https://gitlab.com/gitlab-com/gl-infra/scalability/-/issues/1257",[],"a lot of\noverhead",", and this was made worse by our old RPC transport which could\nend up sending 1 RPC message per advertised Git reference.",[12,345,346,347,352],{},"This problem got fixed in Git itself by changing the functions that\nwrite the references to ",[16,348,351],{"href":349,"rel":350},"https://gitlab.com/gitlab-org/gitlab-git/-/commit/70afef5cdf29b5159f18df1b93722055f78740f8",[],"use buffered\nIO",".\nThis change landed in Git 2.34.0, released in November 2021. Ahead of\nthat, it got shipped in GitLab 14.4 as a custom Git patch.",[12,354,355,356,359,360,362,363,365,366,371,372,377],{},"Finally, we discovered that increasing the copy buffer size used by\n",[34,357,358],{},"git upload-pack"," to relay ",[34,361,65],{}," output made both ",[34,364,358],{}," and ",[16,367,370],{"href":368,"rel":369},"https://gitlab.com/gitlab-org/gitaly/-/merge_requests/4224",[],"every link in the chain after\nit"," more\nefficient. This got fixed in Git by ",[16,373,376],{"href":374,"rel":375},"https://gitlab.com/gitlab-org/gitlab-git/-/commit/55a9651d26a6b88c68445e7d6c9f511d1207cbd8",[],"increasing the buffer\nsize",".\nThis change is part of Git 2.35.0 and is included in GitLab 14.7, both\nof which were released in January 2022.",[22,379,381],{"id":380},"summary","Summary",[12,383,384],{},"In Part 1, we showed that GitLab server performance when service CI Git fetch traffic has improved a lot in 2021. In this post, we explained that the improvements are due to:",[27,386,387,389,392],{},[30,388,47],{},[30,390,391],{},"A more efficient Git data transport between server-side GitLab components",[30,393,394],{},"Efficiency improvements in Git itself",[22,396,398],{"id":397},"thanks","Thanks",[12,400,401],{},"Many people have contributed to the work described in this blog post.\nI would like to specifically thank Quang-Minh Nguyen and Sean McGivern\nfrom the Scalability team, and Patrick Steinhardt and Sami Hiltunen\nfrom the Gitaly team.",[22,403,405],{"id":404},"related-content","Related content",[27,407,408,425],{},[30,409,410,411,414,415,326,420],{},"Improvements to the client-side performance of ",[34,412,413],{},"git fetch"," (although GitLab is a server application, it sometimes acts as a Git client): ",[16,416,419],{"href":417,"rel":418},"https://gitlab.com/gitlab-org/git/-/issues/95",[],"mirror fetches",[16,421,424],{"href":422,"rel":423},"https://gitlab.com/gitlab-org/git/-/issues/94",[],"fetches into repositories with many references",[30,426,427,428],{},"Improvements to server-side Git push performance: ",[16,429,432],{"href":430,"rel":431},"https://gitlab.com/gitlab-org/git/-/issues/92",[],"consistency check improvements",{"title":434,"searchDepth":435,"depth":435,"links":436},"",2,[437,438,439,440,441,442,443],{"id":24,"depth":435,"text":25},{"id":46,"depth":435,"text":47},{"id":193,"depth":435,"text":194},{"id":296,"depth":435,"text":297},{"id":380,"depth":435,"text":381},{"id":397,"depth":435,"text":398},{"id":404,"depth":435,"text":405},"engineering","2022-02-07","Looking back at the server-side performance improvements we made in 2021 for Git fetch.","md",null,false,"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749663383/Blog/Hero%20Images/tanuki-bg-full.png",{},true,"/en-us/blog/git-fetch-performance-2021-part-2",{"title":5,"description":446,"ogTitle":5,"ogDescription":446,"noIndex":449,"ogImage":450,"ogUrl":455,"ogSiteName":456,"ogType":457,"canonicalUrls":455},"https://about.gitlab.com/blog/git-fetch-performance-2021-part-2","https://about.gitlab.com","article","git-fetch-performance-2021-part-2","en-us/blog/git-fetch-performance-2021-part-2",[461,462,463],"git","production","performance","BlogPost","zp9m0asKsSViP1eQILg95axxIHyMvhsNLxqrveQkZ2c",{"logo":467,"freeTrial":472,"sales":477,"login":482,"items":487,"search":814,"minimal":845,"duo":864,"switchNav":873,"pricingDeployment":884},{"config":468},{"href":469,"dataGaName":470,"dataGaLocation":471},"/","gitlab logo","header",{"text":473,"config":474},"Get free trial",{"href":475,"dataGaName":476,"dataGaLocation":471},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com&glm_content=default-saas-trial/","free trial",{"text":478,"config":479},"Request a demo",{"href":480,"dataGaName":481,"dataGaLocation":471},"/sales/?contact-topic=request-demo","sales",{"text":483,"config":484},"Sign in",{"href":485,"dataGaName":486,"dataGaLocation":471},"https://gitlab.com/users/sign_in/","sign in",[488,517,617,622,736,792],{"text":489,"config":490,"menu":492},"Platform",{"dataNavLevelOne":491},"platform",{"type":493,"columns":494},"cards",[495,501,509],{"title":489,"description":496,"link":497},"The intelligent orchestration platform for DevSecOps",{"text":498,"config":499},"Explore our Platform",{"href":500,"dataGaName":491,"dataGaLocation":471},"/platform/",{"title":502,"description":503,"link":504},"GitLab Duo Agent Platform","Agentic AI for the entire software lifecycle",{"text":505,"config":506},"Meet GitLab Duo",{"href":507,"dataGaName":508,"dataGaLocation":471},"/gitlab-duo-agent-platform/","gitlab duo agent platform",{"title":510,"description":511,"link":512},"Why GitLab","See the top reasons enterprises choose GitLab",{"text":513,"config":514},"Learn more",{"href":515,"dataGaName":516,"dataGaLocation":471},"/why-gitlab/","why gitlab",{"text":518,"left":452,"config":519,"menu":521},"Product",{"dataNavLevelOne":520},"solutions",{"type":522,"link":523,"columns":527,"feature":596},"lists",{"text":524,"config":525},"View all Solutions",{"href":526,"dataGaName":520,"dataGaLocation":471},"/solutions/",[528,552,575],{"title":529,"description":530,"link":531,"items":536},"Automation","CI/CD and automation to accelerate deployment",{"config":532},{"icon":533,"href":534,"dataGaName":535,"dataGaLocation":471},"AutomatedCodeAlt","/solutions/delivery-automation/","automated software delivery",[537,541,544,548],{"text":538,"config":539},"CI/CD",{"href":540,"dataGaLocation":471,"dataGaName":538},"/solutions/continuous-integration/",{"text":502,"config":542},{"href":507,"dataGaLocation":471,"dataGaName":543},"gitlab duo agent platform - product menu",{"text":545,"config":546},"Source Code Management",{"href":547,"dataGaLocation":471,"dataGaName":545},"/solutions/source-code-management/",{"text":549,"config":550},"Automated Software Delivery",{"href":534,"dataGaLocation":471,"dataGaName":551},"Automated software delivery",{"title":553,"description":554,"link":555,"items":560},"Security","Deliver code faster without compromising security",{"config":556},{"href":557,"dataGaName":558,"dataGaLocation":471,"icon":559},"/solutions/application-security-testing/","security and compliance","ShieldCheckLight",[561,565,570],{"text":562,"config":563},"Application Security Testing",{"href":557,"dataGaName":564,"dataGaLocation":471},"Application security testing",{"text":566,"config":567},"Software Supply Chain Security",{"href":568,"dataGaLocation":471,"dataGaName":569},"/solutions/supply-chain/","Software supply chain security",{"text":571,"config":572},"Software Compliance",{"href":573,"dataGaName":574,"dataGaLocation":471},"/solutions/software-compliance/","software compliance",{"title":576,"link":577,"items":582},"Measurement",{"config":578},{"icon":579,"href":580,"dataGaName":581,"dataGaLocation":471},"DigitalTransformation","/solutions/visibility-measurement/","visibility and measurement",[583,587,591],{"text":584,"config":585},"Visibility & Measurement",{"href":580,"dataGaLocation":471,"dataGaName":586},"Visibility and Measurement",{"text":588,"config":589},"Value Stream Management",{"href":590,"dataGaLocation":471,"dataGaName":588},"/solutions/value-stream-management/",{"text":592,"config":593},"Analytics & Insights",{"href":594,"dataGaLocation":471,"dataGaName":595},"/solutions/analytics-and-insights/","Analytics and insights",{"title":597,"type":522,"items":598},"GitLab for",[599,605,611],{"text":600,"config":601},"Enterprise",{"icon":602,"href":603,"dataGaLocation":471,"dataGaName":604},"Building","/enterprise/","enterprise",{"text":606,"config":607},"Small Business",{"icon":608,"href":609,"dataGaLocation":471,"dataGaName":610},"Work","/small-business/","small business",{"text":612,"config":613},"Public Sector",{"icon":614,"href":615,"dataGaLocation":471,"dataGaName":616},"Organization","/solutions/public-sector/","public sector",{"text":618,"config":619},"Pricing",{"href":620,"dataGaName":621,"dataGaLocation":471,"dataNavLevelOne":621},"/pricing/","pricing",{"text":623,"config":624,"menu":626},"Resources",{"dataNavLevelOne":625},"resources",{"type":522,"link":627,"columns":631,"feature":725},{"text":628,"config":629},"View all resources",{"href":630,"dataGaName":625,"dataGaLocation":471},"/resources/",[632,665,692],{"title":633,"items":634},"Getting started",[635,640,645,650,655,660],{"text":636,"config":637},"Install",{"href":638,"dataGaName":639,"dataGaLocation":471},"/install/","install",{"text":641,"config":642},"Quick start guides",{"href":643,"dataGaName":644,"dataGaLocation":471},"/get-started/","quick setup checklists",{"text":646,"config":647},"Learn",{"href":648,"dataGaLocation":471,"dataGaName":649},"https://university.gitlab.com/","learn",{"text":651,"config":652},"Product documentation",{"href":653,"dataGaName":654,"dataGaLocation":471},"https://docs.gitlab.com/","product documentation",{"text":656,"config":657},"Best practice videos",{"href":658,"dataGaName":659,"dataGaLocation":471},"/getting-started-videos/","best practice videos",{"text":661,"config":662},"Integrations",{"href":663,"dataGaName":664,"dataGaLocation":471},"/integrations/","integrations",{"title":666,"items":667},"Discover",[668,673,678,683,687],{"text":669,"config":670},"Customer success stories",{"href":671,"dataGaName":672,"dataGaLocation":471},"/customers/","customer success stories",{"text":674,"config":675},"Blog",{"href":676,"dataGaName":677,"dataGaLocation":471},"/blog/","blog",{"text":679,"config":680},"Demo Hub",{"href":681,"dataGaName":682,"dataGaLocation":471},"/demo-hub/","demo hub",{"text":684,"config":685},"The Source",{"href":686,"dataGaName":677,"dataGaLocation":471},"/the-source/",{"text":688,"config":689},"Remote",{"href":690,"dataGaName":691,"dataGaLocation":471},"https://handbook.gitlab.com/handbook/company/culture/all-remote/","remote",{"title":693,"items":694},"Connect",[695,700,705,710,715,720],{"text":696,"config":697},"GitLab Services",{"href":698,"dataGaName":699,"dataGaLocation":471},"/services/","services",{"text":701,"config":702},"Contribute",{"href":703,"dataGaName":704,"dataGaLocation":471},"https://contributors.gitlab.com","contribute",{"text":706,"config":707},"Community",{"href":708,"dataGaName":709,"dataGaLocation":471},"/community/","community",{"text":711,"config":712},"Forum",{"href":713,"dataGaName":714,"dataGaLocation":471},"https://forum.gitlab.com/","forum",{"text":716,"config":717},"Events",{"href":718,"dataGaName":719,"dataGaLocation":471},"/events/","events",{"text":721,"config":722},"Partners",{"href":723,"dataGaName":724,"dataGaLocation":471},"/partners/","partners",{"config":726,"title":729,"text":730,"link":731},{"background":727,"textColor":728},"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":732,"config":733},"Read the latest",{"href":734,"dataGaName":735,"dataGaLocation":471},"/whats-new/","whats new",{"text":737,"config":738,"menu":740},"Company",{"dataNavLevelOne":739},"company",{"type":522,"columns":741},[742],{"items":743},[744,749,755,757,762,767,772,777,782,787],{"text":745,"config":746},"About",{"href":747,"dataGaName":748,"dataGaLocation":471},"/company/","about",{"text":750,"config":751,"footerGa":754},"Jobs",{"href":752,"dataGaName":753,"dataGaLocation":471},"/jobs/","jobs",{"dataGaName":753},{"text":716,"config":756},{"href":718,"dataGaName":719,"dataGaLocation":471},{"text":758,"config":759},"Leadership",{"href":760,"dataGaName":761,"dataGaLocation":471},"/company/team/e-group/","leadership",{"text":763,"config":764},"Handbook",{"href":765,"dataGaName":766,"dataGaLocation":471},"https://handbook.gitlab.com/","handbook",{"text":768,"config":769},"Investor relations",{"href":770,"dataGaName":771,"dataGaLocation":471},"https://ir.gitlab.com/overview/default.aspx","investor relations",{"text":773,"config":774},"Trust Center",{"href":775,"dataGaName":776,"dataGaLocation":471},"/security/","trust center",{"text":778,"config":779},"AI Transparency Center",{"href":780,"dataGaName":781,"dataGaLocation":471},"/ai-transparency-center/","ai transparency center",{"text":783,"config":784},"Newsletter",{"href":785,"dataGaName":786,"dataGaLocation":471},"/company/contact/#contact-forms","newsletter",{"text":788,"config":789},"Press",{"href":790,"dataGaName":791,"dataGaLocation":471},"/press/","press",{"text":793,"config":794,"menu":795},"Contact us",{"dataNavLevelOne":739},{"type":522,"columns":796},[797],{"items":798},[799,804,809],{"text":800,"config":801},"Talk to sales",{"href":802,"dataGaName":803,"dataGaLocation":471},"/sales/","talk to sales",{"text":805,"config":806},"Support portal",{"href":807,"dataGaName":808,"dataGaLocation":471},"https://support.gitlab.com/hc/en-us","support portal",{"text":810,"config":811},"Customer portal",{"href":812,"dataGaName":813,"dataGaLocation":471},"https://customers.gitlab.com/customers/sign_in/","customer portal",{"close":815,"login":816,"suggestions":823},"Close",{"text":817,"link":818},"To search repositories and projects, login to",{"text":819,"config":820},"gitlab.com",{"href":485,"dataGaName":821,"dataGaLocation":822},"search login","search",{"text":824,"default":825},"Suggestions",[826,828,832,834,838,842],{"text":502,"config":827},{"href":507,"dataGaName":502,"dataGaLocation":822},{"text":829,"config":830},"Code Suggestions (AI)",{"href":831,"dataGaName":829,"dataGaLocation":822},"/solutions/code-suggestions/",{"text":538,"config":833},{"href":540,"dataGaName":538,"dataGaLocation":822},{"text":835,"config":836},"GitLab on AWS",{"href":837,"dataGaName":835,"dataGaLocation":822},"/partners/technology-partners/aws/",{"text":839,"config":840},"GitLab on Google Cloud",{"href":841,"dataGaName":839,"dataGaLocation":822},"/partners/technology-partners/google-cloud-platform/",{"text":843,"config":844},"Why GitLab?",{"href":515,"dataGaName":843,"dataGaLocation":822},{"freeTrial":846,"mobileIcon":851,"desktopIcon":856,"secondaryButton":859},{"text":847,"config":848},"Start free trial",{"href":849,"dataGaName":476,"dataGaLocation":850},"https://gitlab.com/-/trials/new/","nav",{"altText":852,"config":853},"Gitlab Icon",{"src":854,"dataGaName":855,"dataGaLocation":850},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203874/jypbw1jx72aexsoohd7x.svg","gitlab icon",{"altText":852,"config":857},{"src":858,"dataGaName":855,"dataGaLocation":850},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203875/gs4c8p8opsgvflgkswz9.svg",{"text":860,"config":861},"Get Started",{"href":862,"dataGaName":863,"dataGaLocation":850},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/get-started/","get started",{"freeTrial":865,"mobileIcon":869,"desktopIcon":871},{"text":866,"config":867},"Learn more about GitLab Duo",{"href":507,"dataGaName":868,"dataGaLocation":850},"gitlab duo",{"altText":852,"config":870},{"src":854,"dataGaName":855,"dataGaLocation":850},{"altText":852,"config":872},{"src":858,"dataGaName":855,"dataGaLocation":850},{"button":874,"mobileIcon":879,"desktopIcon":881},{"text":875,"config":876},"/switch",{"href":877,"dataGaName":878,"dataGaLocation":850},"#contact","switch",{"altText":852,"config":880},{"src":854,"dataGaName":855,"dataGaLocation":850},{"altText":852,"config":882},{"src":883,"dataGaName":855,"dataGaLocation":850},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1773335277/ohhpiuoxoldryzrnhfrh.png",{"freeTrial":885,"mobileIcon":890,"desktopIcon":892},{"text":886,"config":887},"Back to pricing",{"href":620,"dataGaName":888,"dataGaLocation":850,"icon":889},"back to pricing","GoBack",{"altText":852,"config":891},{"src":854,"dataGaName":855,"dataGaLocation":850},{"altText":852,"config":893},{"src":858,"dataGaName":855,"dataGaLocation":850},{"title":895,"titleMobile":896,"button":897,"config":902},"Duo Agent Platform delivers 400% ROI, per new Forrester Consulting study.","400% ROI: Forrester TEI for GitLab Duo",{"text":513,"config":898},{"href":899,"dataGaName":900,"dataGaLocation":901},"https://about.gitlab.com/blog/gitlab-duo-agent-platform-delivers-400-percent-roi/","forrester-tei-dap-banner","global-banner",{"layout":903,"disabled":449},"release",{"data":905},{"text":906,"source":907,"edit":913,"contribute":918,"config":923,"items":928,"minimal":1138},"Git is a trademark of Software Freedom Conservancy and our use of 'GitLab' is under license",{"text":908,"config":909},"View page source",{"href":910,"dataGaName":911,"dataGaLocation":912},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/","page source","footer",{"text":914,"config":915},"Edit this page",{"href":916,"dataGaName":917,"dataGaLocation":912},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/content/","web ide",{"text":919,"config":920},"Please contribute",{"href":921,"dataGaName":922,"dataGaLocation":912},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/CONTRIBUTING.md/","please contribute",{"twitter":924,"facebook":925,"youtube":926,"linkedin":927},"https://twitter.com/gitlab","https://www.facebook.com/gitlab","https://www.youtube.com/channel/UCnMGQ8QHMAnVIsI3xJrihhg","https://www.linkedin.com/company/gitlab-com",[929,976,1030,1074,1106],{"title":618,"links":930,"subMenu":945},[931,935,940],{"text":932,"config":933},"View plans",{"href":620,"dataGaName":934,"dataGaLocation":912},"view plans",{"text":936,"config":937},"Why Premium?",{"href":938,"dataGaName":939,"dataGaLocation":912},"/pricing/premium/","why premium",{"text":941,"config":942},"Why Ultimate?",{"href":943,"dataGaName":944,"dataGaLocation":912},"/pricing/ultimate/","why ultimate",[946],{"title":947,"links":948},"Contact Us",[949,952,954,956,961,966,971],{"text":950,"config":951},"Contact sales",{"href":802,"dataGaName":481,"dataGaLocation":912},{"text":805,"config":953},{"href":807,"dataGaName":808,"dataGaLocation":912},{"text":810,"config":955},{"href":812,"dataGaName":813,"dataGaLocation":912},{"text":957,"config":958},"Status",{"href":959,"dataGaName":960,"dataGaLocation":912},"https://status.gitlab.com/","status",{"text":962,"config":963},"Terms of use",{"href":964,"dataGaName":965,"dataGaLocation":912},"/terms/","terms of use",{"text":967,"config":968},"Privacy statement",{"href":969,"dataGaName":970,"dataGaLocation":912},"/privacy/","privacy statement",{"text":972,"config":973},"Cookie preferences",{"dataGaName":974,"dataGaLocation":912,"id":975,"isOneTrustButton":452},"cookie preferences","ot-sdk-btn",{"title":518,"links":977,"subMenu":986},[978,982],{"text":979,"config":980},"DevSecOps platform",{"href":500,"dataGaName":981,"dataGaLocation":912},"devsecops platform",{"text":983,"config":984},"AI-Assisted Development",{"href":507,"dataGaName":985,"dataGaLocation":912},"ai-assisted development",[987],{"title":988,"links":989},"Topics",[990,995,1000,1005,1010,1015,1020,1025],{"text":991,"config":992},"CICD",{"href":993,"dataGaName":994,"dataGaLocation":912},"/topics/ci-cd/","cicd",{"text":996,"config":997},"GitOps",{"href":998,"dataGaName":999,"dataGaLocation":912},"/topics/gitops/","gitops",{"text":1001,"config":1002},"DevOps",{"href":1003,"dataGaName":1004,"dataGaLocation":912},"/topics/devops/","devops",{"text":1006,"config":1007},"Version Control",{"href":1008,"dataGaName":1009,"dataGaLocation":912},"/topics/version-control/","version control",{"text":1011,"config":1012},"DevSecOps",{"href":1013,"dataGaName":1014,"dataGaLocation":912},"/topics/devsecops/","devsecops",{"text":1016,"config":1017},"Cloud Native",{"href":1018,"dataGaName":1019,"dataGaLocation":912},"/topics/cloud-native/","cloud native",{"text":1021,"config":1022},"AI for Coding",{"href":1023,"dataGaName":1024,"dataGaLocation":912},"/topics/devops/ai-for-coding/","ai for coding",{"text":1026,"config":1027},"Agentic AI",{"href":1028,"dataGaName":1029,"dataGaLocation":912},"/topics/agentic-ai/","agentic ai",{"title":1031,"links":1032},"Solutions",[1033,1035,1037,1042,1046,1049,1053,1056,1058,1061,1064,1069],{"text":562,"config":1034},{"href":557,"dataGaName":562,"dataGaLocation":912},{"text":551,"config":1036},{"href":534,"dataGaName":535,"dataGaLocation":912},{"text":1038,"config":1039},"Agile development",{"href":1040,"dataGaName":1041,"dataGaLocation":912},"/solutions/agile-delivery/","agile delivery",{"text":1043,"config":1044},"SCM",{"href":547,"dataGaName":1045,"dataGaLocation":912},"source code management",{"text":991,"config":1047},{"href":540,"dataGaName":1048,"dataGaLocation":912},"continuous integration & delivery",{"text":1050,"config":1051},"Value stream management",{"href":590,"dataGaName":1052,"dataGaLocation":912},"value stream management",{"text":996,"config":1054},{"href":1055,"dataGaName":999,"dataGaLocation":912},"/solutions/gitops/",{"text":600,"config":1057},{"href":603,"dataGaName":604,"dataGaLocation":912},{"text":1059,"config":1060},"Small business",{"href":609,"dataGaName":610,"dataGaLocation":912},{"text":1062,"config":1063},"Public sector",{"href":615,"dataGaName":616,"dataGaLocation":912},{"text":1065,"config":1066},"Education",{"href":1067,"dataGaName":1068,"dataGaLocation":912},"/solutions/education/","education",{"text":1070,"config":1071},"Financial services",{"href":1072,"dataGaName":1073,"dataGaLocation":912},"/solutions/finance/","financial services",{"title":623,"links":1075},[1076,1078,1080,1082,1085,1087,1090,1092,1094,1096,1098,1100,1102,1104],{"text":636,"config":1077},{"href":638,"dataGaName":639,"dataGaLocation":912},{"text":641,"config":1079},{"href":643,"dataGaName":644,"dataGaLocation":912},{"text":646,"config":1081},{"href":648,"dataGaName":649,"dataGaLocation":912},{"text":651,"config":1083},{"href":653,"dataGaName":1084,"dataGaLocation":912},"docs",{"text":674,"config":1086},{"href":676,"dataGaName":677,"dataGaLocation":912},{"text":1088,"config":1089},"What's new",{"href":734,"dataGaName":735,"dataGaLocation":912},{"text":669,"config":1091},{"href":671,"dataGaName":672,"dataGaLocation":912},{"text":688,"config":1093},{"href":690,"dataGaName":691,"dataGaLocation":912},{"text":696,"config":1095},{"href":698,"dataGaName":699,"dataGaLocation":912},{"text":701,"config":1097},{"href":703,"dataGaName":704,"dataGaLocation":912},{"text":706,"config":1099},{"href":708,"dataGaName":709,"dataGaLocation":912},{"text":711,"config":1101},{"href":713,"dataGaName":714,"dataGaLocation":912},{"text":716,"config":1103},{"href":718,"dataGaName":719,"dataGaLocation":912},{"text":721,"config":1105},{"href":723,"dataGaName":724,"dataGaLocation":912},{"title":737,"links":1107},[1108,1110,1112,1114,1116,1118,1122,1127,1129,1131,1133],{"text":745,"config":1109},{"href":747,"dataGaName":739,"dataGaLocation":912},{"text":750,"config":1111},{"href":752,"dataGaName":753,"dataGaLocation":912},{"text":758,"config":1113},{"href":760,"dataGaName":761,"dataGaLocation":912},{"text":763,"config":1115},{"href":765,"dataGaName":766,"dataGaLocation":912},{"text":768,"config":1117},{"href":770,"dataGaName":771,"dataGaLocation":912},{"text":1119,"config":1120},"Sustainability",{"href":1121,"dataGaName":1119,"dataGaLocation":912},"/sustainability/",{"text":1123,"config":1124},"Diversity, inclusion and belonging (DIB)",{"href":1125,"dataGaName":1126,"dataGaLocation":912},"/diversity-inclusion-belonging/","Diversity, inclusion and belonging",{"text":773,"config":1128},{"href":775,"dataGaName":776,"dataGaLocation":912},{"text":783,"config":1130},{"href":785,"dataGaName":786,"dataGaLocation":912},{"text":788,"config":1132},{"href":790,"dataGaName":791,"dataGaLocation":912},{"text":1134,"config":1135},"Modern Slavery Transparency Statement",{"href":1136,"dataGaName":1137,"dataGaLocation":912},"https://handbook.gitlab.com/handbook/legal/modern-slavery-act-transparency-statement/","modern slavery transparency statement",{"items":1139},[1140,1143,1146],{"text":1141,"config":1142},"Terms",{"href":964,"dataGaName":965,"dataGaLocation":912},{"text":1144,"config":1145},"Cookies",{"dataGaName":974,"dataGaLocation":912,"id":975,"isOneTrustButton":452},{"text":1147,"config":1148},"Privacy",{"href":969,"dataGaName":970,"dataGaLocation":912},[1150],{"id":1151,"title":7,"body":448,"config":1152,"content":1154,"description":448,"extension":1158,"meta":1159,"navigation":452,"path":1160,"seo":1161,"stem":1162,"__hash__":1163},"blogAuthors/en-us/blog/authors/jacob-vosmaer.yml",{"template":1153},"BlogAuthor",{"name":7,"config":1155},{"headshot":1156,"ctfId":1157},"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",[1165,1174,1182],{"title":1166,"description":1167,"heroImage":1168,"category":444,"date":1169,"authors":1170,"slug":1173,"externalUrl":448},"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",[1171,1172],"Mathias Ewald","Martin Paloncy, Edgeless Systems","confidential-ai-for-gitlab-self-hosted",{"title":1175,"description":1176,"heroImage":1177,"category":444,"date":1178,"authors":1179,"slug":1181,"externalUrl":448},"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",[1180],"Lysanne Pinto","green-devops-carbon-measurement-cicd-pipeline",{"title":1183,"description":1184,"heroImage":1185,"category":444,"date":1186,"authors":1187,"slug":1189,"externalUrl":448},"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",[1188],"Paul Meresanu","how-to-build-ci-cd-observability-at-scale",{"promotions":1191},[1192,1206,1218,1230],{"id":1193,"categories":1194,"header":1196,"text":1197,"button":1198,"image":1203},"ai-modernization",[1195],"ai","Is AI achieving its promise at scale?","Quiz will take 5 minutes or less",{"text":1199,"config":1200},"Get your AI maturity score",{"href":1201,"dataGaName":1202,"dataGaLocation":677},"/assessments/ai-modernization-assessment/","modernization assessment",{"config":1204},{"src":1205},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/qix0m7kwnd8x2fh1zq49.png",{"id":1207,"categories":1208,"header":1210,"text":1197,"button":1211,"image":1215},"devops-modernization",[1209,1014],"product","Are you just managing tools or shipping innovation?",{"text":1212,"config":1213},"Get your DevOps maturity score",{"href":1214,"dataGaName":1202,"dataGaLocation":677},"/assessments/devops-modernization-assessment/",{"config":1216},{"src":1217},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138785/eg818fmakweyuznttgid.png",{"id":1219,"categories":1220,"header":1222,"text":1197,"button":1223,"image":1227},"security-modernization",[1221],"security","Are you trading speed for security?",{"text":1224,"config":1225},"Get your security maturity score",{"href":1226,"dataGaName":1202,"dataGaLocation":677},"/assessments/security-modernization-assessment/",{"config":1228},{"src":1229},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/p4pbqd9nnjejg5ds6mdk.png",{"id":1231,"paths":1232,"header":1235,"text":1236,"button":1237,"image":1242},"github-azure-migration",[1233,1234],"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":1238,"config":1239},"See how GitLab compares to GitHub",{"href":1240,"dataGaName":1241,"dataGaLocation":677},"/compare/gitlab-vs-github/github-azure-migration/","github azure migration",{"config":1243},{"src":1217},{"header":1245,"blurb":1246,"button":1247,"secondaryButton":1252},"Start building faster today","See what your team can do with the intelligent orchestration platform for DevSecOps.\n",{"text":1248,"config":1249},"Get your free trial",{"href":1250,"dataGaName":476,"dataGaLocation":1251},"https://gitlab.com/-/trial_registrations/new?glm_content=default-saas-trial&glm_source=about.gitlab.com/","feature",{"text":950,"config":1253},{"href":802,"dataGaName":481,"dataGaLocation":1251},1786803749451]