GitLab moved rate limiting to AI agents: 14 specs and 30+ merge requests
A GitLab team of three engineers and a set of AI agents ran an experiment: could agents migrate part of a legacy rate-limiting system without lowering the reliability bar? The answer was yes. The agents wrote specs, implemented changes, and prepared merge requests through GitLab Duo Agent Platform, while humans owned the architecture and final review. The result: 14 numbered specs and more than 30 merge requests to the labkit-ruby library.
AI-processed from GitLab Blog; edited by Hamidun News
A small GitLab team ran an experiment in which AI agents helped migrate part of a legacy rate-limiting system to a single implementation in the labkit-ruby library without lowering the reliability bar. The team itself calls the experiment a success.
What the system looked like before the migration
For years, GitLab ran two rate-limiting paths side by side: the application-level `Gitlab::ApplicationRateLimiter` with 121 keys, and a separate Rack-level system. The goal of the migration was to merge both paths into a single implementation in `labkit-ruby`, so the system would be observable, testable, and behave the same way across every part of the product. Every request to the GitLab monolith passes through this system, so its failures need to be visible and reversible.
Who worked on the migration, and how
Three GitLab engineers and a set of AI agents worked on the project.
- Max Woolf, Staff Backend Engineer on the API Platform team, owned the monolith side and ran most of the releases
- Bob Van Landuyt from the Scalability team owned the library itself and the solution's architecture
- Several other engineers joined on a targeted basis to get up to speed on the context and help with code and reviews
- The team used GitLab Duo Agent Platform and GitLab Duo Code Review
The agents read context, drafted specs, implemented tightly scoped changes, wrote tests, and did a first-pass review of merge requests. Humans kept control of scope, architecture, releases, and the final call.
How the workflow was structured
The team followed a strict loop: read the epic, write a spec, run an adversarial review of it, start implementation only once blockers were cleared, verify the result with explicit evidence, run an adversarial review of the merge request itself, escalate to human review, and only then merge. Adversarial review was capped at two rounds; after that, the decision always went to a human.
- The team shipped 14 numbered specs over the course of the project
- More than 30 merge requests landed in the `labkit-ruby` library
- In practice, how strictly engineers followed the loop varied: Bob Van Landuyt often ran several rounds of spec writing and review on his own before sharing a common artifact with the team
What it means
GitLab's experiment shows that AI agents can already take on the routine parts of a legacy-code migration — spec drafts, implementation, and tests. But it is the strict workflow, team structure, and mandatory human review that determine whether the system stays as reliable as before. The experiment's authors say it plainly: the agents work, but they also expose weak spots in how a team usually organizes its work. The review loop and observability turned out to matter just as much as the agents' capabilities.
FAQ
How many people worked on GitLab's rate-limiting migration?
Three GitLab engineers worked on the project — Max Woolf, Bob Van Landuyt, and several others who joined on a targeted basis — alongside a set of AI agents built on GitLab Duo Agent Platform.
How much code and how many specs did the team ship?
Over the course of the experiment, the team produced 14 numbered specs and submitted more than 30 merge requests to the labkit-ruby library.
Key Questions Answered
How many people worked on GitLab's rate-limiting migration?
Three GitLab engineers worked on the project — Max Woolf, Bob Van Landuyt, and several others who joined on a targeted basis — alongside a set of AI agents built on GitLab Duo Agent Platform.
How much code and how many specs did the team ship?
Over the course of the experiment, the team produced 14 numbered specs and submitted more than 30 merge requests to the labkit-ruby library.
What the system looked like before the migration?
For years, GitLab ran two rate-limiting paths side by side: the application-level `Gitlab::ApplicationRateLimiter` with 121 keys, and a separate Rack-level system. The goal of the migration was to merge both paths into a single implementation in `labkit-ruby`, so the system would be observable, testable, and behave the same way across every part of the product. Every request to the GitLab monolith passes through this system, so its failures need to be visible and reversible.
Test Frontier LLMs & Autonomous Agents in One Workspace
Run Claude Opus 5.5, GPT-6, Gemini 3.1, and DeepSeek side-by-side in Nomad AI (nomadnet.ai) — unified model routing, deep research, and multimodal workflows under one subscription.
The AI world, distilled — once a week
Seven stories that actually mattered, hand-picked. No noise, no reposts, no press releases.
Done! Check your inbox for a confirmation.