From a4b1fbd6ee320817ba470f6cddcd4f87c32d7c45 Mon Sep 17 00:00:00 2001 From: Nikolay Govorov Date: Tue, 10 Feb 2026 00:44:07 +0000 Subject: [PATCH 1/4] Use cgroups for RAM mesurement --- .github/workflows/e2e-test.yml | 44 +++++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 9 deletions(-) diff --git a/.github/workflows/e2e-test.yml b/.github/workflows/e2e-test.yml index 87cf9d8e..a2bba668 100644 --- a/.github/workflows/e2e-test.yml +++ b/.github/workflows/e2e-test.yml @@ -122,9 +122,10 @@ jobs: needs: zig-build-release env: - MAX_MEMORY: 26000 + MAX_MEMORY: 26000 # 26MB (KB) MAX_AVG_DURATION: 17 LIGHTPANDA_DISABLE_TELEMETRY: true + CG: /sys/fs/cgroup/lpd_${{ github.run_id }}_${{ github.run_attempt }} # use a self host runner. runs-on: lpd-bench-hetzner @@ -150,12 +151,27 @@ jobs: go run ws/main.go & echo $! > WS.pid sleep 2 + - name: run lightpanda in cgroup + run: | + if [ ! -f /sys/fs/cgroup/cgroup.controllers ]; then + echo "cgroup v2 not available: /sys/fs/cgroup/cgroup.controllers missing" + exit 1 + fi + + sudo mkdir -p $CG + + if [[ -f /sys/fs/cgroup/cgroup.subtree_control ]]; then + echo "+memory" | sudo tee /sys/fs/cgroup/cgroup.subtree_control >/dev/null 2>&1 || true + fi + + ./lightpanda serve & echo $! > LPD.pid + cat LPD.pid | sudo tee $CG/cgroup.procs >/dev/null + + sleep 2 + - name: run puppeteer run: | - ./lightpanda serve & echo $! > LPD.pid - sleep 2 RUNS=100 npm run bench-puppeteer-cdp > puppeteer.out || exit 1 - cat /proc/`cat LPD.pid`/status |grep VmHWM|grep -oP '\d+' > LPD.VmHWM kill `cat LPD.pid` - name: puppeteer result @@ -163,9 +179,19 @@ jobs: - name: memory regression run: | - export LPD_VmHWM=`cat LPD.VmHWM` - echo "Peak resident set size: $LPD_VmHWM" - test "$LPD_VmHWM" -le "$MAX_MEMORY" + PID=$(cat LPD.pid) + while kill -0 $PID 2>/dev/null; do + sleep 1 + done + if [ ! -f $CG/memory.peak ]; then + echo "memory.peak not available in $CG" + exit 1 + fi + PEAK_BYTES=$(cat $CG/memory.peak) + PEAK_KB=$((PEAK_BYTES / 1024)) + echo "memory.peak_bytes=$PEAK_BYTES" + echo "memory.peak_kb=$PEAK_KB" + test "$PEAK_KB" -le "$MAX_MEMORY" - name: duration regression run: | @@ -177,8 +203,8 @@ jobs: run: | export AVG_DURATION=`cat puppeteer.out|grep 'avg run'|sed 's/avg run duration (ms) //'` export TOTAL_DURATION=`cat puppeteer.out|grep 'total duration'|sed 's/total duration (ms) //'` - export LPD_VmHWM=`cat LPD.VmHWM` - echo "{\"duration_total\":${TOTAL_DURATION},\"duration_avg\":${AVG_DURATION},\"mem_peak\":${LPD_VmHWM}}" > bench.json + export LPD_MEM_PEAK_KB=$(( $(cat $CG/memory.peak) / 1024 )) + echo "{\"duration_total\":${TOTAL_DURATION},\"duration_avg\":${AVG_DURATION},\"mem_peak\":${LPD_MEM_PEAK_KB}}" > bench.json cat bench.json - name: run hyperfine From 3e1909b645b66b4fde02febda39c611d8435949b Mon Sep 17 00:00:00 2001 From: Pierre Tachoire Date: Tue, 10 Feb 2026 15:51:44 +0100 Subject: [PATCH 2/4] ci: use cgroups with user's permissions --- .github/workflows/e2e-test.yml | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/.github/workflows/e2e-test.yml b/.github/workflows/e2e-test.yml index a2bba668..934f7bcc 100644 --- a/.github/workflows/e2e-test.yml +++ b/.github/workflows/e2e-test.yml @@ -125,7 +125,14 @@ jobs: MAX_MEMORY: 26000 # 26MB (KB) MAX_AVG_DURATION: 17 LIGHTPANDA_DISABLE_TELEMETRY: true - CG: /sys/fs/cgroup/lpd_${{ github.run_id }}_${{ github.run_attempt }} + + # How to give cgroups access to the user actions-runner on the host: + # $ sudo apt install cgroup-tools + # $ sudo chmod o+w /sys/fs/cgroup/cgroup.procs + # $ sudo mkdir -p /sys/fs/cgroup/actions-runner + # $ sudo chown -R actions-runner:actions-runner /sys/fs/cgroup/actions-runner + CG_ROOT: /sys/fs/cgroup + CG: actions-runner/lpd_${{ github.run_id }}_${{ github.run_attempt }} # use a self host runner. runs-on: lpd-bench-hetzner @@ -158,14 +165,8 @@ jobs: exit 1 fi - sudo mkdir -p $CG - - if [[ -f /sys/fs/cgroup/cgroup.subtree_control ]]; then - echo "+memory" | sudo tee /sys/fs/cgroup/cgroup.subtree_control >/dev/null 2>&1 || true - fi - - ./lightpanda serve & echo $! > LPD.pid - cat LPD.pid | sudo tee $CG/cgroup.procs >/dev/null + mkdir -p $CG_ROOT/$CG + cgexec -g memory:$CG ./lightpanda serve & echo $! > LPD.pid sleep 2 @@ -183,16 +184,19 @@ jobs: while kill -0 $PID 2>/dev/null; do sleep 1 done - if [ ! -f $CG/memory.peak ]; then + if [ ! -f $CG_ROOT/$CG/memory.peak ]; then echo "memory.peak not available in $CG" exit 1 fi - PEAK_BYTES=$(cat $CG/memory.peak) + PEAK_BYTES=$(cat $CG_ROOT/$CG/memory.peak) PEAK_KB=$((PEAK_BYTES / 1024)) echo "memory.peak_bytes=$PEAK_BYTES" echo "memory.peak_kb=$PEAK_KB" test "$PEAK_KB" -le "$MAX_MEMORY" + - name: cleanup cgroup + run: rmdir $CG_ROOT/$CG + - name: duration regression run: | export PUPPETEER_AVG_DURATION=`cat puppeteer.out|grep 'avg run'|sed 's/avg run duration (ms) //'` From 6b953b879369684b386f0a8657952de16d4098ff Mon Sep 17 00:00:00 2001 From: Pierre Tachoire Date: Thu, 12 Feb 2026 11:24:59 +0100 Subject: [PATCH 3/4] ci: keep both vm and cg memory regression tests --- .github/workflows/e2e-test.yml | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/.github/workflows/e2e-test.yml b/.github/workflows/e2e-test.yml index 934f7bcc..a64dff6d 100644 --- a/.github/workflows/e2e-test.yml +++ b/.github/workflows/e2e-test.yml @@ -122,7 +122,8 @@ jobs: needs: zig-build-release env: - MAX_MEMORY: 26000 # 26MB (KB) + MAX_VmHWM: 26000 # 26MB (KB) + MAX_CG_PEAK: 6000 # 6MB (KB) MAX_AVG_DURATION: 17 LIGHTPANDA_DISABLE_TELEMETRY: true @@ -173,12 +174,13 @@ jobs: - name: run puppeteer run: | RUNS=100 npm run bench-puppeteer-cdp > puppeteer.out || exit 1 + cat /proc/`cat LPD.pid`/status |grep VmHWM|grep -oP '\d+' > LPD.VmHWM kill `cat LPD.pid` - name: puppeteer result run: cat puppeteer.out - - name: memory regression + - name: cgroup memory regression run: | PID=$(cat LPD.pid) while kill -0 $PID 2>/dev/null; do @@ -192,7 +194,13 @@ jobs: PEAK_KB=$((PEAK_BYTES / 1024)) echo "memory.peak_bytes=$PEAK_BYTES" echo "memory.peak_kb=$PEAK_KB" - test "$PEAK_KB" -le "$MAX_MEMORY" + test "$PEAK_KB" -le "$MAX_CG_PEAK" + + - name: virtual memory regression + run: | + export LPD_VmHWM=`cat LPD.VmHWM` + echo "Peak resident set size: $LPD_VmHWM" + test "$LPD_VmHWM" -le "$MAX_VmHWM" - name: cleanup cgroup run: rmdir $CG_ROOT/$CG From 7df67630affb0ca795aff631c7ae48eb082e9293 Mon Sep 17 00:00:00 2001 From: Pierre Tachoire Date: Thu, 12 Feb 2026 11:33:52 +0100 Subject: [PATCH 4/4] ci: add cg_mem_peak into the tracked results --- .github/workflows/e2e-test.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/e2e-test.yml b/.github/workflows/e2e-test.yml index a64dff6d..d5840ff4 100644 --- a/.github/workflows/e2e-test.yml +++ b/.github/workflows/e2e-test.yml @@ -215,8 +215,9 @@ jobs: run: | export AVG_DURATION=`cat puppeteer.out|grep 'avg run'|sed 's/avg run duration (ms) //'` export TOTAL_DURATION=`cat puppeteer.out|grep 'total duration'|sed 's/total duration (ms) //'` - export LPD_MEM_PEAK_KB=$(( $(cat $CG/memory.peak) / 1024 )) - echo "{\"duration_total\":${TOTAL_DURATION},\"duration_avg\":${AVG_DURATION},\"mem_peak\":${LPD_MEM_PEAK_KB}}" > bench.json + export LPD_VmHWM=`cat LPD.VmHWM` + export LPD_CG_PEAK_KB=$(( $(cat $CG/memory.peak) / 1024 )) + echo "{\"duration_total\":${TOTAL_DURATION},\"duration_avg\":${AVG_DURATION},\"mem_peak\":${LPD_VmHWM},\"cg_mem_peak\":${LPD_MEM_CG_KB}}" > bench.json cat bench.json - name: run hyperfine