How we 3×’d PRs in 6 months, and how you can too
Have you ever watched someone try to speedrun a video game?
It takes most people hours to beat a game like Super Mario Bros. The world record is just under five minutes. Speedrunning is a competitive hobby where players try to finish a game as fast as possible, down to the second.
You might think it takes superhuman reflexes. Do the same thing every time, just mechanically faster. It’s not that simple. Speedrunners spend most of their time studying the route, finding shortcuts, and engineering the system and environment to go faster each time.
Somehow, building an autonomous software factory feels the same. We wanted to see how fast we could get software into the hands of our customers.
After six months, we’ve 3x’d our PRs.
Why does speed matter, really?
We wanted to ship more PRs, and speed is how you do that with the same headcount. On the surface, that might sound like a vanity metric. PRs can be artificially inflated, and more code isn’t inherently valuable. But teams used to think the same about engagement, until they saw how it drives stickiness, retention, and growth.
PRs are a leading indicator of customer value because each one is an experiment. A faster software factory means you can put more ideas in front of your customers to figure out what works. The goal is to run more experiments and see good ideas surface much faster.
Agentic coding assistants have led to a new builder’s block, where the holdup is deciding what to build.— Andrew Ng, DeepLearning.AI founder
AI made building cheap. Knowing what to build is the new game. Speeding up your software factory lets you take more shots at what to build. With the same team, that’s how you out-iterate everyone else.
It’s also how you move engineers from in the software loop, doing every step, to on the loop, steering it.
The software development pipeline
Think of shipping software as a pipeline. An idea becomes code, the code gets validated and reviewed, and then it gets deployed to production. That path is the same whether the change is a one-line bug fix, a new feature release, or a sweeping migration across the codebase. Simple enough. But for us, it slowed down at a few specific steps.
The pipeline gates slowing us down
Before we made a bet on our software factory, most steps in the pipeline were manual. Engineers worked in local environments they had to assemble themselves. Setting one up meant figuring out which dependencies (and the dependencies of dependencies) were needed for testing, then spinning them up. The local frontend alone could take up to 3 minutes to start, and CI runs could stretch beyond 30 minutes. On a bad day, an engineer could lose most of their time just setting up and shipping a single change.
Despite its flaws, this design worked for years because writing code was the slowest part of the system. It was a natural limitation on how many changes could enter the pipeline at once. But agents changed that. Faster code generation meant that a trickle of PRs suddenly became a flood, and the manual validation and review became the stoppage points.
This is the Theory of Constraints, the idea that every system has one main bottleneck that limits how fast the whole thing can move. Speeding up one part of the system moves the goal post to the next-slowest step. What a beautifully messy problem to solve! We were up for the challenge.
For us, the heaviest gates to push through were the ones that stayed largely manual: validation and review. Like any speedrun, we had to shave time off the route.
Rebuilding the pipeline’s foundations
So we rebuilt the foundations under the pipeline and opened those two gates. The PR cycle time is now under an hour, which is 7x faster than before. That’s 2.5 hours below the industry benchmark.
When Shopify built their coding agent, they found something interesting: What’s good for agents is good for humans, too. We agree. An agent needs the same things a good engineer does: a clean codebase, fast feedback when something breaks, and an environment that comes up the same way every time. Fix those for agents, and engineers get the benefits too.
But we hadn’t made these fixes a priority. For years, we optimized for what we shipped, but agents forced us to finally fix how we ship. Brightside? They also helped us improve much faster than expected.
That improvement started with the foundations the pipeline runs on. We rebuilt three areas: the CI every PR passes through, the local environment engineers work in, and the legacy patterns that tripped up humans and agents. These changes made every step of the pipeline faster.
Custom local dev CLI
We run a large, sprawling set of services, and getting them all running locally was a slog. Local setup was app-specific, so to run the full stack, you had to stand up several environments, keep 5+ processes alive, and hope nothing broke along the way. Putting each service in its own container wouldn’t have helped because machines would run out of memory.
So we built a CLI tool that uses devbox to inject dependencies, which keeps startup times fast and less resource-intensive than Docker. It lets engineers run our large infrastructure locally with one command, so the full stack comes up in 28 seconds.
See how it works
devboxuses NixOS to inject dependencies per shell, keeping environments fast and lightweight.- The CLI is a task multiplexer that abstracts how each app server starts.
- It finds services by walking the filesystem or an ENV override, which matters now that engineers use worktrees across a multi-repo setup.
- A one-time set of
maketasks stands up the database with Docker.
Faster CI
Our frontend CI had been creeping up for years and began approaching 30 minutes. We tackled it in three ways:
- Build only what changed. We leaned into our Turborepo monorepo setup with affected-based builds, so CI only touches the packages that a change actually impacts rather than rebuilding everything. We also compiled packages so their outputs could be cached and reused, and paired that with TypeScript isolated declarations so type info is emitted per package without cross-package dependencies. Together, this gave us more cache hits, more parallelism, and fewer redundant rebuilds.
- Trade JavaScript tooling for Rust and Go. The single biggest lever was replacing our JS-based toolchain with native equivalents. Nearly every tool got roughly an order of magnitude faster.
See the full toolchain
- TypeScript type checking:
tsc → tsgo(~10x faster) - Linting:
ESLint → oxlint(~10x faster) - Formatting:
Prettier → oxfmt(~10x faster) - Bundling libraries:
tsc builds → tsdown(~10x faster) - Bundling apps:
esbuild → rolldown(~2–3x faster) - Testing:
Jest → Vitest+ fixed flaky tests (~50% faster)
- TypeScript type checking:
- Parallelize the pipeline itself. We restructured the CI pipeline to run independent stages concurrently rather than in sequence, squeezing out the remaining wall-clock time that faster tools alone couldn’t recover.
A pipeline that once ran at 30 minutes now finishes at a fraction of that time, with most changes clearing CI before an engineer has finished writing their PR description.
Automated legacy migrations
We pointed agents at the patterns that confused them most and let them run the migrations themselves. The largest migration was three competing design systems in one codebase: Ant Design, in-house Cerulean, and core-ui (Radix UI + CVA + Tailwind). We’re deprecating the first two and standardizing on core-ui. We did the same with i18n, reducing three translation systems into one. Then we codified the changes as agent rules and skills that are backed by lint checks, so agents (and engineers) don’t drift back into old patterns. These were migrations we’d written off for years, but agents finally made them possible.
How we develop now
Improving our developer experience, or DevEx, changed how people code in expected and unexpected ways. DevEx is the whole path an engineer travels from idea to shipped: the tools, the environments, and every step in between. The obvious: Agents write a lot of code now. More surprising: Where that code gets written.
Agent-generated code
Like most orgs, our engineers shifted from writing code by hand to steering Cursor, Codex, and Claude Code agents. Nearly all frontend code and most backend code is now agent-generated.
CI as our new dev environment
Once frontend CI dropped below 5 minutes, working locally was no longer the fast option. Engineers now push a branch, let CI run, and review it in GitHub. The CI went from the gate you clear after you build something to the new dev environment for most engineers.
This lets engineers parallelize their work. Because it runs in the cloud, they aren’t limited to one change at a time. They can kick off 20 PRs before logging off and review them the next morning. The only limit is knowing what to build, which is why a migration might hit 100 PRs, while feature development stays around 1 to 3.
Gate 1: Validation
Validation is where we confirm a change does what it’s supposed to do. Every change is validated before it ships, but the process was slow. Spinning up the test build used to take 25 minutes, which was long enough that you’d start another task while you waited, then lose time and focus switching back and forth.
So we made it faster. Automated checks handle most of it, but some things you only catch by trying the change yourself. For that, you can ship a PR and get a working preview in a couple of minutes with no local setup required.
Frontend previews
For a frontend change, we can add a label to the PR, and GitHub Actions builds the assets, pushes them to S3, and our frontend server loads them as a working copy of the app. It comes with dev tools to flip feature flags and settings, and a deep verification link that takes you straight to the page your change affects. The preview is ready in 30 seconds to 5 minutes, and checking a change takes 2 to 5 minutes of click-through with no local setup needed.
Backend ephemerals
Backend changes get validated through ephemerals. Add a label to a PR, and GitHub Actions spins up a throwaway copy of the full stack in the cloud with Argo. An engineer or an agent can then hit the APIs or run the feature end-to-end before it merges. It’s 2–3x faster than it used to be.
Gate 2: Review and approval
Engineers used to spend a large part of their day reviewing other people’s changes or waiting for someone to review theirs. Across the team, review was one of the slowest steps in the pipeline.
We changed that with a risk model. It scores how risky each change is, and low-risk changes merge automatically with no human in the loop. Anything medium-risk or above still goes to a person, and we cleaned up our code owners so it lands with someone who knows that part of the codebase.
Automated code review
We use Cursor’s Bugbot on every PR in CI. It comes out of the box, and we add context when it misses things. So far, it catches bugs that most humans used to let through. Even though we’ve tripled the PRs we ship, bug reports have fallen by more than half (from 715 a month to 319), and high-priority issue reports have also dropped. More code hasn’t meant worse code, and Bugbot is a large reason why.
Risk-based auto-approval
We introduced a risk model that scores each change on size, scope, what part of the codebase it touches, test coverage, and whether it modifies public APIs or data models. If a change is low-risk and review comments are resolved, it merges on its own without a human in the loop. When someone catches a change that shouldn’t have merged, it goes into an eval suite, and we tune the risk model to prevent it from happening again.
SOC2 compliance
How does auto-approval pass a SOC2 audit? Turns out, SOC2 doesn’t need a human to click approve. What it does need is demonstrable controls: documented criteria, logged decisions, and a way to override. So we documented all of it, including what qualifies for auto-approval, what still needs a human, and how to escalate. Approval and validation are logged as separate signals, so every decision can be audited after the fact. We brought compliance in early so we didn’t have to redesign it later.
A culture of AI transformation
We improved our automated systems and tooling and got far, fast. But the harder part was creating the culture to get there.
Wade Chambers, who runs engineering at Amplitude, describes engineers as craftspeople who built their careers on figuring out clean abstractions, reusable interfaces, and code that others can build on. The idea that an agent can do that just as well isn’t easy to hear. Getting past it to reach broader adoption took two waves: AI fluency (moving from chat-based questions to goal-oriented tasks), and then using that fluency to disrupt entire workflows.
We put a lot of thought into getting both right, and we still had a few hiccups along the way.
AI progression is largely not a technical issue. It’s a cultural one.— Wade Chambers, Chief Engineering Officer, Amplitude
Start with the leaders
Leader ambition can be one of the biggest drags on organizational velocity. You can’t ask engineers to hand their work to an agent if their own leaders won’t. So we made them go first, literally. Amplitude’s chief engineering officer asked senior leaders to vibe code in front of the entire engineering, product, and design org. Leaders experienced the highs and lows of agentic building (and breaking) live on stage. They then took that live-coding exercise back to their own teams to repeat it. This made it feel like leaders were co-developing with their teams, rather than simply talking at them.
Let anyone ship
The biggest positive was handing over the keys to the kingdom and letting non-engineers ship code. Designers, PMs, and even marketers use Claude and Cursor to ship anything from bug fixes to product improvements. Non-engineers make up about 5% of our PRs, but they’re high-value changes, and that number continues to grow.
The best part is that these changes happen much faster because there’s no more handoff to eng. And the fixes are often better because the person closest to the problem makes the fix. Jingshu Zhao, one of our principal designers, started with a small PR to address a button alignment issue. Soon after, she used Claude Code to reorganize our navigation and sunset sections with low usage. It was a change the broader team wanted to make but was never able to prioritize, so she did it herself.
Jingshu’s changes go beyond the UI. While testing our agent-creation templates, she noticed the agents were guessing instead of asking, like picking a funnel name on their own instead of asking which one the user meant. She used Claude Code to trace it across both the template and tool definitions, and shipped consistent fixes across every template.
Designers can now unblock product improvements without competing with engineering priorities. It makes me feel like I’m contributing to product development. Not just designing the UI, but improving the quality and behavior of the AI experience itself.— Jingshu Zhao, Principal Designer, Amplitude
Getting non-engineers to code was only possible with the setup, validation, and review changes we made to our software factory. Standing up the whole stack only takes 10 to 15 minutes (down from 1 to 4 days), so there’s no barrier to getting started. Preview links let them check a change without running anything locally, and each PR deep-links to the exact page that changed, so verification is only a short click-through.
Our advice for getting non-engineers on board is to make it wildly easy for them. That means strong documentation and training on things like first-time setup and choosing an environment. We also have an internal marketplace for shared skills that anyone can access.
Spend where it counts
We don’t cap what people spend on AI. If anything, we encourage more of it. But we’ve also learned that the model you pick matters just as much as how you run it, so we pay attention to high bills and see whether a lighter model would work. A less expensive model lets you run two or three times as much with the same budget, so you aren’t limited on how much you can justify doing. We recently refactored a major backend to have proper typings for only $500. We used a cheaper model and a well-planned script that was run locally. That same work could have easily cost tens of thousands of dollars. So our guidance is to not feel constrained by tokens, but also to choose the right model for the job.
It’s never perfect
We made some mistakes early on (and will make more…). The first was spreading the effort too thinly across the org (the peanut butter approach). We eventually shifted to a tiger team model and embedded AI-pilled engineers across teams to share their knowledge.
Another mistake was trying to bite off more than we could chew and build agents before we had any of the infrastructure in place. But there was no need for us to jump to the end. Prioritizing our foundational DevEx is what ultimately helped us move faster.
The receipts
What we learned
We set out to speedrun shipping software, and we were able to 3x our PRs. These were the big lessons we learned along the way.
First, fix the foundations of your software factory. Even the best engineers and agents can’t outrun a 30-minute CI. Second, expect the constraints to keep moving. Every gate you open only pushes the slowdown to the next one. Finally, treat speed and more PRs as a way to find what works faster than anyone else can.
Now that building is cheap, the game is knowing what to build and shipping it first. That’s the real speedrun.
To the builders: Enjoy the run. And if you need help building your own software factory, send us a note: devex@amplitude.com.