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".