Skip to content

fix(broker): jemalloc global allocator to stop churn-driven RSS growth (#23) - #24

Merged
mack42 merged 1 commit into
mainfrom
fix/jemalloc-allocator
Jul 11, 2026
Merged

fix(broker): jemalloc global allocator to stop churn-driven RSS growth (#23)#24
mack42 merged 1 commit into
mainfrom
fix/jemalloc-allocator

Conversation

@mack42

@mack42 mack42 commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

Summary

Make ramqp-brokerd use jemalloc as its global allocator. Closes #23.

(This is the follow-on to #22, which merged before this commit landed on the
branch — the deps (#20/#21) and test-battery work went in, this did not.)

Why

The 20-minute connection-churn soak added in #22 surfaced a severe degradation:
broker RSS climbs +64% with no plateau and throughput collapses −76%
(719k → 170k msg/s) over the run. An LD_PRELOAD A/B on the identical workload
pinned the cause to glibc malloc arena fragmentation under churnnot a
broker logic leak (profiling ruled out connection/consumer/fd/task/unacked
leaks; a debug pass showed the queue actor's unacked scan is O(0) at close). With
jemalloc, RSS plateaus (+12%) and throughput holds (−11%).

20-min churn soak glibc jemalloc
RSS drift +64% (no plateau) +12% (plateaus)
throughput early→late 719k → 170k (−76%) 1033k → 916k (−11%)
verdict FAIL PASS

Change

  • tikv-jemallocator wired as #[global_allocator] in the ramqp-brokerd bin,
    behind a default-on jemalloc feature. --no-default-features opts out on
    targets jemalloc doesn't support.
  • Only the daemon sets the allocator — the library never imposes it on
    downstream users.

Validation

  • cargo fmt --check clean; clippy --all-targets --all-features -D warnings clean.
  • Compiled-in (no LD_PRELOAD) churn soak passes: RSS plateaus (+14.5%),
    throughput holds (−13%) — matching the preload A/B, unlike glibc's failure.

ramqp-broker 0.8.28 → 0.8.29.

glibc's malloc fragments its per-thread arenas under the broker's high
connection open/close churn: a 20-minute churn soak (8 client pairs, reconnect
every 500 msgs, ~1.2M reconnects) grows broker RSS +64% with no plateau and
collapses throughput -76% (719k -> 170k msg/s). jemalloc keeps both flat
(RSS +12%, throughput -11%) — established by an LD_PRELOAD A/B on the identical
workload and confirmed here with the compiled-in build (the churn soak passes,
RSS plateaus). This is a glibc allocator behavior under churn, not a leak in
broker logic (profiling ruled out connection/consumer/fd/task/unacked leaks).

tikv-jemallocator is wired as `#[global_allocator]` in the `ramqp-brokerd` bin,
behind a default-on `jemalloc` feature; `--no-default-features` opts out on
targets jemalloc does not support. Only the daemon sets the allocator — the
library never imposes it on downstream users.

ramqp-broker 0.8.28 -> 0.8.29.
@mack42 mack42 self-assigned this Jul 11, 2026
@mack42
mack42 merged commit 0bfe52a into main Jul 11, 2026
8 checks passed
@mack42
mack42 deleted the fix/jemalloc-allocator branch July 11, 2026 18:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

RSS growth + throughput collapse under connection churn is glibc malloc fragmentation (ship jemalloc)

1 participant