From a974ff68e00278ccaf441b0567cd46e2b5067fdd Mon Sep 17 00:00:00 2001 From: Ruben Fiszel Date: Tue, 19 May 2026 13:53:30 +0000 Subject: [PATCH] fix: enable jemalloc background_thread to prevent worker RSS growth (#9236) * fix: enable jemalloc background purge to prevent worker RSS growth Co-Authored-By: Claude Opus 4.7 (1M context) * fix: drop decay overrides, keep only jemalloc background_thread The background thread is the actual fix; jemalloc's default decay windows (dirty 10s, muzzy 0) are correct for months-long workers and muzzy_decay_ms:5000 was more retentive than the default. Co-Authored-By: Claude Opus 4.7 (1M context) --------- Co-authored-by: Claude Opus 4.7 (1M context) --- backend/src/main.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/backend/src/main.rs b/backend/src/main.rs index 74e2c240ba..3a6def74a0 100644 --- a/backend/src/main.rs +++ b/backend/src/main.rs @@ -89,6 +89,20 @@ use tikv_jemallocator::Jemalloc; #[global_allocator] static GLOBAL: Jemalloc = Jemalloc; +// Stock jemalloc only purges freed pages during alloc/free calls on app +// threads, so a long-lived worker that goes quiet after a burst never runs the +// purge: RSS freezes at the high-water mark and eventually OOMs under a hard +// cgroup limit. Enabling the background thread makes the decay run on idle, +// returning pages to the OS; the decay windows are left at jemalloc defaults +// (dirty 10s, muzzy 0) on purpose — over a worker's months-long lifetime there +// is no benefit to reclaiming more aggressively than that. jemalloc applies the +// _RJEM_MALLOC_CONF env var after this symbol, so operators can still tune +// decay or add prof:* for profiling. +#[cfg(all(not(target_env = "msvc"), feature = "jemalloc"))] +#[allow(non_upper_case_globals)] +#[export_name = "_rjem_malloc_conf"] +pub static malloc_conf: &[u8] = b"background_thread:true\0"; + #[cfg(feature = "parquet")] use windmill_common::global_settings::OBJECT_STORE_CONFIG_SETTING;