From ecbe5c722303465ebecd4169e5e0574c68a3c74b Mon Sep 17 00:00:00 2001 From: pavanmanishd Date: Fri, 23 Oct 2026 01:15:57 +0530 Subject: [PATCH] fix(bottomless): reap finished S3 uploads as they complete The upload loop spawns one task per WAL batch into a JoinSet and drains that set only after the receive loop ends, which happens at shutdown. A JoinSet keeps every finished task until it is joined, so each uploaded batch stayed in memory for the life of the replicator. Reap the finished uploads inside the receive loop. The retained set is then bounded by s3_max_parallelism instead of growing with the WAL. Fixes #2298. --- bottomless/src/replicator.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/bottomless/src/replicator.rs b/bottomless/src/replicator.rs index 6f318fd125..b942886199 100644 --- a/bottomless/src/replicator.rs +++ b/bottomless/src/replicator.rs @@ -483,6 +483,12 @@ impl Replicator { } drop(permit); }); + + // A JoinSet holds every finished task until it is joined, so + // without this the set keeps one entry per uploaded batch for + // the whole life of the replicator and memory grows with the + // WAL. Reap the finished uploads as they complete. + while join_set.try_join_next().is_some() {} } while join_set.join_next().await.is_some() {}