223 pull requests in 11 days for the project I never had time to build
Drive a fleet of agents by day, a few deep plans by night, and merge the wins over coffee.
By Julien Dubois Principal Manager, Developer Relations at Microsoft and GitHub. Creator of JHipster.
I always wanted a real developer UI for Spring Boot. Every Spring app is a black box in development. Actuator gives you raw JSON, not a console, so what I wanted was health, metrics, security and tracing in one embedded UI.
I’d shipped a slice of this in JHipster years ago, but only for generated apps. A real console for any Spring Boot app sat on my wishlist for years. The catch is that it’s massive. Around 40 panels, each one a backend plus a frontend plus its own tests, deeply integrated across a dozen JVM subsystems. By hand, one experienced developer would need somewhere between six and a half and eight and a half months. Too big to justify, until I stopped writing the code myself.
Then I did it in 11 days. Not by typing faster. I didn’t even open my IDE. I managed a fleet of AI agents while I architected, reviewed and steered. The agents did the scaffolding, the panels and the tests. I did the judgement.
What I built, BootUI
BootUI is a production-grade Spring Boot 4 starter that adds an embedded, local-only developer console to your app. You add one starter to your pom.xml, run locally, and open the console.
It is a five-module Maven build on Spring Boot 4 and Java 17, integrated across Actuator, Spring Security, Flyway and Liquibase, Hibernate, Micrometer with OTLP, GraalVM, OSV scanning and ArchUnit, published to Maven Central with full CI. The frontend is an embedded Vue 3 single-page app, packaged inside the starter. Each panel is endpoints plus a view plus tests.
There are around 40 feature panels. Health and metrics, a security advisor, a vulnerabilities view, tracing, and more. Those panels look a lot alike, which made them the biggest source of structural repetition in the codebase. That detail matters, and I will come back to why it made the whole thing work.
Eleven days, and how I know the numbers are real
The figures here are derived from git history, PR metadata and code metrics, not from time-tracking logs. Through the tagged 1.0.0 release there were around 264 commits on main and about 223 squash-merged pull requests, landing at roughly 20 a day across 11 days. That came to about 83k total tracked source lines, close to 50k of them Java across around 461 files and 81 test classes, plus 52 Vue components, 40 panels, and 35 end-to-end specs. In all, about 116 test suites.
A cadence of 20 PRs a day with an AI agent co-authoring commits is impossible to reach by hand. The agent did the typing. I dispatched many asynchronous tasks in parallel. The evidence lines up with that. The commit clock runs from around five in the morning to midnight most days, which is consistent with parallel async tasks rather than continuous typing. “Copilot” shows up as a named commit and PR author on about 44 commits, and the repo ships a copilot-instructions.md with per-panel conventions, so the workflow was explicitly agent-oriented. Even on release day I was landing a docs site, a scanner dashboard, token charts and a Hikari fix, which is itself several days of solo work.
Where my own time went was writing prompts, reviewing and merging those 223 PRs, and resolving CI failures around Spring Boot 4, Flyway 11 and OTLP. Review and orchestrate, not write every line.
The honest by-hand comparison is the part people argue about, so I ran it carefully. One experienced Spring Boot and Vue developer, with no AI codegen, would need 6.5 to 8.5 months for the same polished 1.0.0, roughly 1,100 to 1,450 hours of hands-on effort, and the 40 panels are the dominant cost. A COCOMO organic estimate on 50k lines yields more than 100 person-months, which is too high because much of the code is repetitive scaffolding, so a domain-expert solo figure of about 7.5 months is the defensible middle ground. My actual human effort on BootUI was 80 to 110 hours, about two intense solo weeks. That is a calendar speed-up of roughly 17 to 23 times, and a human-hours speed-up of roughly 12 to 17 times.
I was the manager, not the developer
I didn’t open my IDE. I wasn’t the developer. I was the manager. Many agents ran in parallel on the panels, the integrations, the frontend, and the CI and docs, and my job was to brief, review and merge.
Your throughput is not your keyboard. It is your briefs. What blocks a single developer is typing, and what blocks a single agent is you waiting for it to finish. Running many at once removes both, because they come back one after another and there is always something to review. You don’t type faster this way. You ship what used to take months.
A day in the loop
The rhythm that produced 20 merged PRs a day is a simple daily loop, and the day is the engine. I am hands-on all day. I spec, launch, review, merge and re-task, live, and most of the day’s PRs land right there.
The evening is a hand-off. Before I step away I queue a few deep, long-running plans. The night is a bonus, not the engine. A handful of deep autonomous runs finish by morning, which is the minority of the work. Repeat that for about 11 days and you reach a tagged 1.0.0. Six ingredients make the loop work.
Ingredient one, write the specifications
The first thing I write is never code. It is the house rules. An AGENTS.md, which GitHub Copilot reads as copilot-instructions.md, and every agent reads it first. It sets the conventions once, the stack, the build, the tests and the style, with per-panel conventions so 40 panels come out consistent. Mine runs around 700 lines. That is about the right size, because a file that is too big pollutes the context, and it also costs tokens and money on every run.
The high-leverage move is writing the known failures into that file once. Most models were trained on Spring Boot 3, so they struggle with the reworked Jackson API in Spring Boot 4, and 10 agents trained on the same data hit the same wall at the same time. Rather than fix that by hand in each one, I write the fix down once. The same goes for operational traps, like giving every agent its own local Maven repository so parallel installs do not corrupt a shared one.
On top of the house rules I write one spec per task. What to build, where, what “done” looks like, and the acceptance test the agent must make pass. Small, self-contained, no hidden dependencies. The spec is the product now. The better the brief, the less you babysit.
Ingredient two, build the test harness
No agent runs without a test harness. One command compiles and runs the unit and end-to-end tests, and comes back green or red, so an agent can verify its own work before it opens a PR. No tests means you cannot trust the output.
CI is the trust layer. BootUI has about 116 test suites, 81 in Java and 35 in Playwright, and CodeQL plus the end-to-end tests gate every PR to main. The loop does the work. An agent writes code, pushes it, and GitHub Actions sends back the results. If they are red the agent reads the failure, fixes it, commits and pushes again, and the checks run once more. Dependabot keeps the dependencies current alongside all of this. A compiled, typed language like Java helps too, because a hallucinated call often fails to compile before a test ever runs, and the tests catch what the compiler misses. You cannot read every line of 223 PRs. A green build you trust is what makes the volume reviewable.
Ingredient three, split the work and run agents in parallel
Parallelism is the whole point, so the work has to be parallel-ready. The 40 near-identical panels are perfect to fan out, because AI is strong at cloning something and adapting it to something similar. I give one task to one agent, small scope and a clear goal, each on its own branch or worktree so they do not collide. Splitting the work cleanly is an architecture problem before it is a prompting one, and getting it wrong is where the merge conflicts come from.
A fleet is not one chat window. I drove BootUI mostly through the GitHub Copilot coding agent app, because it lets many agents run live on one machine, and I comfortably keep 10 going at once. More than 10 gets complicated for a human to hold in their head, and the laptop starts to slow down. The mobile app runs agents in Docker containers, so I can keep them moving when I am away from my desk. The CLI and the IDE plugin suit smaller fan-out, and all three share the same back end, the Copilot SDK, which is open source, so you can build your own interface on top of it if you want. The rule stays simple. Don’t babysit one agent. Run 10.
Ingredient four, let a few deep plans run overnight
The day is the engine and the night is a bonus shift. Before I log off I hand a few deep, long-running plans to autonomous agents, the big jobs I don’t want to sit and watch. On BootUI those were things like wiring and testing the security filter chains across 37 rules, pushing coverage further across the suites, and reshaping the Actuator data layer in a larger refactor. Each is a long run that lands a few PRs by morning.
For the genuinely tricky work I have the agent criticize its own output with two or three other models. One writes the code, the others analyze and vote on the fix. That is also how I catch hallucinations, because the model that invented something usually stands alone against the others, and it shows up plainly in the logs. A good overnight prompt means everything is done when I come back. A weak one means I have nothing, which is why prompt-writing is worth practicing. The night is a bonus on top of the day, not a replacement for the driving.
Ingredient five, merge the results over coffee
The morning starts over coffee. I triage the few overnight PRs, merge the green ones fast, drop or re-task whatever didn’t land, cherry-pick the good parts of the rest, and then start driving the day’s fleet. When I review a PR I look at three things that stay in sync because they are generated together, the code, its tests, and its documentation. Green tests tell me the code and the tests agree, and I squash and merge.
Review is the real bottleneck. It is not the typing anymore. It is the merging. I don’t merge blind and I don’t merge like crazy, because the day you wave through a large diff without reading it is the day something wrong lands in main. So make review a fast, trusted ritual you run all day, not a line-by-line slog at the end.
Ingredient six, pick the right model for the task
Most of the work went to a workhorse, GPT-5.5 on extra-high reasoning, with around 90 percent of its tokens served from cache. For the tricky parts I brought in Claude Opus 4.8 and Gemini 3.1 Pro, three strong models cross-checking each other to find the best fix. For simple, mechanical tasks a smaller model or Auto mode is fast and cheap, and Auto tends to pick better than I would while carrying its own token rebate.
The economics are driven by the cache more than by the model price. The whole build ran on about 2.7 billion tokens for roughly 2,000 dollars, with around 95 percent served from cache, so most of the run costs a tenth of the headline price. That changes the obvious advice. Swapping to a cheaper model for one small task often bursts the cache and costs more than staying on the model whose context is already warm. If I have a small task, I spawn a separate small agent for it rather than switching the big agent’s model. And I avoid editing AGENTS.md mid-run, because it lives at the top of the cache and one change invalidates it, so I update it at the end of a run instead. Knowing how the cache works matters more than picking the cheapest model.
Why the multiplier was so large
I want to be honest about why BootUI hit a multiplier this large, because not every project will. Three things made this codebase unusually well-suited to agents. First, massive repetition, since around 40 structurally similar panels are cheap for an agent to clone and are the most expensive part by hand. Second, a broad-but-shallow shape, many Spring subsystems each shallow on its own, where the human cost is mostly looking things up, which is exactly what the model already absorbed in training. Third, strong guardrails, because multi-module CI, CodeQL, end-to-end tests and explicit instructions let me accept high throughput safely.
The net effect was a 6.5 to 8.5 month solo effort compressed into 11 days and about two weeks of human attention. The biggest leverage is on large-surface, pattern-heavy, well-tested code, not on hard algorithms. A project that is mostly novel logic with thin tests will not see these numbers, and I would not claim otherwise.
Where this goes wrong
The failure modes are consistent, and most of them trace back to the operator. Scope creep is the first. Tell an agent to build the whole thing and it wanders, so keep one tight goal per task. Missing tests are the second. Without a harness you cannot trust the output and you cannot merge at volume, so the harness comes first and a green build gates every merge.
Giant PRs are the third. A 2,000-line PR is impossible to review well, and review fatigue tempts you to wave it through, so keep the chunks small and reviewable and pace yourself. The wrong model is the fourth. A weak model fails the hard tasks, a strong one is slow and costly on the easy ones, so match the model to the job. When people tell me AI-generated code is not good, the cause is usually one of these. Thin specs, weak tests, oversized PRs, or the wrong model. If the agent generates bad code, that is usually your fault, not the model’s. Most failed runs are a briefing problem.
One page to screenshot
If you take one thing away, take this.
A new Spring Boot console fell out of it
The recipe was the point, but it left behind a real, open-source product. BootUI gives any Spring Boot app an embedded console with live health and metrics, a security advisor that walks your filter chains, an OSV scan of your dependencies, a Flyway and Liquibase data view with a Hibernate advisor, tracing through Micrometer and OTLP, and an architecture view backed by ArchUnit and GraalVM reachability. Add one starter to your pom.xml, run locally, and open the console. The code and the full docs are open.
Write the specs, give them tests, run them wide, and ship what used to take months. Now go build.
This deep dive is adapted from Julien’s Deep Engineering workshop, From Coder to Manager of Agents. Here the slides from the talk.






