git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Performance regression in "update" hooks

From
Patrick Steinhardt <ps@pks.im>
Date
Mar 2, 2026, 07:17 UTC
Message-ID
<aaU5lZwEuR4OrxCl@pks.im>
Hi,

Bencher has alerted me that there's been two performance regressions in git-receive-pack(1) [1] and git-fetch(1) [2].

The first one is quite easy to reproduce with the benchmarks at [3] and bisects to fc148b146a (receive-pack: convert update hooks to new API, 2026-01-28):

  $ cd receive-refs
  $ ./run --revisions /path/to/your/git/repo \
      fc148b146ad41be71a7852c4867f0773cbfe1ff9~,fc148b146ad41be71a7852c4867f0773cbfe1ff9 \
      --parameter-list refformat reftable \
      --parameter-list refcount 10000
  Benchmark 1: receive: many refs (refformat = reftable, refcount = 10000, revision = fc148b146ad41be71a7852c4867f0773cbfe1ff9~)
    Time (mean ± σ):     182.0 ms ±   2.7 ms    [User: 91.5 ms, System: 89.3 ms]
    Range (min … max):   175.8 ms … 185.0 ms    15 runs
  Benchmark 2: receive: many refs (refformat = reftable, refcount = 10000, revision = fc148b146ad41be71a7852c4867f0773cbfe1ff9)
    Time (mean ± σ):     484.6 ms ±  27.6 ms    [User: 176.2 ms, System: 376.1 ms]
    Range (min … max):   406.2 ms … 495.1 ms    10 runs
  Summary
    receive: many refs (refformat = reftable, refcount = 10000, revision = fc148b146ad41be71a7852c4867f0773cbfe1ff9~) ran
      2.66 ± 0.16 times faster than receive: many refs (refformat = reftable, refcount = 10000, revision = fc148b146ad41be71a7852c4867f0773cbfe1ff9)
I've Cc'd Adrian.

The other performance regression seems to be present in both git-receive-pack(1) and git-fetch(1) and happens between e6e9f13364 (Sync with 'master', 2026-02-25) and ebd1da8b75 (Merge branch 'cx/fetch-display-ubfix' into next, 2026-02-26). It took me a while to reproduce as my local Git configuration was hiding the regression, but I have been able to bisect this to 452b12c2e0 (builtin/maintenance: use "geometric" strategy by default, 2026-02-24).

The problem here is rather simple though. The benchmark fetches 10,000 refs into the repository, and before the commit we didn't do anything about them. But after the commit we now have per-data-structure tasks, and the result is that we thus end up packing refs. That's also why the regression isn't present in the reftable backend, as it wouldn't need any optimization.

So I'd consider this to be a bug in the benchmarking infrastructure itself that I'll fix by disabling auto-maintenance.

Thanks!
Patrick

[1]: https://bencher.dev/perf/git?lower_value=false&upper_value=false&lower_boundary=false&upper_boundary=false&x_axis=date_time&branches=595859eb-071c-48e9-97cf-195e0a3d6ed1&testbeds=02dcb8ad-6873-494c-aabc-9a6237601308&benchmarks=e3553193-aefc-40a4-8816-9c1bdc1838a4%2Ccd00a2a1-0fd1-416a-9812-cfd3e9b4fdb8&measures=63dafffb-98c4-4c27-ba43-7112cae627fc&start_time=1765177145759&end_time=1772434745759&tab=plots&plot=6887f804-2bbc-4219-8211-55b6440fd5c0&plots_search=6887f804-2bbc-4219-8211-55b6440fd5c0&key=true&reports_per_page=4&branches_per_page=8&testbeds_per_page=8&benchmarks_per_page=8&plots_per_page=8&reports_page=1&branches_page=1&testbeds_page=1&benchmarks_page=1&plots_page=1 [2]: https://bencher.dev/perf/git?lower_value=false&upper_value=false&lower_boundary=false&upper_boundary=false&x_axis=date_time&branches=595859eb-071c-48e9-97cf-195e0a3d6ed1&testbeds=02dcb8ad-6873-494c-aabc-9a6237601308&benchmarks=196480c8-64d1-4768-a3e2-ac3c5f75a26e%2Cb422ed57-2b09-474b-a85f-2d71ba7ca46b&measures=63dafffb-98c4-4c27-ba43-7112cae627fc&start_time=1765177141331&end_time=1772434741331&tab=plots&plot=4134acc8-9194-454c-9d71-f41b44ab969d&plots_search=4134acc8-9194-454c-9d71-f41b44ab969d&key=true&reports_per_page=4&branches_per_page=8&testbeds_per_page=8&benchmarks_per_page=8&plots_per_page=8&reports_page=1&branches_page=1&testbeds_page=1&benchmarks_page=1&plots_page=1 [3]: https://gitlab.com/gitlab-org/data-access/git/benchmarks

Next: Adrian Ratiu
Message 1 of 7 in “Performance regression in "update" hooks”
  1. Patrick SteinhardtMar 2, 2026
  2. Adrian RatiuMar 2, 2026
  3. Adrian RatiuMar 2, 2026
  4. Patrick SteinhardtMar 2, 2026
  5. Jeff KingMar 2, 2026
  6. Adrian RatiuMar 2, 2026
  7. Junio C HamanoMar 2, 2026

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.