A fast, headless Git server backed by S3.
Host repositories in your own bucket. Push and clone with standard Git clients, or work with files, commits, and branches through the API. Runs as a single Go binary.
docker run -p 8347:8347 -v forge-data:/data ghcr.io/folsomintel/forge
or build it:
go build ./cmd/forged && ./forged serve
Local disk is the default store. To use S3 / R2 / Tigris / MinIO:
FORGE_STORE=s3 FORGE_S3_ENDPOINT=… FORGE_S3_BUCKET=… \
FORGE_S3_ACCESS_KEY=… FORGE_S3_SECRET_KEY=… forged serve
Register a key, mint a token, clone:
forged keygen --name laptop
TOKEN=$(forged token --key laptop --scopes 'git:read git:write repo:write')
git clone http://t:$TOKEN@localhost:8347/hello.git
Smart HTTP (v0 and v2), SSH, LFS, partial clone (--filter), and bundle-uri
including incremental bundle chains. SHA-1 repositories only — no SHA-256 yet.
There's also a REST API (contents, trees, commits, diffs, branches, tags, webhooks) and a Server-Sent Events stream of ref updates.
- Every push becomes one immutable
pack+idxin the store. No loose objects. - Refs live in a write-ahead log as compare-and-swap entries; a push's ref updates commit atomically. The pre-receive hook makes the pack and the log entry durable in the bucket before the push is acknowledged.
- Reads run against a cache repo materialized from the store on demand. Receive, fetch, ref advertisement, and the REST read paths are written in Go with native delta and thin-pack resolution, so they don't fork git; git is used for repacking and as a fallback.
- Maintenance publishes clone and catch-up bundles as static objects. A read replica can serve a repo larger than its disk: it keeps pack indexes local and reads pack data from the bucket in blocks.
See ARCHITECTURE.md for the full design.
Forge implements common Git operations in Go to avoid starting a Git process for each request and to read packs directly from the bucket.
- Ref advertisements (
info/refs) read from the metadata index without loading the repository into the local cache. - Pushes use a Go packfile parser that resolves deltas and thin packs.
- Fetches assemble incremental packs from previous pushes. Full clones can stream packs directly from the bucket, and depth-1 clones are built from the tip's tree without starting Git.
- Object reads use Go tree and commit parsers with a pool of
git cat-fileprocesses. On replicas, a pack reader can fetch blocks from the bucket and resolve objects, including deltas, without downloading entire packs to disk.
Git still handles pack generation and repacking. Requests the Go paths cannot handle fall back to Git.
Measured with ForgeMark: 32
concurrent agents on one repo, each commit 1–3 files of 1KB, load generator
in Fly sjc (2026-10-05). Forge and walgit each ran on one Fly
performance-4x (4 CPU, 8GB) over Tigris. Cursor Origin is the hosted service;
its hardware and region are unknown, so its latency includes network time.
| 32 agents | push | shallow clone | clone + 5 pushes |
|---|---|---|---|
| forge | 160/s, p50 185ms | 517/s, p50 59ms | 136/s, p50 180ms |
| Cursor Origin | 75/s, p50 412ms | 123/s, p50 253ms | 64/s, p50 355ms |
| walgit | 11/s, p50 2.6s | 22/s, p50 1.3s | 3.8/s, p50 6.7s |
At 128 agents forge sustained 375 pushes/s (p50 326ms) with no errors.
Everything is set through FORGE_* environment variables. The common ones:
| Variable | Default | Meaning |
|---|---|---|
FORGE_ADDR |
127.0.0.1:8347 |
HTTP listen address |
FORGE_SSH_ADDR |
off | git-over-SSH listen address |
FORGE_STORE |
local |
local or s3 |
FORGE_STORE_PATH, FORGE_S3_* |
store location and credentials | |
FORGE_DATA_DIR |
cache and SQLite index (disposable) | |
FORGE_PUBLIC_URL |
enables bundle-uri clone offload | |
FORGE_RATE_API, FORGE_RATE_GIT |
per-subject rate limits | |
FORGE_FAST_PUSH, FORGE_FAST_FETCH |
true |
Go push and fetch paths; false sends everything to Git |
FORGE_REPLICA |
false |
read-only follower |
FORGE_REMOTE_PLACEMENT_BYTES |
0 |
on a replica, serve repos over N bytes from the bucket |
Pre-1.0. The design and hot paths are covered by an e2e suite that runs real git and checks forge's read output byte-for-byte against it, but forge has not been run in production or benchmarked on a large monorepo.
AGPL-3.0 (see LICENSE). If you run a modified forge as a network service, you
must offer its users the modified source.