GitHub went down again last week. Look at the chart below and find the month where the flat green line stops being flat.

GitHub's monthly uptime, from their own status page. The dashed line is the Microsoft acquisition.
That dashed line is Microsoft closing the acquisition in October 2018. I am sure the two things are unrelated. Draw your own conclusion.
To be fair to them, nobody built this thing for what is hitting it now. Git is from 2005. Spokes is from around 2013. Both assume a human is typing the commits, a human who sleeps and takes lunch and occasionally thinks twice before pushing. Then we handed the keyboard to agents that do none of those and open a pull request every time they have a thought. Pull requests opened by AI agents went from around 4 million in September 2025 to more than 17 million by March 2026, and by then Claude Code alone was running at about 2.6 million public commits a week, roughly 4.5% of all public commits on GitHub.
GitHub is just where it shows up first. Thomas Seifert (Cloudflare's CFO) put a number on the wider version on an earnings call: within five years, non-human traffic could be 1,000 times human traffic. Humans, in his words, become "a rounding error".
Cursor shipped their own git hosting last week, called Origin, and published a long engineering post explaining how it works. I went through the whole thing. It is worth understanding even if you never use it.
Start with the way git stores things on disk, because the whole design follows from it. Git stores your code as objects (your files and commits, hashed) and packs them into things called packfiles. Inside a packfile, most objects are not stored whole. They are stored as a delta, which just means the difference from some other object rather than a full copy, and that other object is often a delta too. So when you ask for one file, git finds the last delta, applies it to the one before it, applies that to the one before that, and keeps going back until it hits a full copy and can hand you the thing you actually asked for.

Object C is not stored whole. Reading it means walking the delta chain back to the base object.
If that part is hard to follow, spend a weekend on how git works under the hood. I wrote a git implementation in Go last year, GoGit, through the CodeCrafters git challenge, if you want to try implementing it yourself.
So a git repository is not rows in a database. It is a content-addressed object store. Every blob, tree and commit is keyed by its SHA, and those objects sit inside packfiles alongside a companion .idx that maps a SHA to a byte offset in the pack. Reading one object is a binary search in that index, a seek to an arbitrary offset in a file that can be gigabytes, and then the delta chain. That is a random-access workload against a real filesystem, and it wants the disk on the same machine as the process.
That is inconvenient, because the normal way is to store data at scale is network storage: disks that live somewhere else and are shared over the network. S3 is network storage. So is NFS.
Git cannot use it. When git builds a packfile it sorts objects so that similar ones end up next to each other, then stores each one as a small diff against a neighbour. That layout is chosen to make the file small, and it has nothing to do with the order you read things in. So one git log jumps around a multi-gigabyte file thousands of times. Locally each jump is microseconds (NVMe). Over a network each jump is a round trip, and thousands of round trips is the difference between instant and go-and-make-a-coffee. Cursor put it more politely: this "just doesn't play well with a networked filesystem".
Speed is only half of it. Git also expects the guarantees a local disk gives it. When it takes a lock, it expects to be the only one holding that lock. When a write finishes, it expects the whole write to be on disk, not most of it. Network filesystems give you those guarantees most of the time, which sounds fine right up until two pushes land at once, both think they hold the lock, and you are looking at a corrupted repository. GitHub went down this road before Spokes and backed out of it.
So every server serving a repository needs its own local copy on fast disk.
So now the question is this. You push, your colleague pushes, and there are several copies of that repository sitting on different machines. How does the host decide what the repository now contains?
How GitHub does it
GitHub built a system called Spokes. Keep three copies of your repository on three different machines, each on a fast local disk (NVMe). When you push, a majority of those copies have to acknowledge it before GitHub tells you the push worked. That agreement step is a three-phase commit.

Packfiles need fast random access, so every git host keeps its own full copy on local NVMe.
The tradeoff lands on the write path. Every step of that agreement is bound by the slowest machine in the cluster, so every copy you add to serve more reads is one more machine your push has to wait for. Scaling reads makes writes worse, which is not the direction you expect scaling to go.
There is a second cost too. Each repository lives on specific machines, so GitHub needs a database keeping track of which machines hold which repository and whether each copy is still healthy. Cursor's phrase for this is that you end up treating repositories as pets rather than cattle, each one tracked and nursed individually instead of being interchangeable.
What Cursor did instead
The disks stop being the truth. The truth is a log in S3, which Cursor call Continuity, and each disk just holds a copy built by replaying it.

The packfile goes up first. The push only exists once the compare-and-swap on the index succeeds.
The log is a chain of entries. One entry per push, and the entry is the packfile you sent. Alongside the entries sits one small object, the index, which records where the log currently ends.
That is what makes a push atomic. You upload your packfile and write your log entry first. At that point your entry exists in S3 but is not part of the log yet, because the index still points at the entry before yours. Your push lands the moment the index moves to point at your entry. Moving it is a compare-and-swap: set the index to your entry, but only if it still points at the one you read a moment ago. Two people push at once, both write their entries, both try to move the index, and S3 only lets one through. The loser re-reads and tries again. That is the entire coordination mechanism: one conditional write and a retry loop.
So they did not get rid of the need for machines to agree. They handed that job to S3. S3 is already a huge distributed system that solved this internally, and conditional writes have been available on it since November 2024. What disappears is everything that used to implement agreement locally: the voting between servers, the list of which machines are in the cluster, the lookup table of where each repository lives.

Replicas never talk to each other. Each one replays the log alone, so adding copies costs the push nothing.
The disks are just caches of all this. A server replays the log to rebuild the repository, and git runs normally on top.
The copies never talk to each other. They just read the log from S3 and catch up on their own. So unlike Spokes, adding more copies does not slow your push down at all. Cursor tested it with 100 copies: reads got faster in proportion, and pushes did not get any slower.
It also means no machine needs to own a repository. If a server does not have the one you asked for, it rebuilds it from the log. Repositories nobody is using get deleted off disk entirely, then built again from the log the next time someone asks. Your repository is, functionally, a cache entry.
And because every push is still sitting in the log, you get the whole history of the repository's states for free, including the repacks. Any copy can be rewound or fast-forwarded to any point.
Cursor's reported figures: 120 sustained pushes/sec on S3 Standard, more than 300 on S3 Express One Zone. At the Express One Zone figure they say the bottleneck is no longer storage but how fast git can compact the data on disk. They also report stress tests to 100 replicas: reads scale linearly and push throughput does not regress. A freshness check, a replica asking whether it is behind the log, comes in under 10ms on average, because it is a metadata-only S3 conditional GET. All of it was run against their own monorepo.
What it costs

Four trades: a hard push ceiling, bandwidth instead of CPU, queueing on a hot repo, and no self-hosting.
120 pushes a second is the ceiling, and an S3 round trip is what sets it. A local-disk system with a fast consensus group will beat that on one repository.
Compaction changed too. In Spokes every replica repacks its own copy. Origin repacks once, on the primary, and ships the compacted packs to everyone else. You pay bandwidth instead of CPU, and a slow replica can no longer fall behind.
What I would measure first is one hot repository. Every push to it competes for the same index object. Push hard enough and you are all queueing on a single compare-and-swap. A monorepo under heavy CI will not show you this, because CI is reads.
No self-hosting either. Cursor say the engine can run on any cloud. That is about where Cursor can deploy it. You still push to their servers.
Do you need this

Spokes optimises peak push rate. Origin optimises replica count. Measure which one actually binds you.
Most teams do not. If your repositories take human-paced commits and you are not serving CI from hundreds of replicas, Spokes-shaped hosting is well understood and it makes the right trade for you.
Which is fine, because that is not what Cursor are building for. Agents create millions of tiny repositories that each get almost no traffic, and their monorepo generates enormous CI read load. Both of those are replica-count problems.
So the design is a bet on which of those two numbers your workload cares about. Given where commit volume is going, I do not think it is a bad bet.
Even if you never touch Origin, work out whether your bottleneck is replica count or push rate before you pick an architecture, because these two designs optimise opposite ends. And if you are building anything that needs ordering across machines, check whether your object store's compare-and-swap can be the ordering primitive before you reach for a consensus library. That has only been possible on S3 since late 2024, so most designs you will read predate it.
I am putting a repo on it this weekend. I do not expect it to feel any different, and that is sort of the point. Nothing about pushing changes for you. The parts underneath just got better.
Sources
Vicent Marti, Git at any scale, Cursor engineering blog: https://cursor.com/blog/git-at-any-scale
Cursor, Origin code hosting changelog: https://cursor.com/changelog/origin-code-hosting
GitHub, Introducing DGit, later renamed Spokes: https://github.blog/engineering/architecture-optimization/introducing-dgit/
Simon Willison, S3 adds new functionality for conditional writes: https://simonwillison.net/2024/Nov/26/s3-conditional-writes/
GoGit, my git implementation in Go: https://github.com/Krish-Parekh/GoGit
CodeCrafters, Build your own Git: https://codecrafters.io/challenges/git
The Register, Humans will be a rounding error on the internet, says Cloudflare exec: https://www.theregister.com/networks/2026/08/07/humans-will-be-a-rounding-error-on-the-internet-says-cloudflare-exec/
GitHub status page, source of the uptime chart: https://www.githubstatus.com/
GitHub, Building resilience in Spokes, the routing query and the majority-lock write path: https://github.blog/engineering/infrastructure/building-resilience-in-spokes/
Three-phase commit protocol: https://en.wikipedia.org/wiki/Three-phase_commit_protocol
Originally published in Depth First, my LinkedIn newsletter. Read it on LinkedIn.