Repository navigation
Conversation
joshuarli
force-pushed
the
ci/add-xdist-worker-backend-tests
branch
from
October 30, 2026 18:36
65610bf to
616ace8
Compare
This was referenced Oct 30, 2026
This was referenced Oct 30, 2026
This was referenced Oct 30, 2026
Bump XDIST_WORKERS to 4 on pull requests and master to speed up backend test shards. Co-Authored-By: Joshua Li <14209781+joshuarli@users.noreply.github.com>
Sample cpu/mem every 5s per shard and upload resource-usage artifacts with a headroom verdict for one more xdist worker. Co-Authored-By: Joshua Li <14209781+joshuarli@users.noreply.github.com>
…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>
…profiling Same-CPU comparisons put ubuntu-26.04 within noise of 24.04, and the ARM runners we want next are 26.04. The py-spy step is commented out; the wrapper script stays for ad-hoc profiling. Co-Authored-By: Joshua Li <14209781+joshuarli@users.noreply.github.com>
…afka healthcheck Same changes as the backend test job: ubuntu-26.04, the resource monitor (uploaded as acceptance-resource-usage-<run>-<shard>), and the kafka-topics healthcheck shim. Co-Authored-By: Joshua Li <14209781+joshuarli@users.noreply.github.com>
sentry-junior
Bot
force-pushed
the
ci/add-xdist-worker-backend-tests
branch
from
October 30, 2026 23:04
83ebd20 to
06e6ecc
Compare
This was referenced Oct 30, 2026
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Runs backend tests with 4 xdist workers per shard, on both pull requests and master. Before this, pull requests used 2 and master used 3. The PR also removes most of the extra CPU load that made a 4th worker a wash at first, and adds resource monitoring so future tuning can be measured. The
backend testandacceptancejobs also move fromubuntu-24.04toubuntu-26.04; acceptance stays at 2 workers and gets about 5% faster per job (see Acceptance below).Next step, stacked on this PR: #129387 moves both jobs to
ubuntu-26.04-armon pull requests, which cuts backend test time by another ~27% and acceptance jobs by ~10%.Rollout order
Land these in order. Each is stacked on the one before, so after one merges, retarget the next PR's base to
masterand rebase it. Each can be reverted on its own.ubuntu-26.04← this PRbackend testandacceptancemove to x64ubuntu-26.04. Also adds the Kafka healthcheck shim, the assert-rewrite prewarm, Postgres with durability off, and the resource monitor.backend testandacceptancerun onubuntu-26.04-armfor pull requests only; master stays on amd64. Also includes the Chromium snap for Arm acceptance, the compiled Arm pydantic wheels inuv.lock, and inselenium.py0.1s wait polling plus debug capture only on failure.uv.lockchange only adds Arm wheels, which x64 installs ignore.Trigger: Override Selective Testing) are unchanged.test_organization_agent_token.py.Whole stack, on pull requests: backend test time is about −40% compared with master today, the slowest shard about −45% and the median job about −31%. Roughly a quarter of the gain comes from the 4th worker and most of the rest from Arm. Selective PR runs should land near a 3-minute slowest job.
Result
With 4 workers, total test-step time is about 6% lower than with 3 workers on the same code, after correcting for runner CPU type (margin of error about ±2%). In every comparison, the slowest shard was also faster.
The 5th worker adds nothing (see the experiments below), so 4 is the sweet spot on these 4-vCPU, 16 GB runners.
Test step time (
Run backend test) across all 30 shards:226e1191226e1191Whole job on the final code: median 344–353s, slowest 394–408s. Master's slowest job was around 430s. Setup takes about 100s with either worker count.
Runner hardware matters more than you'd think. GitHub-hosted
ubuntu-24.04runners came with four CPU types. Fitting test time per shard and per CPU model gives these relative times (lower is faster):The same shard can take up to 1.9× longer depending on the runner it lands on, so single-run wall times are only directional. The resource monitor now records each shard's CPU model so runs can be compared fairly.
Acceptance
acceptancemoves toubuntu-26.04too, and gets the same resource monitor and Kafka healthcheck. It stays at 2 xdist workers, because more workers made it slower:ubuntu-24.04, 9 recent runs, median)Worker count, with all runs at 10 shards and corrected for runner CPU type (residual noise about 5% per shard):
The runner is already CPU-bound with Chrome plus per-worker Snuba, so each extra worker mostly adds another Snuba bootstrap. On Arm (#129387) acceptance gets about 10% faster across the board.
What changed
XDIST_WORKERS: '4'for backend tests on pull requests and master.prewarm_assert_rewrite.py, started frompytest-selected.py). Every xdist worker used to rewrite and compile the shard's test files, conftests andsrc/sentry/testutilsat the same moment. That was about 11.5s of CPU per worker, all at startup. A background process now writes pytest's rewritten pycs once while the workers start up. It compiles with the same absolute path pytest uses, because pytest doesn't fixco_filenamein cached code. An earlier version used relative paths, which changed traceback paths and broketest_thread_leak_strict_mode_raises.test_prewarm_assert_rewrite.pyruns real pytest against a prewarmed file to guard this. The prewarm only runs with xdist.kafka-topics-healthcheck.sh).sentry-shared-kafka's healthcheck runskafka-topics --listevery 5s, which starts a JVM each time. That cost about 0.35 cores during tests. After everything that waits on Kafka's health has finished, CI answers that exact command with a TCP probe. Any otherkafka-topicscall still runs the real binary. Kafka dropped to 0.02 cores and still reports healthy. The step iscontinue-on-error. Used in both backend and acceptance.fsync=off,synchronous_commit=off,full_page_writes=off. This is a throwaway CI database.monitor-resources.py, uploaded asbackend-resource-usage-<run>-<shard>andacceptance-resource-usage-<run>-<shard>). Every 5s it records:some; thefullline is always 0 system-wide)cpu.statruns-on: ubuntu-26.04forbackend testandacceptance. On the same CPU types it was within ~2% of 24.04, which is noise (ci(backend): experiment: backend test shards on ubuntu-26.04 #129378, results). It's here as the upgrade, and because the ARM runners in ci(backend): Run backend test shards on ubuntu-26.04-arm #129387 are 26.04.Install py-spystep is commented out inbackend.yml, andprofile-backend-tests.shstays in the repo for ad-hoc profiling. The comment above the step says how to turn it back on. It costs about 0.37 cores and skews timings.Where the CPU goes now
The runner is about 93% busy during tests, with CPU pressure around 34. Mean cores per shard during the test phase:
Postgres's "exited" CPU is query work done on test connections that later closed. It isn't autovacuum: turning autovacuum off changed nothing, so that change was reverted.
From py-spy (first profiling run):
create_organizationfixtures are large chunks of test timeExperiments (stacked draft PRs, run at the same time on the same base)
Backend experiments ran the full suite, green on all 30 shards. Results are normalized for runner CPU model against a same-time rerun of this PR (4 workers). The margin of error is about ±2%.
PIECES_PER_SHARD48 → 24log_queries=0and query profiler off viausers.dubuntu-26.04x64ubuntu-26.04-armEarlier single runs on this branch also showed:
autovacuum=off: no effect, revertedFollow-ups (not in this PR)
backend testandacceptancetoubuntu-26.04-armon pull requests: ci(backend): Run backend test shards on ubuntu-26.04-arm #129387, stacked on this PR. ci(backend): Size selective shards by test duration for a ~3 minute slowest job #129398 then sizes selective shards for a ~3 minute slowest job. In the ci(backend): experiment: backend test shards on ubuntu-26.04-arm #129372 experiment, ARM cut summed test time 6,233s → 4,550s (−27%), the slowest shard 290s → 195s (−33%) and the median job 345s → 259s (−25%), all with 4 workers.sentry-shared-kafka's healthcheck cheap or less frequent upstream, for example with a longintervalplusstart_interval. That would replace the CI shim and also help local dev.via @joshuarli.
--
View Session [Sentry]