From 486c2046099006a19025563d266fc7abef4bee44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20=C3=81ngel?= Date: Mon, 25 May 2026 19:29:11 +0000 Subject: [PATCH] fix(engine): probe nvidia-smi for actual VRAM before falling back to heuristic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On NVIDIA systems, spawns nvidia-smi once (cached) to read actual GPU memory. Uses real VRAM for the Chrome GPU budget instead of guessing from total system RAM. Falls back to total/2 on non-NVIDIA systems or when nvidia-smi is unavailable. No other headless Chrome renderer probes GPU memory — Remotion, Puppeteer, and Playwright all ignore --force-gpu-mem-available-mb entirely. --- .../engine/src/services/browserManager.ts | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/packages/engine/src/services/browserManager.ts b/packages/engine/src/services/browserManager.ts index 8423fc0b2..0361dfce6 100644 --- a/packages/engine/src/services/browserManager.ts +++ b/packages/engine/src/services/browserManager.ts @@ -480,7 +480,32 @@ function getTotalMemMb(): number { return Math.floor(totalmem() / (1024 * 1024)); } +let _cachedVramMb: number | null = null; + +function probeNvidiaVramMb(): number | null { + if (_cachedVramMb !== null) return _cachedVramMb; + try { + const { execSync } = require("child_process") as typeof import("child_process"); + const out = execSync("nvidia-smi --query-gpu=memory.total --format=csv,noheader,nounits", { + timeout: 3000, + encoding: "utf-8", + stdio: ["pipe", "pipe", "pipe"], + }).trim(); + const mb = parseInt(out.split("\n")[0] ?? "", 10); + if (Number.isFinite(mb) && mb > 0) { + _cachedVramMb = mb; + return mb; + } + } catch { + // nvidia-smi not available or no NVIDIA GPU + } + return null; +} + function getGpuMemBudgetMb(): number { + const vram = probeNvidiaVramMb(); + if (vram) return Math.min(vram, 65536); + const total = getTotalMemMb(); if (total < 4096) return 512; if (total < 8192) return 1024;