Skip to content

ci(backend): experiment: backend test shards on ubuntu-26.04-arm - #129372

Draft
sentry-junior[bot] wants to merge 11 commits into
ci/add-xdist-worker-backend-testsfrom
ci/xdist-exp-ubuntu-26.04-arm
Draft

sentry-junior[bot] wants to merge 11 commits into
ci/add-xdist-worker-backend-testsfrom
ci/xdist-exp-ubuntu-26.04-arm

Conversation

@sentry-junior

@sentry-junior sentry-junior Bot commented Oct 30, 2026

Copy link
Copy Markdown
Contributor

Experiment stacked on #129338 (4 xdist workers). Not for merge.

Runs the backend test job on ubuntu-26.04-arm (Arm64, 4 vCPU / 16 GB for public repos) instead of ubuntu-24.04 x64.

Changes:

  • backend.yml: runs-on: ubuntu-26.04-arm for backend test only. The odiff download now picks odiff-linux-arm64 or odiff-linux-x64 from uname -m.
  • monitor-resources.py: Arm kernels have no model name in /proc/cpuinfo, so the monitor records CPU implementer/CPU part instead, plus a test for it.

Pre-checked: the backend-ci service images (snuba, symbolicator, objectstore, cbtemulator, docker-redis-cluster) publish arm64 manifests, and actions/python-versions ships Python 3.13.17 for 26.04 arm64. The venv cache key includes the Python path, which contains the arch, so x64 and arm64 venvs don't collide. Still unverified: arm64 wheels for every locked package on the internal PyPI, and the Kafka/ClickHouse/Postgres images pulled through devservices' remote configs.

How it'll be measured: full suite (Trigger: Override Selective Testing), run at the same time as a re-run of #129338 on ubuntu-24.04 x64.

via @joshuarli.

--

View Session [Sentry]

joshuarli and others added 10 commits October 30, 2026 11:32
Bump XDIST_WORKERS to 4 on pull requests and master to speed up backend test shards.
Sample cpu/mem every 5s per shard and upload resource-usage artifacts with a headroom verdict for one more xdist worker.
…y-spy

Break each resource sample down into CPU-seconds per docker container,
xdist worker, pytest controller, and other host process, plus user/system/
iowait/steal split. Fix PSI parsing, which read the always-zero full line.

Sample the pytest controller and its xdist workers with py-spy and upload
the collapsed stacks with the resource artifact.

Co-Authored-By: Joshua Li <14209781+joshuarli@users.noreply.github.com>
Co-Authored-By: Joshua Li <14209781+joshuarli@users.noreply.github.com>
…-process CPU

- Rewrite the shard's test modules, conftests and testutils once in a
  background process instead of in each xdist worker.
- Run the throwaway test postgres with fsync, synchronous_commit and
  full_page_writes off.
- Recover CPU of processes that exit between samples from their cgroup's
  cpu.stat, and record reaped children's CPU by parent.
- Turn py-spy profiling off by default; it costs ~0.4 cores.

Co-Authored-By: Joshua Li <14209781+joshuarli@users.noreply.github.com>
…Ms, count postgres connections

Prewarmed pycs were compiled with relative paths while pytest uses the
absolute spec origin and doesn't fix co_filename, so tracebacks changed.

sentry-shared-kafka's healthcheck starts a JVM every 5s, about 0.25 cores
during tests. Once everything that waits on Kafka is up, answer that exact
command with a TCP probe.

Log postgres connections and autovacuum runs to name the ~0.3 cores of
short-lived postgres process CPU.

Co-Authored-By: Joshua Li <14209781+joshuarli@users.noreply.github.com>
…d clickhouse activity

Autovacuum ran ~190 vacuums/analyzes per shard during tests, a likely source
of the ~0.3 cores of short-lived postgres process CPU. Move the service
diagnostics to a script and add ClickHouse query/part CPU breakdowns to
explain its ~0.4 cores.

Co-Authored-By: Joshua Li <14209781+joshuarli@users.noreply.github.com>
… postgres experiments

Same commit as the 4-worker runs except XDIST_WORKERS, to see whether the
fourth worker still pays off after the CPU fixes. Will be set back to 4.

autovacuum=off didn't change postgres CPU (exited backends are closed test
connections, not autovacuum), so it and the connection logging go.
Same-shard runtimes differ up to 1.9x between runs with identical CPU-seconds
ratios, so record each runner's CPU model.

Co-Authored-By: Joshua Li <14209781+joshuarli@users.noreply.github.com>
The 3-worker control on the same commit was ~9% slower in total test time
(7057s vs 6397-6535s across 30 shards) and its slowest shard 24-48s slower,
so keep 4. The ClickHouse query breakdown has answered its question.

Co-Authored-By: Joshua Li <14209781+joshuarli@users.noreply.github.com>
Picks the odiff binary for the runner's architecture, and records an Arm
runner's CPU implementer/part ids, since Arm kernels report no model name.

Co-Authored-By: Joshua Li <14209781+joshuarli@users.noreply.github.com>
@github-actions github-actions Bot added the Scope: Backend Automatically applied to PRs that change backend components label Oct 30, 2026
@sentry-junior sentry-junior Bot added the Trigger: Override Selective Testing Run the full test suite; necessary in cases where selected tests are flaky due to reshuffling label Oct 30, 2026
@sentry-junior

sentry-junior Bot commented Oct 30, 2026

Copy link
Copy Markdown
Contributor Author

First run, 41132145862: ARM is much faster. 29 of 30 shards passed. Shard 21 failed only on test_pydantic_1x_compiled, because the index has no compiled pydantic 1.x for linux aarch64. getsentry/pypi#2693 fixes that.

Compared against a re-run of #129338 at the same time on ubuntu-24.04 x64 (41124537028 attempt 3, 4 workers, same code):

ARM (ubuntu-26.04-arm) x64 (ubuntu-24.04)
Test step, summed over 30 shards 4,635s 6,470s
Slowest shard, test step 183s 309s
Setup before tests, median 97s 123s
Whole job, median / slowest 259s / 285s 366s / 438s
CPU types all 30: Arm Neoverse N2 (0x41/0xd49) 19× EPYC 7763, 6× EPYC 9V45, 3× EPYC 9V74, 2× Xeon
  • Per-CPU-type mean test step: ARM 154s. On x64: EPYC 7763 244s, 9V74 191s, 9V45 148s. ARM roughly matches the fastest x64 type, and every ARM runner got the same CPU, so there's no slow-runner tail.
  • ARM ran with pure-Python pydantic, which is slower, so these ARM numbers are pessimistic.
  • The test mix wasn't exactly equal. ARM ran 0.4% fewer tests (48,148 vs. 48,349 outcomes), most likely because this PR merges into the stacked branch while ci(backend): Run 4 xdist workers per backend test shard on ubuntu-26.04 #129338 merges into master. Shard contents also differed between the runs, so I compared totals and per-CPU-type means, not shard by shard.

getsentry/pypi#2693 published compiled pydantic 1.10.26 wheels for linux
aarch64; refresh uv.lock so Arm runners install them instead of the purelib
wheel.

Co-Authored-By: Joshua Li <14209781+joshuarli@users.noreply.github.com>
@sentry-junior

sentry-junior Bot commented Oct 30, 2026

Copy link
Copy Markdown
Contributor Author

Second run, with compiled pydantic (41138038705, baac6124): all 30 shards green. uv.lock now includes the linux aarch64 pydantic wheels that getsentry/pypi#2693 published, so test_pydantic_1x_compiled passes.

Compared against a re-run of #129338 at the same time on ubuntu-24.04 x64 (41124537028 attempt 5):

ARM (ubuntu-26.04-arm) x64 (ubuntu-24.04)
Test step, summed over 30 shards 4,550s 6,233s
Slowest shard, test step 195s 290s
Setup before tests, median 98s 120s
Whole job, median / slowest 259s / 300s 345s / 422s
Mean test step by CPU 152s (all 30 Neoverse N2) EPYC 7763 244s (n=12), 9V74 205s (n=10), 9V45 150s (n=7)

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Scope: Backend Automatically applied to PRs that change backend components Trigger: Override Selective Testing Run the full test suite; necessary in cases where selected tests are flaky due to reshuffling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant