Owen Gretzinger β head of engineering at Boardy, the AI "superconnector" startup β posted an article with 184,000 views that reads less like a blog post and more like a set of blueprints: "How I made our CI 20x faster (steal this)." A year ago, a pull request at Boardy waited up to 40 minutes for CI. Now it waits 2. And the reason it matters is not the usual "developer happiness" framing. It is that every PR they ship is now written by coding agents, and agents do not get tired of pushing β they push, wait for CI, fix the red check, and push again. When code-writing got 10x faster and CI didn't, CI became the thing you wait on. So Gretzinger spent a month treating CI like a product, doing most of the work from his phone, through an internal agent in Slack, and left the receipts: nine numbered optimizations, each with a before/after number, and a final line that is the most interesting part of the whole piece β "the slowest part of the loop is me clicking merge." This post walks through every one of the nine changes and the numbers behind them, then zooms out to what the article actually proves: that the agent-economics argument about developer infrastructure is no longer theoretical, and that the bottleneck is now migrating from CI toward the human in the loop.
Why CI Is Now The Bottleneck (And Why "Agent-Economics" Is The Right Frame)
The opening two sentences do all the framing: "A year ago, a PR at Boardy waited up to 40 minutes for CI. Now it waits 2." The obvious reading is "faster CI is nice." The article's reading is sharper, and it is the reading that makes the whole thing worth stealing. "That matters more than ever, because every PR we ship is written with coding agents, and agents don't get tired of pushing. They push, wait for CI, fix the red check, push again. When writing code gets 10x faster and CI doesn't, CI is what you're waiting on."
That is the entire thesis of a whole generation of posts about agent-driven development, compressed into two lines, and it is the same logic that Anthropic's Scion post (which we covered recently) built an entire version-control system on. There, the numbers were 2,500 merges a day in May 2026 growing to 30,000 by September β a 12x jump in four months β and the company's own statement that "every bottleneck we remove immediately leads to a further increase in the amount of code we produce." Gretzinger's article is the same story at startup scale, and it is the version of the story a normal engineering team can actually act on. Anthropic built new infrastructure. Boardy, an 11-person team, re-tuned the infrastructure they already had β and got a 20x result on the loop that matters to them. The difference in ambition is the difference in scale; the underlying physics is identical. Code production got cheap and fast. Everything else in the loop β review, CI, deploy, merge β is now the constraint, and it will be re-optimized exactly in proportion to how much of the code is written by agents that never stop pushing.
There is a second, subtler point in those opening lines, and it is the one that makes the article a field manual rather than a list of tips. Gretzinger says he "treated CI like a product" and did "most of the work using an internal agent in Slack from my phone." He is not just describing how he made CI faster. He is describing who made it faster. The agent that writes the PRs is the same kind of agent that audits the CI runs, benchmarks the typechecker from his repo, and opens the PR that merges the optimization. The tool that produces the load (agents writing code) is also the tool that optimizes the system that absorbs the load (CI). That is a genuinely new operating model, and it is worth sitting with, because it means the old "we'll optimize CI during a dedicated engineering sprint" model is being displaced by "an agent watches CI continuously and fixes what it finds, on demand, from a phone."
The Nine Fixes, With The Numbers
The article is a list of nine numbered changes (plus three quick ones folded into the sixth). Each has a before/after number, which is what makes it stealable. Let's go through them in order, because the order is roughly the order of impact, and the first one is a category error that most teams would never think to fix.
1. Get off GitHub's default runners (40 min β ~10 min)
This is the biggest single win, and it is the one that reframes everything. "Our jobs waited up to 11 minutes on GitHub's hosted runners just to get a machine. Now they start in 8 seconds." They moved to Blacksmith, a managed GitHub-Actions-runner replacement that runs on bare metal in its own regions (Gretzinger also names Vercel CI, boat.dev, "and a dozen more" as competitors β the runner-replacement market is now crowded). One line per job. The number that should reframe your thinking is not "CI got 4x faster." It is that a 5-second job that waits 10 minutes for a machine is a 10-minute job. He explicitly calls out that they left their two smallest jobs on GitHub because they "only run for a few seconds" β and those tiny jobs "became the slowest part of the pipeline." The queue time, not the work time, was the cost. This is the same failure mode as every other resource pool: a cheap task paying the full price of a contended scheduler. The fix was to move every job, including the trivial ones, off the contended pool. Runners got them from 40 minutes to about 10. "Everything below is the rest."
2. Replace ESLint with Oxlint (2 min β 5 s)
A straightforward tool swap: the Rust-based Oxlint replaces ESLint, taking lint from 2 minutes to 5 seconds. But the second sentence is the agent-economics gem: "Agents don't get annoyed by strict rules, so turn on everything you can. Enforce the 'black hole of success.'" In the human era, strict lint rules were a trade-off β every extra rule was a small tax on developer experience, so teams calibrated the rule set to keep the friction tolerable. In the agent era, that trade-off disappears. The agent does not get annoyed. It just fixes what the linter flags, faster than a human ever could. So the optimal rule set under an agent is not the "what a human would tolerate" set. It is every rule that is correct. You can afford to be strict to a degree that would have been miserable for humans, because the strictness is now enforced by something that has no patience cost. That is a quiet but real shift in how you should configure your tooling once the operator is a model.
3. Switch typecheckers every time a faster one ships (70 s β <5 s)
"We switched our typechecker three times in a month." The numbers: their server's cold typecheck was 70 seconds on tsc, TypeScript 7 (the native compiler) took it to 13 seconds, and bun check does it in under 5 seconds, so that is what CI runs. Locally, tsrs does it in 0.6 seconds. This is the "continuous tooling arbitrage" pattern: the type-checking space is in a period of rapid, competing improvement (native TypeScript, bun's check, standalone Rust reimplementations), and the winning move is not to pick the best tool once, but to re-benchmark and re-adopt on every release. And the agent is what makes that pattern affordable: "I was at a dinner when Jarred posted that bun check was getting up to 7x faster. So I pasted the post into an internal Slack agent. Six minutes later it had benchmarks from our repo. Twenty minutes after that the PR was merged." The entire loop β read the announcement, benchmark it against our specific repo, open the PR to switch β happened in 20 minutes, unattended, from a phone, while the engineer was at dinner. That is not a typechecker story. That is a story about what "maintaining your toolchain" looks like when the maintenance is delegated to an agent that watches the space.
4. Shard your tests onto bigger machines (bought cores, not shards)
"We split one 8-minute test target into six shards on 8-vCPU machines, each with its own database." The counterintuitive part: "Bigger machines mattered more than more shards. Each shard spent most of its CPU loading modules and almost none of it running tests, so we bought cores, not shards." This is a load-profile insight. The bottleneck in a test shard is not the test execution; it is the fixed cost of loading the module graph. More shards with fewer cores each does not help, because each shard still pays the same per-shard load cost. More cores per shard does, because the load cost is parallelizable. The general lesson: before you shard, profile what the shard is actually doing. If it is mostly fixed setup cost, you need bigger machines, not more of them. This is the kind of thing that looks obvious in hindsight and is invisible when you are just watching the clock.
5. Stop reloading your app for every test file (100 s β 35 s per shard)
A one-line configuration change with a big effect: Vitest gives every test file a fresh worker by default, so at Boardy every single test file imported their entire NestJS app from scratch. Setting isolate: false makes the app load once and persist across files. "Each of our shards went from 100 seconds to 35." The cost is that "tests will start leaking into each other" β so the fix requires a state-reset hook after every file, and, again, an agent-aware move: "tell your agents what a test has to clean up." He notes that Linear found the same thing (the article references Linear's engineering note on the identical Vitest behavior). The pattern here is a recurring one in the article: the fastest wins are often a single configuration flag that changes a hidden per-unit fixed cost, and the flag is discoverable by reading the tool's defaults and asking "are we paying this cost on every unit, or once?"
6. Fix setup (168 s β 74 s) β the one nobody looks at
This is the most instructive fix in the list, because it is the one that was invisible for a year. "Last week our server test job took 168 seconds. Now it takes 74. The tests inside it barely changed. Almost all of that came from setup, which is the part nobody looks at (and agents missed initially)." The biggest piece came from an audit: he "asked an agent to pull our last 150 runs and split every job into waiting, setup and running." It found that half the test jobs were missing the dependency cache. The root cause is a subtle GitHub Actions behavior: "GitHub scopes PR caches to their own branch, and nothing seeded one from main, so most PRs started cold." That bug "had been there all year. Nobody noticed because nobody was sitting there watching CI. The agents were, and they just retried instead of fixing the actual issue." Read that last sentence again. The agents had been absorbing a year of slow CI by retrying β the red or slow check, then push again β and the retrying was masking the setup cost instead of exposing it. The agent's patience, which is a feature for the push-wait-fix loop, was a bug for diagnostics: it meant the slow setup never showed up as a failure anyone had to investigate. It only showed up when an agent was explicitly asked to look at the runs. The three quick fixes folded in here: cache node_modules (restores in 13 s, replacing a 33 s install), use a blobless clone (filter: blob:none, not a shallow clone β "shallow breaks anything that reads git history" β checkout from 36 s to 12 s), and match parallelism to your cores ("our 4-vCPU job was running 8 tasks at once. Halving the concurrency was just as fast and killed a flaky test").
7. Run everything in parallel
"Lint, typecheck, build and tests all run at once. A PR takes as long as the slowest one." And then the second half, which is where parallelism stops being a default and becomes a craft: "Then look at what else your slowest job is doing. Our first test shard was also running migration checks and other apps' tests, so it always finished last. Moving those into their own job cut 2 minutes." In a parallel pipeline, the total time is the time of the critical path β the slowest job. So the optimization is not just "run in parallel" (that is the default everyone thinks of) but "identify the job on the critical path and remove everything from it that does not have to be there." The migration checks and other apps' tests were riding along on the first shard by accident, and their presence was setting the floor for the whole pipeline. Unload the critical path, and the parallel pipeline's benefit compounds.
8. Only run what a PR touches (nx affected + nightly full suite)
"We use nx affected so a PR only tests the projects it changed, and run the full suite every night on main." This is the standard "impact-based" CI pattern β run the minimal set of tests affected by the diff, and keep the full suite as a nightly safety net so you are not betting the whole codebase on the diff-detection being correct. The interesting addition is the next sentence: "Then test the skip logic itself. We hid a server change from Nx on purpose and all six shards skipped their tests and reported green. Now that fails the run." This is a genuinely important and under-appreciated point. Impact-based CI has a failure mode where the skip is wrong β a change that should have triggered tests does not, and the PR goes green with zero relevant coverage. Most teams implement the skip logic and trust it. Boardy adversarially tested it: they deliberately made a change that Nx's dependency graph did not see, watched all six shards skip and report green (the exact silent-failure they feared), and then added a guard that makes that scenario fail the run. The lesson generalizes: when you make the pipeline cheaper by running less, you must add a test that the "less" is correct. Otherwise you have traded a slow pipeline for an unreliable one, which is worse.
9. Run the checks before every push (<9 s locally)
"Our pre-push hook runs format, lint and typecheck on changed files in under 9 seconds. An agent that hits a type error locally fixes it in seconds instead of waiting for CI." And the agent-aware detail: "Put it in a hook rather than a line in AGENTS.md, because agents skip steps." This is the anti-hallucination move. You cannot rely on an agent remembering to run the checks β the instruction in the system prompt is skipped, the way humans skip instructions. A hook is a hard gate: the push literally does not happen until the checks pass. It is the difference between "please run the linter" and "the linter runs, and the push is blocked if it fails." For agents specifically, the pre-push hook compresses the inner loop from "push, wait 2 minutes, get a red check, fix, push again" to "hit the type error in 9 seconds locally, fix it, push green." The agent's iteration speed is now bounded by the local check, not the CI round-trip. That is where the 2-minute CI and the 9-second pre-push hook combine to make the whole loop feel instant to the agent.
What It Costs: The Number That Matters Most
The section titled "What it costs" has one sentence, and it is the economic heart of the article: "Our CI bill went from $230 a month to $4,300, but it's the cheapest money we spend on making agents faster." That is an 18x cost increase, and they paid it gladly. The reason is the ratio. A 40-minute CI loop means an agent sitting idle 40 minutes per iteration β or, more precisely, a human's attention being consumed by babysitting those 40 minutes, or throughput being capped by them. A 2-minute loop means the agent can do roughly 20x more push-wait-fix cycles in the same wall-clock time, or a human can walk away and come back to green. The $4,070/month delta is buying 20x more agent throughput. If each agent iteration moves real work forward, the cost of the faster runners and bigger machines is trivially outweighed by the throughput. This is the "agent-economics" argument made concrete with a dollar figure: the cost of CI is not the CI bill, it is the throughput the CI bill is gating. Once the code is written by agents that do not stop, the binding constraint is the loop time, and every dollar that shortens the loop is one of the highest-ROI dollars an engineering team spends.
What's Next: "The Slowest Part of the Loop Is Me"
The closing section is the most forward-looking part of the article, and it lands the joke while making a serious point. "Now that agents write the code and CI only takes 2 minutes, the slowest part of the loop is me clicking merge. With dozens of agent sessions going at once, sometimes it still takes a while for me to get work across the finish line. So it's time to address the next biggest bottleneck: me."
This is the natural consequence of the whole thesis, stated plainly. The agent-economics logic does not stop at CI. It propagates. If code production is fast, and CI is fast, and the local checks are fast, then the remaining serial human in the loop β the person who reviews, approves, and clicks merge β becomes the rate-limiting step. At Boardy, with "dozens of agent sessions going at once," Owen himself is the bottleneck. The article does not solve that problem (that is the next article, presumably), but it correctly identifies it, and it is the exact same move Anthropic made in the code-review post we covered β moving from "human reads every line" to "human vets intent, automation handles the rest." The trajectory is clear and it is the same at every scale we have now seen documented: the bottleneck in the agent-driven development loop keeps migrating toward the human, and the engineering work keeps migrating ahead of it. First it was code (agents write it). Then it was the infrastructure around the code (CI, which Boardy just fixed and Anthropic is rebuilding as Scion). Now it is the approval step (a human clicking merge). The next optimization, for Boardy and for everyone else, is the human in the loop.
What To Actually Steal (The 15-Minute Version)
The article's own instruction is "Give this article to your agent and have it do the same to yours." That is the right move, because most of the wins are discoverable by an agent that is given the task and access to the repo and the CI history. But if you want the minimum-viable version β the changes that are low-risk, high-impact, and do not require a month of project β these are the ones to do first, in order:
- Measure where the time actually goes. This is the fix that found the year-old cache bug. Ask an agent to pull your last ~150 CI runs and split every job into waiting (queue time), setup (checkout, install, cache restore), and running (actual work). You will be surprised by the ratio. This is the single highest-value action in the article, and it costs one prompt.
- Get off the default runners. The queue-time fix. Blacksmith is the named option (bare-metal GitHub-Actions-compatible runners, one-line change per job), and the market is crowded now (Vercel CI, boat.dev, and more). Even moving only your long-running jobs will cut the biggest chunk. Move the tiny ones too, per the "5-second job is a 10-minute job" lesson.
- Check your dependency cache is actually working on PRs. The GitHub-Actions scoping behavior (PR caches scoped to their own branch, not seeded from main) is a real, common bug. If half your jobs are starting cold, this is your 168β74s fix.
- Turn on every lint rule you can. The agent-economics shift: the "developer friction" cost of strictness is now paid by a model that does not get annoyed. Enforce the black hole of success.
- Re-benchmark your typechecker on a schedule. tsc β native TypeScript β bun check β tsrs is a 70s β 13s β 5s β 0.6s path that happened in a single month. The tool is changing faster than most teams re-evaluate it. Make the re-evaluation a thing an agent does when a new version ships.
What This Proves About The Agent-Economics Argument
Stepping back from the specific fixes, the article is evidence for three broader claims that have been getting more airtime in the last few months, and it is worth stating them precisely because they are now backed by a named, real, non-frontier-lab team with real numbers.
1. The CI bottleneck is real, and it is now the binding constraint for agent throughput
For a year, the argument was theoretical: "agents write code faster than CI can verify it, so CI will be the bottleneck." Boardy's 40β2 minute number, with the explicit statement that every PR is agent-written, is that argument made concrete. And it is not a frontier-lab phenomenon. It is an 11-person startup. The Scion post was the same argument at the extreme end (30,000 merges/day, new version control). This is the same argument at the other end (an 11-person team re-tuning GitHub Actions). The physics does not depend on scale; only the response does.
2. The optimization itself is now an agent task, not a human project
This is the under-appreciated part. Gretzinger did not run a "CI optimization sprint" with a team. He ran an agent, from his phone, in Slack, that audited the runs, benchmarked the tools, and opened the PRs. The bun-check switch (read the announcement β benchmark from our repo β PR merged) happened in 20 minutes while he was at dinner. The cache bug was found by an agent pulling 150 runs. The 20,000-test audit ("almost nothing worth cutting") was an agent. The pattern is: the agent that generates the load is also the agent that optimizes the system absorbing the load. That means "keeping your toolchain fast" is no longer a recurring human project. It is a standing agent task. The teams that internalize that will have a structural advantage, because their infrastructure will be continuously re-tuned by the same agents that are putting load on it, and the teams that do not will keep paying the queue-time and setup-time tax they could have eliminated with a prompt.
3. The next bottleneck is the human, and the article correctly identifies it
The "me clicking merge" closer is not a joke that ends the piece; it is the next line item in the same optimization. The agent-economics logic propagates past CI, past the local checks, to the approval step. The teams that get to 2-minute CI and then discover that a human is the slowest component will face the same question Anthropic did in the code-review post: how do you keep human judgment (which you want) in the loop without making human attention the rate limit? Boardy has not answered that yet. The fact that they have correctly identified it, and that the answer is the same direction of travel as the code-review automation we have already seen documented, is the signal. The bottleneck is migrating toward the human, and the next round of engineering work β automated review, intent-based approval, confidence-gated merges β is where it is going.
The three takeaways
Bottom Line
Owen Gretzinger's article is one of the most useful pieces of agent-engineering writing to come out in the last few months, and it is useful for a reason that goes beyond the specific fixes. It is a named, real, small team with real numbers, demonstrating that the "CI is the bottleneck" argument is not a frontier-lab projection. It is an 11-person startup that went from 40 minutes to 2 minutes by re-tuning the GitHub Actions pipeline they already had, and the single most important reframe is the economic one: the CI bill went from $230 to $4,300 a month, and it is "the cheapest money we spend on making agents faster," because what you are buying is not faster CI, you are buying 20x more agent throughput. The individual fixes β get off the default runners, swap the linter and typechecker on a re-benchmark schedule, shard onto bigger machines, stop reloading the app per test file, fix the setup that nobody looks at, parallelize and unload the critical path, run only what a PR touches and then test the skip logic, and gate the push with a local hook β are each individually stealable, and most of them are discoverable by an agent given the task and the repo. But the deeper point is the operating model: the agent that writes the code is the same agent that audits the CI, benchmarks the tools, and merges the optimization, running from a Slack channel on a phone. That means "keeping the toolchain fast" stops being a recurring human project and becomes a standing agent task. And the closer β "the slowest part of the loop is me clicking merge" β is the correct identification of where the bottleneck is going next. The trajectory is the same at every scale now documented: agents took code, then the infrastructure around code, and now the approval step is the rate limit. The teams that see that coming and start automating the human-in-the-loop step β the way the code-review teams already have β will be the ones still moving when everyone else is waiting on a merge button.
References
- Owen Gretzinger β "How I made our CI 20x faster (steal this)" (X Article, Oct 30, 2026, 184K views) [x.com]
- Owen Gretzinger β Head of Engineering, Boardy (AI "superconnector," 160k+ introductions) [LinkedIn]
- Blacksmith β managed GitHub Actions runners on bare metal (the named runner replacement) [blacksmith.sh]
- Oxlint β Rust-based ESLint replacement [oxlint.rs]
- Bun β
bun checktypechecker [bun.sh] - Anthropic β "Redesigning source control at Anthropic" (Scion; the same agent-throughput bottleneck at frontier scale, covered by ThinkSmart) [ThinkSmart Research]
- Anthropic Claude Code team β "How we do code review at this scale" (the human-in-the-loop bottleneck, covered by ThinkSmart) [ThinkSmart Research]
Source X Article read in full on October 30, 2026 (952 words, 55 content blocks). All CI numbers (40 min β 2 min, 11 min β 8 s runner start, 2 min β 5 s lint, 70 s β 13 s β <5 s typecheck, 100 s β 35 s per shard, 168 s β 74 s setup, 33 s β 13 s node_modules restore, 36 s β 12 s checkout, $230 β $4,300/mo CI bill, 20,000 test cases, 11-person team) are as reported by Owen Gretzinger for Boardy. Tool names (Blacksmith, Vercel CI, boat.dev, Oxlint, bun check, tsrs, Nx affected, Vit isolate) are as named in the article; Linear's finding on the Vitest behavior is cited by the author. The "black hole of success" phrasing is the author's. The broader agent-economics analysis and the "what to steal" prioritization are this author's synthesis, not the author's.