Skip to content

Create manylinux2014 wheels#745

Merged
hugovk merged 2 commits into
ultrajson:mainfrom
hugovk:re-add-manylinux2014
Jun 14, 2026
Merged

Create manylinux2014 wheels#745
hugovk merged 2 commits into
ultrajson:mainfrom
hugovk:re-add-manylinux2014

Conversation

@hugovk

@hugovk hugovk commented Jun 14, 2026

Copy link
Copy Markdown
Member

Fixes #741.

Changes proposed in this pull request:

  • Re-add manylinux2014 support to wheels

@hugovk hugovk added the changelog: Added For new features label Jun 14, 2026
@codecov

codecov Bot commented Jun 14, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.44%. Comparing base (209371e) to head (bd943e8).

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #745   +/-   ##
=======================================
  Coverage   93.44%   93.44%           
=======================================
  Files           7        7           
  Lines        2241     2241           
=======================================
  Hits         2094     2094           
  Misses        147      147           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@hugovk

hugovk commented Jun 14, 2026

Copy link
Copy Markdown
Member Author

We ought a quick benchmark to see if there are meaningful performance gains from building with the later toolchains available in the newer images. Building more than one wheel would be a very easy way to give a free performance boost if there are.

#741 (comment)

Here's benchmark branch and run, uses tests/benchmark.py from this repo:

Uses wheels from:


Here's a Claude summary:

Benchmark: manylinux2014 (gcc 10) vs manylinux_2_28 (gcc 14)

Method: benchmarked ujson wheels built from the same C source with the two images, so the only variable is the compiler. Both wheel sets came straight from CI:

wheels image / gcc source run commit
old manylinux2014 / gcc 10.2.1 re-add-manylinux2014 dispatch 0811ca8
new manylinux_2_28 / gcc 14.2.1 pre-pin deploy run d31a7b7

Source parity verified — git diff of lib/, python/, deps/, *.c, *.h, setup.py between the two commits is empty.

Each wheel was loaded into the same interpreter on the same runner and run through tests/benchmark.py, across a matrix of {x86_64, aarch64} × {CPython 3.10–3.14, 3.14t} (12 jobs, all green).

Results — geomean speed-up (new / old), 17 metrics per job

Python aarch64 x86_64
3.10 +8.8% +6.7%
3.11 +11.1% +8.9%
3.12 +9.4% +5.5%
3.13 +8.7% +8.9%
3.14 +9.0% +10.6%
3.14t +9.9% +8.2%

Overall geomean: +8.8%, consistent across both arches and every Python version.

The gains are concentrated on encode paths — string-array encode ~, UTF-8 encode ~+50%, dict encode ~+23% — while decode is milder (~3–12%). A handful of metrics dip just under 1.0 (noise); no systematic regression. The pattern matches a separate local aarch64 run, so it's real codegen (newer gcc auto-vectorising the escape/copy loops), not measurement noise.

Takeaway

Re-adding manylinux2014 restores broad compatibility (glibc 2.17) but costs this ~8–9% encode-heavy speed-up. So building both image variants is worth considering: old systems get a working wheel, and modern systems (pip prefers the higher platform tag) automatically pick up the faster manylinux_2_28 build — at the cost of roughly doubling the Linux wheel count.

@bwoodsend

Copy link
Copy Markdown
Collaborator

Yeah, I think that's big enough a difference to warrant doing both.

@hugovk

hugovk commented Jun 14, 2026

Copy link
Copy Markdown
Member Author

New benchmark, wheels from https://github.com/hugovk/ultrajson/actions/runs/27506564289, run in https://github.com/hugovk/test/actions/runs/27507091606.


Claude summary:

Benchmark: manylinux2014 (gcc 10) vs manylinux_2_28 (gcc 14)

Geomean speed-up (new / old), 17 metrics per job

Python aarch64 x86_64
3.10 +11.9% +9.5%
3.11 +11.7% +8.6%
3.12 +8.8% +9.2%
3.13 +11.5% +6.1%
3.14 +8.7% +9.6%
3.14t +8.3% +8.0%

Overall geomean: +9.3%, every job between +6% and +12%.

Gains concentrate on encode paths — string-array encode ~ (per-benchmark max +215%), UTF-8 encode ~+50%, dict encode ~+23% — while decode is milder (~3–12%). A few metrics dip just under 1.0 (noise); no systematic regression. A local aarch64 run (Docker, 3.11) showed the same pattern, so it's real codegen (newer gcc auto-vectorising the escape/copy loops), not measurement noise.

Takeaway

Re-adding manylinux2014 restores glibc 2.17 compatibility but costs this ~9% encode-heavy speed-up. Building both variants gets the best of both: old systems get a working wheel, and modern systems automatically pick up the faster manylinux_2_28 build via the higher platform tag — at the cost of ~16 extra Linux wheels (here 77 → 93 dists).


And the manylinux2014 wheels are similar in size to the others, around 55k each.

@hugovk hugovk marked this pull request as ready for review June 14, 2026 18:06
@hugovk hugovk merged commit 1a23a68 into ultrajson:main Jun 14, 2026
40 checks passed
@hugovk hugovk deleted the re-add-manylinux2014 branch June 14, 2026 19:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

changelog: Added For new features

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Request: Re-add manylinux2014 wheels

2 participants