By admin , 29 April 2026

Two ends of one wire

Fetch and push performance depends on negotiation efficiency, transfer size, and server-side computation. Each has levers, and the right ones differ by repo size.

Protocol v2

Protocol v2 (default in Git 2.26+) reduces the upfront ref advertisement, dramatically helping repos with thousands of refs. Verify it is in use:

GIT_TRACE_PACKET=1 git ls-remote origin 2>&1 | head -2
git config protocol.version 2

See "Protocol v2 for efficient fetch negotiation".

Negotiation algorithm

git config fetch.negotiationAlgorithm skipping
git config fetch.negotiationAlgorithm noop      # client has nothing to advertise

The skipping algorithm (default in Git 2.32+) advertises ancestors with exponential gaps, finding common bases in fewer rounds.

Bundle URIs

Servers can advertise a bundle URI for new clones, letting the client download a static bundle from a CDN before negotiating the rest. Game-changer for huge clones:

git clone --bundle-uri=https://cdn.example/repo.bundle https://example.com/repo.git
git config fetch.bundleURI https://cdn.example/repo.bundle

Parallel fetch

git config fetch.parallel 0
git config submodule.fetchJobs 8

fetch.parallel=0 uses all cores. Helpful when many remotes or submodules are involved.

Push optimization

git config push.useBitmaps true
git config pack.useBitmaps true
git push --atomic origin main feature

--atomic ensures all refs update or none do, preventing partial pushes on network failures.

Server-side considerations

Servers benefit from MIDX, reachability bitmaps, geometric repack, and commit-graph just as clients do. git pack-objects on the server is the dominant cost; bitmaps cut it dramatically.

Shallow and partial clones

For CI or read-only consumers:

git clone --depth=1 https://example.com/repo.git
git clone --filter=blob:none https://example.com/repo.git
git clone --filter=tree:0 --no-checkout https://example.com/repo.git

See "Shallow clones in CI/CD" and "Partial clone: promise and promisor remotes".

Common mistakes

Using --depth=1 in CI then trying to bisect or run path-restricted log — works only on commits in the shallow window. Disabling bitmaps on the server "for simplicity" and watching CPU spike under load. Pushing 10,000 refs at once over protocol v0 — upgrade to v2.

Related

See "Protocol v2 for efficient fetch negotiation", "Wire protocol optimization: stateless-connect", and "Reachability bitmaps for fast set operations".