[{"data":1,"prerenderedAt":1076},["ShallowReactive",2],{"/blog/ai-agents-for-migrating-rate-limiting-system":3,"navigation-en-us":291,"banner-en-us":718,"footer-en-us":728,"blog-post-authors-en-us-Sam Wiskow":973,"blog-related-posts-en-us-ai-agents-for-migrating-rate-limiting-system":988,"blog-promotions-en-us":1013,"next-steps-en-us":1066},{"id":4,"title":5,"authors":6,"body":8,"category":271,"date":272,"description":273,"extension":274,"externalUrl":275,"faq":275,"featured":276,"heroImage":277,"meta":278,"navigation":276,"path":279,"seo":280,"slug":283,"stem":284,"tags":285,"template":289,"updatedDate":275,"__hash__":290},"blogPosts/en-us/blog/ai-agents-for-migrating-rate-limiting-system.md","How we used AI agents to migrate GitLab rate limiting",[7],"Sam Wiskow",{"type":9,"value":10,"toc":262},"minimark",[11,15,25,30,42,51,54,60,67,70,74,89,99,102,105,109,112,115,118,121,124,133,136,139,142,147,150,161,164,171,174,179,184,191,195,201,204,207,212,215,222,226,233,240,259],[12,13,14],"p",{},"A small team at GitLab spent the past few weeks running an experiment: Could we use AI agents to migrate part of our legacy rate-limiting system without dropping the safety bar?",[12,16,17,18,24],{},"Short answer: yes. AI agents do work. They can also expose weaknesses in how you usually work. The pod, the loop, and the observability mattered more than the agents. What follows is how we structured the work using GitLab, ",[19,20,23],"a",{"href":21,"rel":22},"https://about.gitlab.com/gitlab-duo-agent-platform/",[],"GitLab Duo Agent Platform",", and other tools — what worked, what the loop is and where it missed, and how you can copy what we did.",[26,27,29],"h2",{"id":28},"the-setup","The setup",[12,31,32,33,37,38,41],{},"GitLab has had two rate-limiting paths in production for years: an application-level ",[34,35,36],"code",{},"Gitlab::ApplicationRateLimiter"," with 121 keys, and a separate Rack-level system. The goal was to unify them on a single implementation in ",[34,39,40],{},"labkit-ruby",". Observable, testable, and operated the same way everywhere. Every request to the monolith touches it, so its failure modes have to be visible and reversible.",[12,43,44,45,50],{},"The pod comprised three GitLab team members and a handful of ",[19,46,49],{"href":47,"rel":48},"https://about.gitlab.com/topics/agentic-ai/",[],"AI agents",". Max Woolf, a Staff Backend Engineer on the API Platform team, owned the monolith side and ran most of the rollouts. Bob Van Landuyt, who works on Scalability, owned the gem and shaped the architecture. I held scope and wrote some of the early labkit code. A couple other engineers floated in to absorb context and contribute code and reviews.",[12,52,53],{},"Agents read context, drafted specs, implemented bounded changes, wrote tests, and pre-reviewed merge requests. GitLab Duo Code Review kept code quality high on merge requests. Humans owned scope, architecture, rollout, and final review.",[12,55,56,57,59],{},"We ran a strict loop: read the epic, write the spec, run adversarial review on the spec, implement only after blockers cleared, verify with explicit evidence, run adversarial review on the merge request, escalate to human review, merge. Adversarial review was capped at two resolution rounds before a human had to weigh in. Across the project we shipped 14 numbered specs and somewhere north of 30 merge requests into ",[34,58,40],{},". In practice, the loop ran tighter or looser depending on the person. Bob often did several spec/review cycles privately before producing a shared artifact.",[12,61,62],{},[63,64],"img",{"alt":65,"src":66},"diagram of the loop","https://res.cloudinary.com/about-gitlab-com/image/upload/v1783518190/iejv72y7iz9i9rczcfbr.png",[12,68,69],{},"That loop sounds like a lot. On legacy code, it’s a loop I can trust an agent to execute.",[26,71,73],{"id":72},"what-worked","What worked",[12,75,76,77,80,81,84,85,88],{},"Cohort 1 was the high-stakes test: five heavily-trafficked keys including ",[34,78,79],{},"pipelines_create",", ",[34,82,83],{},"notes_create",", and ",[34,86,87],{},"user_sign_in",". We rolled it 1% → 10% → 50% on May 4, 2026, 100% on May 5, 2026. Bob’s running commentary from that day is the operating model in miniature:",[12,90,91],{},[92,93,94,95,98],"em",{},"“All rollouts complete. Up to now, all rate limits from the ",[34,96,97],{},"applimiter"," and the labkit implementation agree. But I suspect this is because there’s not a lot of traffic there. I’m going to see if I can generate some traffic exceeding the limit.”",[12,100,101],{},"That’s what a good rollout looks like, and it’s the kind of judgement no agent should make for you. The new system agreeing with the old isn’t success, it might just mean nothing tripped.",[12,103,104],{},"Cohort 2 collapsed the next 95 call sites, 83 in the monolith, and 12 in Enterprise Edition (EE), under a single feature flag pair. Without that consolidation, the rollout would have meant something like 95 individual flag flips and ~190 YAML edits. Agents are very good at this kind of mechanical fan-out across a codebase. Humans are very bad at it.",[26,106,108],{"id":107},"where-the-loop-missed","Where the loop missed",[12,110,111],{},"The loop missed the following things.",[12,113,114],{},"One was a shadow-mode miss. Cohort 2 had been running in shadow mode for days, agreeing with the old implementation. Switching it from observe to enforce should have been uneventful. There was a small hiccup.",[12,116,117],{},"The new adapter quietly dropped an identifier on one unauthenticated code path. Three String values were being squeezed into two primitive slots, and the wrong value overwrote the identifier. A tiny portion of users saw a generic failure for a short period of time.",[12,119,120],{},"Shadow comparison had actually flagged that key as diverging. We just hadn’t built our label set to distinguish a structural collision from a normal disagreement, so the signal sat in the dashboard while we ramped to 100%.",[12,122,123],{},"We immediately turned the enforcement flag off. Bob pinned the structural problem in one sentence:",[12,125,126],{},[92,127,128,129,132],{},"“I think we should make this better once we clean up this mess and call the ",[34,130,131],{},"ApplicationLimiter"," only with named characteristics, no more array scopes.”",[12,134,135],{},"The immediate fix shipped two days later. The structural cleanup is on the list for the next pass.",[12,137,138],{},"It went through every step of the loop: spec, adversarial review, implementation, GitLab Duo Code Review, gradual rollout. The loop both did and didn’t catch it. The lesson wasn’t “agents are dangerous.” It was that we had observability, but not observability that distinguished the failure modes that mattered.",[12,140,141],{},"On May 15, Max ran an audit against master, pinged me in Slack, and opened Cohort 6:",[12,143,144],{},[92,145,146],{},"“I’ve added a Cohort 6 to the migration: bits and bobs that got missed (not you, Bob).”",[12,148,149],{},"We had planned five cohorts. We needed six.",[12,151,152,153,156,157,160],{},"The diagnosis came a few days later: Claude had missed a handful of EE-only rate limits: ",[34,154,155],{},"notification_emails",", some EE registry entries, three webhook keys, three sub-second ",[34,158,159],{},"partner_*"," keys, a few orphaned adapter rows. 17 keys out of 121 had slipped past the earlier cohorts. Each had a reason it didn’t fit cleanly into one of them. None had a reason to be invisible.",[12,162,163],{},"We hadn’t asked the agents, or ourselves, to keep a running count against the full key inventory.",[12,165,166,167,170],{},"Another was Redis. The ",[34,168,169],{},"redis-cluster-ratelimiting"," service runs as a 4-shard cluster. Bob’s read at the start was honest: “There’s headroom, but not enough to double utilization entirely.”",[12,172,173],{},"By early May the constraint we’d hit before came back:",[12,175,176],{},[92,177,178],{},"Bob: “The bottleneck we came across before, that wasn’t new for this project, is an actual bottleneck. This means we need to do an infra change to get around that.”",[12,180,181],{},[92,182,183],{},"Max: “Uh oh.”",[12,185,186,187,190],{},"We bumped ",[34,188,189],{},"maxclients"," in stages and halted at 75,000 connections instead of pushing to 100,000, once it became clear that more connections were going to tip the primaries’ CPU into saturation. One primary per shard, one core for command execution. No vertical lever to pull.",[26,192,194],{"id":193},"what-the-agents-actually-changed","What the agents actually changed",[12,196,197],{},[63,198],{"alt":199,"src":200},"Diagram of moved bottleneck due to agents","https://res.cloudinary.com/about-gitlab-com/image/upload/v1783518190/bzyemaewofxyq9ikxxcb.png",[12,202,203],{},"They moved the bottleneck. With agents drafting specs and implementing inside a tight loop, code generation stopped being the slow part. Review capacity, rollout judgement, and operator attention became the slow parts. That’s a much better problem to have, but today it still consumes human capacity.",[12,205,206],{},"It also wasn’t always pleasant. Mid-project, Max wrote:",[12,208,209],{},[92,210,211],{},"“Mixed bag, ended up in circles with an agent. Had one of those ‘I could’ve done this faster myself’ moments, which was irritating.”",[12,213,214],{},"A few weeks earlier he’d called the project “one of my steeper learning curves at GitLab, for sure.” Working with agents is a skill, and the cost of building it is days where you’d have made more progress alone.",[12,216,217,218,221],{},"The other shift was being honest about what “done” meant. Bob’s note at the end of Cohort 1 (",[92,219,220],{},"“the feature flag per rate-limit is overkill, we shouldn’t do these for the next migrations”",") is a small example of the kind of judgement no agent makes for you. They will happily generate 95 flag flips if you ask. The human judgement was deciding not to.",[26,223,225],{"id":224},"where-we-are-now","Where we are now",[12,227,228,229,232],{},"By mid-June, all six cohorts are at 100%. All 121 keys in the ",[34,230,231],{},"ApplicationRateLimiter"," run through the new framework, an audit confirmed the legacy path is down to near-zero, and we added a guardrail so no future rate limit can silently bypass it.",[12,234,235,236,239],{},"That’s the application-level migration done. ",[34,237,238],{},"RackAttack"," is next, the higher-volume layer at roughly 4 billion requests a day. Its shadow-and-enforce middleware is in development; the first merge request is approved and queued for merge.",[12,241,242,243,246,247,252,253,258],{},"If you want to copy this, you can use ",[19,244,23],{"href":21,"rel":245},[]," to help you write your specs, Duo Developer to implement your issues, and ",[19,248,251],{"href":249,"rel":250},"https://docs.gitlab.com/user/gitlab_duo/code_review/",[],"Duo Code Review"," to help you merge your MRs. But that’s the easy part. I’d ask whether you have a Bob. Someone who’ll deliberately try to break the new system at 1% before letting it run at 50%. And whether you have a Max. Someone who’ll run an audit when everyone else thinks the migration is done. The workflow matters; the people more. If you want to try this on your own legacy code, ",[19,254,257],{"href":255,"rel":256},"https://about.gitlab.com/free-trial/",[],"try it out today",".",[12,260,261],{},"AI agents work. So does changing how we work alongside them.",{"title":263,"searchDepth":264,"depth":264,"links":265},"",2,[266,267,268,269,270],{"id":28,"depth":264,"text":29},{"id":72,"depth":264,"text":73},{"id":107,"depth":264,"text":108},{"id":193,"depth":264,"text":194},{"id":224,"depth":264,"text":225},"ai","2026-07-08","Learn how our three-person pod used GitLab Duo Agent platform, along with other AI tools, to successfully migrate the rate limiting system, and what we learned.","md",null,true,"https://res.cloudinary.com/about-gitlab-com/image/upload/v1773075582/yiosxfhwk8rfkulrtchv.png",{},"/en-us/blog/ai-agents-for-migrating-rate-limiting-system",{"config":281,"title":5,"description":273},{"noIndex":282},false,"ai-agents-for-migrating-rate-limiting-system","en-us/blog/ai-agents-for-migrating-rate-limiting-system",[286,287,288],"AI","features","tutorial","BlogPost","6KGRdeA8NYtIFp3YS7CdooSDx43Y5quSe8s3D9NN8eA",{"logo":292,"freeTrial":297,"sales":302,"login":307,"items":312,"search":638,"minimal":669,"duo":688,"switchNav":697,"pricingDeployment":708},{"config":293},{"href":294,"dataGaName":295,"dataGaLocation":296},"/","gitlab logo","header",{"text":298,"config":299},"Get free trial",{"href":300,"dataGaName":301,"dataGaLocation":296},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com&glm_content=default-saas-trial/","free trial",{"text":303,"config":304},"Request a demo",{"href":305,"dataGaName":306,"dataGaLocation":296},"/sales/?contact-topic=request-demo","sales",{"text":308,"config":309},"Sign in",{"href":310,"dataGaName":311,"dataGaLocation":296},"https://gitlab.com/users/sign_in/","sign in",[313,341,441,446,560,616],{"text":314,"config":315,"menu":317},"Platform",{"dataNavLevelOne":316},"platform",{"type":318,"columns":319},"cards",[320,326,333],{"title":314,"description":321,"link":322},"The intelligent orchestration platform for DevSecOps",{"text":323,"config":324},"Explore our Platform",{"href":325,"dataGaName":316,"dataGaLocation":296},"/platform/",{"title":23,"description":327,"link":328},"Agentic AI for the entire software lifecycle",{"text":329,"config":330},"Meet GitLab Duo",{"href":331,"dataGaName":332,"dataGaLocation":296},"/gitlab-duo-agent-platform/","gitlab duo agent platform",{"title":334,"description":335,"link":336},"Why GitLab","See the top reasons enterprises choose GitLab",{"text":337,"config":338},"Learn more",{"href":339,"dataGaName":340,"dataGaLocation":296},"/why-gitlab/","why gitlab",{"text":342,"left":276,"config":343,"menu":345},"Product",{"dataNavLevelOne":344},"solutions",{"type":346,"link":347,"columns":351,"feature":420},"lists",{"text":348,"config":349},"View all Solutions",{"href":350,"dataGaName":344,"dataGaLocation":296},"/solutions/",[352,376,399],{"title":353,"description":354,"link":355,"items":360},"Automation","CI/CD and automation to accelerate deployment",{"config":356},{"icon":357,"href":358,"dataGaName":359,"dataGaLocation":296},"AutomatedCodeAlt","/solutions/delivery-automation/","automated software delivery",[361,365,368,372],{"text":362,"config":363},"CI/CD",{"href":364,"dataGaLocation":296,"dataGaName":362},"/solutions/continuous-integration/",{"text":23,"config":366},{"href":331,"dataGaLocation":296,"dataGaName":367},"gitlab duo agent platform - product menu",{"text":369,"config":370},"Source Code Management",{"href":371,"dataGaLocation":296,"dataGaName":369},"/solutions/source-code-management/",{"text":373,"config":374},"Automated Software Delivery",{"href":358,"dataGaLocation":296,"dataGaName":375},"Automated software delivery",{"title":377,"description":378,"link":379,"items":384},"Security","Deliver code faster without compromising security",{"config":380},{"href":381,"dataGaName":382,"dataGaLocation":296,"icon":383},"/solutions/application-security-testing/","security and compliance","ShieldCheckLight",[385,389,394],{"text":386,"config":387},"Application Security Testing",{"href":381,"dataGaName":388,"dataGaLocation":296},"Application security testing",{"text":390,"config":391},"Software Supply Chain Security",{"href":392,"dataGaLocation":296,"dataGaName":393},"/solutions/supply-chain/","Software supply chain security",{"text":395,"config":396},"Software Compliance",{"href":397,"dataGaName":398,"dataGaLocation":296},"/solutions/software-compliance/","software compliance",{"title":400,"link":401,"items":406},"Measurement",{"config":402},{"icon":403,"href":404,"dataGaName":405,"dataGaLocation":296},"DigitalTransformation","/solutions/visibility-measurement/","visibility and measurement",[407,411,415],{"text":408,"config":409},"Visibility & Measurement",{"href":404,"dataGaLocation":296,"dataGaName":410},"Visibility and Measurement",{"text":412,"config":413},"Value Stream Management",{"href":414,"dataGaLocation":296,"dataGaName":412},"/solutions/value-stream-management/",{"text":416,"config":417},"Analytics & Insights",{"href":418,"dataGaLocation":296,"dataGaName":419},"/solutions/analytics-and-insights/","Analytics and insights",{"title":421,"type":346,"items":422},"GitLab for",[423,429,435],{"text":424,"config":425},"Enterprise",{"icon":426,"href":427,"dataGaLocation":296,"dataGaName":428},"Building","/enterprise/","enterprise",{"text":430,"config":431},"Small Business",{"icon":432,"href":433,"dataGaLocation":296,"dataGaName":434},"Work","/small-business/","small business",{"text":436,"config":437},"Public Sector",{"icon":438,"href":439,"dataGaLocation":296,"dataGaName":440},"Organization","/solutions/public-sector/","public sector",{"text":442,"config":443},"Pricing",{"href":444,"dataGaName":445,"dataGaLocation":296,"dataNavLevelOne":445},"/pricing/","pricing",{"text":447,"config":448,"menu":450},"Resources",{"dataNavLevelOne":449},"resources",{"type":346,"link":451,"columns":455,"feature":549},{"text":452,"config":453},"View all resources",{"href":454,"dataGaName":449,"dataGaLocation":296},"/resources/",[456,489,516],{"title":457,"items":458},"Getting started",[459,464,469,474,479,484],{"text":460,"config":461},"Install",{"href":462,"dataGaName":463,"dataGaLocation":296},"/install/","install",{"text":465,"config":466},"Quick start guides",{"href":467,"dataGaName":468,"dataGaLocation":296},"/get-started/","quick setup checklists",{"text":470,"config":471},"Learn",{"href":472,"dataGaLocation":296,"dataGaName":473},"https://university.gitlab.com/","learn",{"text":475,"config":476},"Product documentation",{"href":477,"dataGaName":478,"dataGaLocation":296},"https://docs.gitlab.com/","product documentation",{"text":480,"config":481},"Best practice videos",{"href":482,"dataGaName":483,"dataGaLocation":296},"/getting-started-videos/","best practice videos",{"text":485,"config":486},"Integrations",{"href":487,"dataGaName":488,"dataGaLocation":296},"/integrations/","integrations",{"title":490,"items":491},"Discover",[492,497,502,507,511],{"text":493,"config":494},"Customer success stories",{"href":495,"dataGaName":496,"dataGaLocation":296},"/customers/","customer success stories",{"text":498,"config":499},"Blog",{"href":500,"dataGaName":501,"dataGaLocation":296},"/blog/","blog",{"text":503,"config":504},"Demo Hub",{"href":505,"dataGaName":506,"dataGaLocation":296},"/demo-hub/","demo hub",{"text":508,"config":509},"The Source",{"href":510,"dataGaName":501,"dataGaLocation":296},"/the-source/",{"text":512,"config":513},"Remote",{"href":514,"dataGaName":515,"dataGaLocation":296},"https://handbook.gitlab.com/handbook/company/culture/all-remote/","remote",{"title":517,"items":518},"Connect",[519,524,529,534,539,544],{"text":520,"config":521},"GitLab Services",{"href":522,"dataGaName":523,"dataGaLocation":296},"/services/","services",{"text":525,"config":526},"Contribute",{"href":527,"dataGaName":528,"dataGaLocation":296},"https://contributors.gitlab.com","contribute",{"text":530,"config":531},"Community",{"href":532,"dataGaName":533,"dataGaLocation":296},"/community/","community",{"text":535,"config":536},"Forum",{"href":537,"dataGaName":538,"dataGaLocation":296},"https://forum.gitlab.com/","forum",{"text":540,"config":541},"Events",{"href":542,"dataGaName":543,"dataGaLocation":296},"/events/","events",{"text":545,"config":546},"Partners",{"href":547,"dataGaName":548,"dataGaLocation":296},"/partners/","partners",{"config":550,"title":553,"text":554,"link":555},{"background":551,"textColor":552},"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":556,"config":557},"Read the latest",{"href":558,"dataGaName":559,"dataGaLocation":296},"/whats-new/","whats new",{"text":561,"config":562,"menu":564},"Company",{"dataNavLevelOne":563},"company",{"type":346,"columns":565},[566],{"items":567},[568,573,579,581,586,591,596,601,606,611],{"text":569,"config":570},"About",{"href":571,"dataGaName":572,"dataGaLocation":296},"/company/","about",{"text":574,"config":575,"footerGa":578},"Jobs",{"href":576,"dataGaName":577,"dataGaLocation":296},"/jobs/","jobs",{"dataGaName":577},{"text":540,"config":580},{"href":542,"dataGaName":543,"dataGaLocation":296},{"text":582,"config":583},"Leadership",{"href":584,"dataGaName":585,"dataGaLocation":296},"/company/team/e-group/","leadership",{"text":587,"config":588},"Handbook",{"href":589,"dataGaName":590,"dataGaLocation":296},"https://handbook.gitlab.com/","handbook",{"text":592,"config":593},"Investor relations",{"href":594,"dataGaName":595,"dataGaLocation":296},"https://ir.gitlab.com/overview/default.aspx","investor relations",{"text":597,"config":598},"Trust Center",{"href":599,"dataGaName":600,"dataGaLocation":296},"/security/","trust center",{"text":602,"config":603},"AI Transparency Center",{"href":604,"dataGaName":605,"dataGaLocation":296},"/ai-transparency-center/","ai transparency center",{"text":607,"config":608},"Newsletter",{"href":609,"dataGaName":610,"dataGaLocation":296},"/company/contact/#contact-forms","newsletter",{"text":612,"config":613},"Press",{"href":614,"dataGaName":615,"dataGaLocation":296},"/press/","press",{"text":617,"config":618,"menu":619},"Contact us",{"dataNavLevelOne":563},{"type":346,"columns":620},[621],{"items":622},[623,628,633],{"text":624,"config":625},"Talk to sales",{"href":626,"dataGaName":627,"dataGaLocation":296},"/sales/","talk to sales",{"text":629,"config":630},"Support portal",{"href":631,"dataGaName":632,"dataGaLocation":296},"https://support.gitlab.com/hc/en-us","support portal",{"text":634,"config":635},"Customer portal",{"href":636,"dataGaName":637,"dataGaLocation":296},"https://customers.gitlab.com/customers/sign_in/","customer portal",{"close":639,"login":640,"suggestions":647},"Close",{"text":641,"link":642},"To search repositories and projects, login to",{"text":643,"config":644},"gitlab.com",{"href":310,"dataGaName":645,"dataGaLocation":646},"search login","search",{"text":648,"default":649},"Suggestions",[650,652,656,658,662,666],{"text":23,"config":651},{"href":331,"dataGaName":23,"dataGaLocation":646},{"text":653,"config":654},"Code Suggestions (AI)",{"href":655,"dataGaName":653,"dataGaLocation":646},"/solutions/code-suggestions/",{"text":362,"config":657},{"href":364,"dataGaName":362,"dataGaLocation":646},{"text":659,"config":660},"GitLab on AWS",{"href":661,"dataGaName":659,"dataGaLocation":646},"/partners/technology-partners/aws/",{"text":663,"config":664},"GitLab on Google Cloud",{"href":665,"dataGaName":663,"dataGaLocation":646},"/partners/technology-partners/google-cloud-platform/",{"text":667,"config":668},"Why GitLab?",{"href":339,"dataGaName":667,"dataGaLocation":646},{"freeTrial":670,"mobileIcon":675,"desktopIcon":680,"secondaryButton":683},{"text":671,"config":672},"Start free trial",{"href":673,"dataGaName":301,"dataGaLocation":674},"https://gitlab.com/-/trials/new/","nav",{"altText":676,"config":677},"Gitlab Icon",{"src":678,"dataGaName":679,"dataGaLocation":674},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203874/jypbw1jx72aexsoohd7x.svg","gitlab icon",{"altText":676,"config":681},{"src":682,"dataGaName":679,"dataGaLocation":674},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203875/gs4c8p8opsgvflgkswz9.svg",{"text":684,"config":685},"Get Started",{"href":686,"dataGaName":687,"dataGaLocation":674},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/get-started/","get started",{"freeTrial":689,"mobileIcon":693,"desktopIcon":695},{"text":690,"config":691},"Learn more about GitLab Duo",{"href":331,"dataGaName":692,"dataGaLocation":674},"gitlab duo",{"altText":676,"config":694},{"src":678,"dataGaName":679,"dataGaLocation":674},{"altText":676,"config":696},{"src":682,"dataGaName":679,"dataGaLocation":674},{"button":698,"mobileIcon":703,"desktopIcon":705},{"text":699,"config":700},"/switch",{"href":701,"dataGaName":702,"dataGaLocation":674},"#contact","switch",{"altText":676,"config":704},{"src":678,"dataGaName":679,"dataGaLocation":674},{"altText":676,"config":706},{"src":707,"dataGaName":679,"dataGaLocation":674},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1773335277/ohhpiuoxoldryzrnhfrh.png",{"freeTrial":709,"mobileIcon":714,"desktopIcon":716},{"text":710,"config":711},"Back to pricing",{"href":444,"dataGaName":712,"dataGaLocation":674,"icon":713},"back to pricing","GoBack",{"altText":676,"config":715},{"src":678,"dataGaName":679,"dataGaLocation":674},{"altText":676,"config":717},{"src":682,"dataGaName":679,"dataGaLocation":674},{"title":719,"titleMobile":720,"button":721,"config":726},"Duo Agent Platform delivers 400% ROI, per new Forrester Consulting study.","400% ROI: Forrester TEI for GitLab Duo",{"text":337,"config":722},{"href":723,"dataGaName":724,"dataGaLocation":725},"https://about.gitlab.com/blog/gitlab-duo-agent-platform-delivers-400-percent-roi/","forrester-tei-dap-banner","global-banner",{"layout":727,"disabled":282},"release",{"data":729},{"text":730,"source":731,"edit":737,"contribute":742,"config":747,"items":752,"minimal":962},"Git is a trademark of Software Freedom Conservancy and our use of 'GitLab' is under license",{"text":732,"config":733},"View page source",{"href":734,"dataGaName":735,"dataGaLocation":736},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/","page source","footer",{"text":738,"config":739},"Edit this page",{"href":740,"dataGaName":741,"dataGaLocation":736},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/content/","web ide",{"text":743,"config":744},"Please contribute",{"href":745,"dataGaName":746,"dataGaLocation":736},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/CONTRIBUTING.md/","please contribute",{"twitter":748,"facebook":749,"youtube":750,"linkedin":751},"https://twitter.com/gitlab","https://www.facebook.com/gitlab","https://www.youtube.com/channel/UCnMGQ8QHMAnVIsI3xJrihhg","https://www.linkedin.com/company/gitlab-com",[753,800,854,898,930],{"title":442,"links":754,"subMenu":769},[755,759,764],{"text":756,"config":757},"View plans",{"href":444,"dataGaName":758,"dataGaLocation":736},"view plans",{"text":760,"config":761},"Why Premium?",{"href":762,"dataGaName":763,"dataGaLocation":736},"/pricing/premium/","why premium",{"text":765,"config":766},"Why Ultimate?",{"href":767,"dataGaName":768,"dataGaLocation":736},"/pricing/ultimate/","why ultimate",[770],{"title":771,"links":772},"Contact Us",[773,776,778,780,785,790,795],{"text":774,"config":775},"Contact sales",{"href":626,"dataGaName":306,"dataGaLocation":736},{"text":629,"config":777},{"href":631,"dataGaName":632,"dataGaLocation":736},{"text":634,"config":779},{"href":636,"dataGaName":637,"dataGaLocation":736},{"text":781,"config":782},"Status",{"href":783,"dataGaName":784,"dataGaLocation":736},"https://status.gitlab.com/","status",{"text":786,"config":787},"Terms of use",{"href":788,"dataGaName":789,"dataGaLocation":736},"/terms/","terms of use",{"text":791,"config":792},"Privacy statement",{"href":793,"dataGaName":794,"dataGaLocation":736},"/privacy/","privacy statement",{"text":796,"config":797},"Cookie preferences",{"dataGaName":798,"dataGaLocation":736,"id":799,"isOneTrustButton":276},"cookie preferences","ot-sdk-btn",{"title":342,"links":801,"subMenu":810},[802,806],{"text":803,"config":804},"DevSecOps platform",{"href":325,"dataGaName":805,"dataGaLocation":736},"devsecops platform",{"text":807,"config":808},"AI-Assisted Development",{"href":331,"dataGaName":809,"dataGaLocation":736},"ai-assisted development",[811],{"title":812,"links":813},"Topics",[814,819,824,829,834,839,844,849],{"text":815,"config":816},"CICD",{"href":817,"dataGaName":818,"dataGaLocation":736},"/topics/ci-cd/","cicd",{"text":820,"config":821},"GitOps",{"href":822,"dataGaName":823,"dataGaLocation":736},"/topics/gitops/","gitops",{"text":825,"config":826},"DevOps",{"href":827,"dataGaName":828,"dataGaLocation":736},"/topics/devops/","devops",{"text":830,"config":831},"Version Control",{"href":832,"dataGaName":833,"dataGaLocation":736},"/topics/version-control/","version control",{"text":835,"config":836},"DevSecOps",{"href":837,"dataGaName":838,"dataGaLocation":736},"/topics/devsecops/","devsecops",{"text":840,"config":841},"Cloud Native",{"href":842,"dataGaName":843,"dataGaLocation":736},"/topics/cloud-native/","cloud native",{"text":845,"config":846},"AI for Coding",{"href":847,"dataGaName":848,"dataGaLocation":736},"/topics/devops/ai-for-coding/","ai for coding",{"text":850,"config":851},"Agentic AI",{"href":852,"dataGaName":853,"dataGaLocation":736},"/topics/agentic-ai/","agentic ai",{"title":855,"links":856},"Solutions",[857,859,861,866,870,873,877,880,882,885,888,893],{"text":386,"config":858},{"href":381,"dataGaName":386,"dataGaLocation":736},{"text":375,"config":860},{"href":358,"dataGaName":359,"dataGaLocation":736},{"text":862,"config":863},"Agile development",{"href":864,"dataGaName":865,"dataGaLocation":736},"/solutions/agile-delivery/","agile delivery",{"text":867,"config":868},"SCM",{"href":371,"dataGaName":869,"dataGaLocation":736},"source code management",{"text":815,"config":871},{"href":364,"dataGaName":872,"dataGaLocation":736},"continuous integration & delivery",{"text":874,"config":875},"Value stream management",{"href":414,"dataGaName":876,"dataGaLocation":736},"value stream management",{"text":820,"config":878},{"href":879,"dataGaName":823,"dataGaLocation":736},"/solutions/gitops/",{"text":424,"config":881},{"href":427,"dataGaName":428,"dataGaLocation":736},{"text":883,"config":884},"Small business",{"href":433,"dataGaName":434,"dataGaLocation":736},{"text":886,"config":887},"Public sector",{"href":439,"dataGaName":440,"dataGaLocation":736},{"text":889,"config":890},"Education",{"href":891,"dataGaName":892,"dataGaLocation":736},"/solutions/education/","education",{"text":894,"config":895},"Financial services",{"href":896,"dataGaName":897,"dataGaLocation":736},"/solutions/finance/","financial services",{"title":447,"links":899},[900,902,904,906,909,911,914,916,918,920,922,924,926,928],{"text":460,"config":901},{"href":462,"dataGaName":463,"dataGaLocation":736},{"text":465,"config":903},{"href":467,"dataGaName":468,"dataGaLocation":736},{"text":470,"config":905},{"href":472,"dataGaName":473,"dataGaLocation":736},{"text":475,"config":907},{"href":477,"dataGaName":908,"dataGaLocation":736},"docs",{"text":498,"config":910},{"href":500,"dataGaName":501,"dataGaLocation":736},{"text":912,"config":913},"What's new",{"href":558,"dataGaName":559,"dataGaLocation":736},{"text":493,"config":915},{"href":495,"dataGaName":496,"dataGaLocation":736},{"text":512,"config":917},{"href":514,"dataGaName":515,"dataGaLocation":736},{"text":520,"config":919},{"href":522,"dataGaName":523,"dataGaLocation":736},{"text":525,"config":921},{"href":527,"dataGaName":528,"dataGaLocation":736},{"text":530,"config":923},{"href":532,"dataGaName":533,"dataGaLocation":736},{"text":535,"config":925},{"href":537,"dataGaName":538,"dataGaLocation":736},{"text":540,"config":927},{"href":542,"dataGaName":543,"dataGaLocation":736},{"text":545,"config":929},{"href":547,"dataGaName":548,"dataGaLocation":736},{"title":561,"links":931},[932,934,936,938,940,942,946,951,953,955,957],{"text":569,"config":933},{"href":571,"dataGaName":563,"dataGaLocation":736},{"text":574,"config":935},{"href":576,"dataGaName":577,"dataGaLocation":736},{"text":582,"config":937},{"href":584,"dataGaName":585,"dataGaLocation":736},{"text":587,"config":939},{"href":589,"dataGaName":590,"dataGaLocation":736},{"text":592,"config":941},{"href":594,"dataGaName":595,"dataGaLocation":736},{"text":943,"config":944},"Sustainability",{"href":945,"dataGaName":943,"dataGaLocation":736},"/sustainability/",{"text":947,"config":948},"Diversity, inclusion and belonging (DIB)",{"href":949,"dataGaName":950,"dataGaLocation":736},"/diversity-inclusion-belonging/","Diversity, inclusion and belonging",{"text":597,"config":952},{"href":599,"dataGaName":600,"dataGaLocation":736},{"text":607,"config":954},{"href":609,"dataGaName":610,"dataGaLocation":736},{"text":612,"config":956},{"href":614,"dataGaName":615,"dataGaLocation":736},{"text":958,"config":959},"Modern Slavery Transparency Statement",{"href":960,"dataGaName":961,"dataGaLocation":736},"https://handbook.gitlab.com/handbook/legal/modern-slavery-act-transparency-statement/","modern slavery transparency statement",{"items":963},[964,967,970],{"text":965,"config":966},"Terms",{"href":788,"dataGaName":789,"dataGaLocation":736},{"text":968,"config":969},"Cookies",{"dataGaName":798,"dataGaLocation":736,"id":799,"isOneTrustButton":276},{"text":971,"config":972},"Privacy",{"href":793,"dataGaName":794,"dataGaLocation":736},[974],{"id":975,"title":7,"body":275,"config":976,"content":978,"description":275,"extension":982,"meta":983,"navigation":276,"path":984,"seo":985,"stem":986,"__hash__":987},"blogAuthors/en-us/blog/authors/sam-wiskow.yml",{"template":977},"BlogAuthor",{"name":7,"config":979},{"headshot":980,"ctfId":981},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749659433/Blog/Author%20Headshots/swiskow-headshot.jpg","swiskow","yml",{},"/en-us/blog/authors/sam-wiskow",{},"en-us/blog/authors/sam-wiskow","TR52XmFI8G3xfSF6pTXW6r_bf0Bd5tf82MmM7VjjKfM",[989,997,1005],{"title":990,"description":991,"heroImage":992,"category":271,"date":993,"authors":994,"slug":996,"externalUrl":275},"How I built a demo generator with GitLab Duo Agent Platform","Demos haven't always looked like this. Looking back over my career, here's how they have evolved. Follow the tutorial to build your own demo and agent.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1765809212/noh0mdfn9o94ry9ykura.png","2026-08-13",[995],"Itzik Gan Baruch","agentic-click-through-demo",{"title":998,"description":999,"heroImage":1000,"category":271,"date":1001,"authors":1002,"slug":1004,"externalUrl":275},"How to govern agentic AI, MCPs, and AI code assistants","AI agents can write, push, and deploy without human review at each step. Learn a practical framework for controlling access, permissions, and audit trails.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1785337625/ifzlc2hyzaxhzmjgyymh.png","2026-07-31",[1003],"Julie Griffin","govern-agentic-ai-mcps-code-assistants",{"title":1006,"description":1007,"heroImage":1008,"category":271,"date":1009,"authors":1010,"slug":1012,"externalUrl":275},"Claude Opus 5 on GitLab: Reasoning built for the hard tasks","Anthropic’s Claude Opus 5 is now available on GitLab Duo Agent Platform, delivering deeper reasoning without sacrificing speed.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1750099203/Blog/Hero%20Images/Blog/Hero%20Images/blog-image-template-1800x945%20%2820%29_2bJGC5ZP3WheoqzlLT05C5_1750099203484.png","2026-07-27",[1011],"Brittany Lutz","claude-opus-5-on-gitlab-duo-agent-platform",{"promotions":1014},[1015,1028,1040,1052],{"id":1016,"categories":1017,"header":1018,"text":1019,"button":1020,"image":1025},"ai-modernization",[271],"Is AI achieving its promise at scale?","Quiz will take 5 minutes or less",{"text":1021,"config":1022},"Get your AI maturity score",{"href":1023,"dataGaName":1024,"dataGaLocation":501},"/assessments/ai-modernization-assessment/","modernization assessment",{"config":1026},{"src":1027},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/qix0m7kwnd8x2fh1zq49.png",{"id":1029,"categories":1030,"header":1032,"text":1019,"button":1033,"image":1037},"devops-modernization",[1031,838],"product","Are you just managing tools or shipping innovation?",{"text":1034,"config":1035},"Get your DevOps maturity score",{"href":1036,"dataGaName":1024,"dataGaLocation":501},"/assessments/devops-modernization-assessment/",{"config":1038},{"src":1039},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138785/eg818fmakweyuznttgid.png",{"id":1041,"categories":1042,"header":1044,"text":1019,"button":1045,"image":1049},"security-modernization",[1043],"security","Are you trading speed for security?",{"text":1046,"config":1047},"Get your security maturity score",{"href":1048,"dataGaName":1024,"dataGaLocation":501},"/assessments/security-modernization-assessment/",{"config":1050},{"src":1051},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/p4pbqd9nnjejg5ds6mdk.png",{"id":1053,"paths":1054,"header":1057,"text":1058,"button":1059,"image":1064},"github-azure-migration",[1055,1056],"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":1060,"config":1061},"See how GitLab compares to GitHub",{"href":1062,"dataGaName":1063,"dataGaLocation":501},"/compare/gitlab-vs-github/github-azure-migration/","github azure migration",{"config":1065},{"src":1039},{"header":1067,"blurb":1068,"button":1069,"secondaryButton":1074},"Start building faster today","See what your team can do with the intelligent orchestration platform for DevSecOps.\n",{"text":1070,"config":1071},"Get your free trial",{"href":1072,"dataGaName":301,"dataGaLocation":1073},"https://gitlab.com/-/trial_registrations/new?glm_content=default-saas-trial&glm_source=about.gitlab.com/","feature",{"text":774,"config":1075},{"href":626,"dataGaName":306,"dataGaLocation":1073},1786803763101]