Git is usually treated as a filesystem problem: the `.git` directory looks like a folder, so the natural way to host Git in the cloud is to give it a filesystem and put that filesystem on top of object storage. One developer tried exactly that and found it did not hold up for real-world repositories. The result is objgit, an open-source Git server that stores Git's objects directly in object storage — specifically Tigris — and replaces Git's own packfile machinery with a custom format designed for remote, byte-addressable storage.
To understand why that is necessary, it helps to start with what Git actually stores. A repository is, at root, two things: a sea of objects and named references that point at individual objects inside it. Every commit, tree, and file blob is a separate, content-addressed, compressed object whose filename is the hash of its bytes — the same content is always the same object, everywhere. In a tiny repository this is unremarkable: three objects on disk, each a bare zlib-compressed file. But a checkout of the Linux kernel contains roughly 11.8 million objects, and Git does not keep them as 11.8 million files. It bundles them into packfiles — compressed archives that store many objects inside a single file — precisely because storing them as loose files would run into filesystem inode limits.

The article explains that a repository is, at root, a sea of content-addressed objects plus named references pointing into them, and that Git bundles these into packfiles rather than keeping millions of loose files. The meme captures the counterintuitive part of that: the small-brain assumption that Git keeps whole files for every version is wrong, which is exactly why the packfile format matters for object storage.
Packfiles are where the object-storage translation breaks. Git was designed around local storage: it constantly writes packfiles to disk and immediately reads them back, and it memory-maps them so the operating system's page cache serves hot data as if it were RAM. A filesystem read in that world takes around ten nanoseconds. A network roundtrip to object storage takes around ten milliseconds — at minimum — which the author describes as at least a million times slower. Git also relies on a Unix idiom of writing a file and reading it straight back to compute its hash, which object storage cannot do, since you cannot fetch an object that has not finished being written.
The deeper obstacle is the packfile index. Each packfile has an accompanying `.idx` file that tells Git where every object lives inside the pack. The index records, for each object, its offset and its decompressed size — but not its compressed size. That distinction is fatal for object storage. Object storage is addressed by HTTP range requests: to fetch a single object out of a 128-megabyte pack, a client needs to know the object's starting byte and its length, then ask the bucket for exactly that span. Because the index omits compressed length, you cannot compute that span from the index alone, and you cannot cheaply discover it another way. This is the core reason, the author argues, that earlier attempts to store Git in object storage struggled — not because range requests are unavailable, but because Git's index format does not supply the information needed to use them.
The author's solution borrows an idea from physical media. A CD cue sheet is a plain-text file that lists tracks and the offsets at which they begin inside a larger WAV file, so a player can jump directly to any track without scanning the whole disc. Objgit's replacement format does the same thing for Git objects, but with a binary, fixed-width layout. A small `objects.cue` file contains a 16-byte header — magic number, version, record size, and record count — followed by records of 58 bytes each, so record N sits at byte offset `16 + N * 58`. Each record carries the object's hash, type, compression method, size, and the offset and length of its bytes inside a single large `objects.bin` file. Retrieving any object therefore takes one seek into the cue file, one lookup, and one HTTP range request into the binary blob — 366 bytes on the wire rather than the entire pack.
The payoff is that this works at production scale without changing anything on the client side. The author reports the approach performing well on real-world-sized repositories, and the design is described as the least obtrusive way to make Git objects feel like object-storage objects. The underlying storage layer keeps named references to points in that sea of objects in FoundationDB, a distributed key-value store, which the author calls a kind of recursion: object storage holding objects, with references to those objects stored in another object-like system.
The project behind the blog post, objgit, is a fuller picture of what this becomes as a product. Hosted at tigrisdata/objgit, it is a Git server — not a proxy for an existing forge — that speaks the SSH, HTTP, and Git protocols, runs post-receive hooks inside user-space sandboxes, and supports Git LFS with presigned transfers so large files move directly between the client and Tigris rather than through the server. It also takes EROFS snapshots per tree, exposes basic Prometheus metrics, and ships a Kubernetes deployment via Kustomize. It currently has no authentication, which the author lists as a known gap to fill if the project proves useful.
Two caveats should accompany this. First, the performance claims — that the filesystem shim was too slow for real-world repositories and that the new format works well at production size — come from the project's own author and its blog, not from an independent benchmark; the supplied repository page corroborates the project's feature set but does not validate the measurements. Second, the ecosystem gap the author notes is real: mainstream Git servers such as GitLab, Forgejo, and Gitea still expect a local filesystem for their repositories, so objgit is currently a self-hosted, early-stage alternative rather than a drop-in replacement. Whether the cue-sheet idea proves general enough to be adopted elsewhere is, for now, an open question.
What the work demonstrates is less that Git can be moved to the cloud — that had been attempted before — and more that the specific bottleneck was never the network or the protocol, but the index format Git inherited from a disk-centric era. Replacing that one piece, rather than wrapping Git in a filesystem layer, is what makes object storage viable as a Git backend.