GitHub moved from a 10x to 30x capacity plan in months as pull requests hit 90M and commits 1.4B. We unpack the redesign and tradeoffs. Read now.
From a 10x plan to 30x under real load
GitHub’s move from a 10x capacity plan to a 30x plan did not happen in the abstract. Pull requests reached 90M and commits 1.4B, which is the kind of sustained growth that exposes every assumption baked into an older scaling model. A 10x plan can look complete on paper—more replicas, larger storage tiers, wider caches—yet still leave hard ceilings in the paths that matter most: merge checks, diff generation, ref updates, and the metadata that ties a commit to a pull request. When those paths saturate together, you do not get a graceful slowdown; you get queueing, retries, and user-visible stalls that no single “add hardware” ticket can fix.
Jumping to a 30x target in months forces a different mindset. You stop asking how to stretch the current design and start asking which boundaries must move. Capacity is not only CPU and disk. It is write amplification, cross-service fan-out, lock contention, and how much work a single user action is allowed to trigger in the background. Rearchitecture at this scale is less about one heroic rewrite and more about raising the ceiling on the hottest, most shared surfaces first.
What a capacity rearchitecture actually changes
A redesign aimed at multi-tens-of-x growth usually starts by splitting “hot path” work from “must be durable eventually” work. Serving a pull request page and computing a large merge base are different jobs with different latency budgets. Collapsing them into one request path is convenient early on and expensive later. The rearchitecture pattern is familiar: isolate expensive computation, make progress incremental, and make sure failure in a background pipeline does not take down the interactive surface.
Storage and indexing get the same treatment. Commits and pull requests are not one blob of data; they are graphs of refs, trees, reviews, checks, and comments that grow at different rates. Treating them as a single scaling unit invites the slowest-growing dimension to dictate cost for everything else. Partitioning by repository, by time, or by workload type—and accepting that some cross-partition queries become harder—is a common tradeoff when the alternative is a shared bottleneck that every tenant pays for.
- Separate interactive reads from heavy analysis so page latency does not ride behind batch work.
- Bound fan-out: one push or merge should not open unbounded parallel work across the fleet.
- Prefer incremental and resumable jobs over full recomputation when graphs get large.
- Make backpressure explicit: reject or delay excess work early rather than thrash under load.
Tradeoffs you accept when you aim for 30x
Higher capacity almost always costs simplicity. Stricter isolation improves blast radius and scaling, but debugging a merge that touches several services is harder than debugging a monolithic path. Stronger caching protects read load, yet stale views and invalidation bugs become product issues, not just ops issues. Asynchronous pipelines keep the UI responsive while risking temporary inconsistency between “what the user just did” and “what the system has fully processed.”
Operational tradeoffs show up just as clearly. A system built for 30x needs clearer ownership of queues, clearer SLOs per surface, and more deliberate load shedding. You also accept that not every feature can share the same durability or freshness guarantee. Some paths must be correct immediately; others can catch up. Documenting that distinction—and building product UX around it—is part of the redesign, not a follow-up polish item.
Practical lessons for teams facing their own ceilings
You do not need GitHub’s absolute scale for the same pattern to apply. Measure where capacity actually disappears: lock wait time, queue depth, p99 of the hottest endpoints, and how much work a single write multiplies into. If growth projections already outrun a 10x plan, do not wait for an outage to renegotiate the plan. Revisit the unit of scaling, the cost of a single write, and which work is allowed on the critical path.
Then sequence the redesign around outcomes, not slogans. Protect interactive paths first, make expensive work incremental, and instrument the boundaries you introduce so the next capacity jump is a planning exercise rather than an emergency. GitHub’s shift from 10x to 30x under 90M pull requests and 1.4B commits is a reminder that capacity plans age with product usage—and that the durable fix is architectural, not just more of the same.