Skip to content
zit Artifact [d53883be77]
Login

Artifact [d53883be77]

Artifact d53883be7798f8c168321588009c75b87c408fef6cbc1491f6a54cca1e542d1d:


# zit 0.3.11

zit 0.3.11 fixes a quadratic in the sync server. A pull between two peers that
already hold the whole repository transfers nothing, and at 1.25M artifacts it
took over seventeen minutes to do so. The server's share of that — 760 seconds
of CPU — is gone: the same pull now costs the server under five seconds.

No artifact, tag namespace, sync message, or on-disk format changed.

## The server no longer scans per artifact

Composing a sync reply, the server walks every artifact it holds and, for each,
avoids re-announcing something the peer already has by checking the peer's
announced list. That check was a linear scan of the list, run once per held
artifact — and because an ordinary pull announces the peer's entire holdings,
both the walk and the list were the size of the repository. The reply was
O(held x announced): 9.5x the artifacts cost 78x the server CPU. It did not
grow slowly; past a few million artifacts it does not complete.

The announced and requested names are now built into one set per reply and
probed once per held artifact — O(held). On the 1.25M no-op pull the server's
work falls from 760s to 4.9s; the whole pull, from 17.4 minutes to 4.7. The
remaining time is a separate, linear cost — announcing and materialising every
held artifact one at a time — which is what cluster minting will
bound; it is not this fix.

Why it was never caught: the read verbs and clone were measured and level with
fossil, but clone announces nothing (it converges on a record cursor), and no
both-sides-full pull had ever been run at the scale where a small quadratic
constant becomes minutes. The pull now carries an evidence counter —
announcement probes per reply — pinned at two repository sizes to track the
holdings, not the announcement; a quadratic cannot pass it. A both-sides-full
incremental pull is now part of qualification.

## Compatibility

- Artifacts, tags, and the sync protocol are unchanged; Fossil RFC
  revision 00 remains the target.
- No on-disk or cache format changed, and no wire bytes changed — the fix is
  the same reply computed faster.
- No command, flag, or output changed.

## Qualification

`zig build test`, `e2e`, `smoke` (Fossil interop against a real `fossil`),
`muscle` (41 differential steps), `git-import-e2e`, `git-export-e2e`, and
`dst`, plus the three-runner CI battery (macOS ARM64, Linux x86-64, Linux
ARM64). The before/after pull timings were taken on the sub-manifest pkgsrc
corpus with release builds; the server's collapse from 760s to 4.9s was
confirmed by stack sampling the serve process across both.