Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 22 additions & 5 deletions packages/engine/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
* fallbacks for backward compatibility during migration.
*/

import { totalmem } from "os";

/**
* Full engine configuration. All fields are wired through the config
* object; env vars serve as backward-compatible fallbacks resolved
Expand Down Expand Up @@ -208,6 +210,24 @@ export const DEFAULT_CONFIG: EngineConfig = {
debug: false,
};

function getSystemTotalMb(): number {
return Math.floor(totalmem() / (1024 * 1024));
}

function memoryAdaptiveCacheLimit(): number {
const total = getSystemTotalMb();
if (total < 4096) return 32;
if (total < 8192) return 64;
return DEFAULT_CONFIG.frameDataUriCacheLimit;
}

function memoryAdaptiveCacheBytesMb(): number {
const total = getSystemTotalMb();
if (total < 4096) return 128;
if (total < 8192) return 256;
return DEFAULT_CONFIG.frameDataUriCacheBytesLimitMb;
}

/**
* Resolve configuration by merging: defaults ← env vars ← explicit overrides.
* Env vars provide backward compatibility during migration; explicit config
Expand Down Expand Up @@ -298,14 +318,11 @@ export function resolveConfig(overrides?: Partial<EngineConfig>): EngineConfig {
audioGain: envNum("PRODUCER_AUDIO_GAIN", DEFAULT_CONFIG.audioGain),
frameDataUriCacheLimit: Math.max(
32,
envNum("PRODUCER_FRAME_DATA_URI_CACHE_LIMIT", DEFAULT_CONFIG.frameDataUriCacheLimit),
envNum("PRODUCER_FRAME_DATA_URI_CACHE_LIMIT", memoryAdaptiveCacheLimit()),
),
frameDataUriCacheBytesLimitMb: Math.max(
64,
envNum(
"PRODUCER_FRAME_DATA_URI_CACHE_BYTES_MB",
DEFAULT_CONFIG.frameDataUriCacheBytesLimitMb,
),
envNum("PRODUCER_FRAME_DATA_URI_CACHE_BYTES_MB", memoryAdaptiveCacheBytesMb()),
),

playerReadyTimeout: envNum(
Expand Down
51 changes: 48 additions & 3 deletions packages/engine/src/services/browserManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@
*/

import type { Browser, PuppeteerNode } from "puppeteer-core";
import { execSync } from "child_process";
import { existsSync, readdirSync } from "fs";
import { join } from "path";
import { homedir } from "os";
import { homedir, totalmem } from "os";
import { DEFAULT_CONFIG, type EngineConfig } from "../config.js";

let _puppeteer: PuppeteerNode | undefined;
Expand Down Expand Up @@ -476,6 +477,49 @@ export function _setPuppeteerForTests(mock: PuppeteerNode | undefined): void {
_puppeteer = mock;
}

function getTotalMemMb(): number {
return Math.floor(totalmem() / (1024 * 1024));
}

let _cachedVramMb: number | null = null;

function probeNvidiaVramMb(): number | null {
if (_cachedVramMb !== null) return _cachedVramMb;
try {
// Synchronous, runs once per process (cached). ~50ms on typical systems.
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, 16384);

const total = getTotalMemMb();
if (total < 4096) return 512;
if (total < 8192) return 1024;
return Math.min(Math.floor(total / 2), 16384);
}

function getLowMemoryFlags(): string[] {
const total = getTotalMemMb();
if (total >= 8192) return [];
const heapMb = total < 4096 ? 256 : 512;
return [`--js-flags=--max-old-space-size=${heapMb}`];
}

export interface BuildChromeArgsOptions {
width: number;
height: number;
Expand Down Expand Up @@ -530,9 +574,10 @@ export function buildChromeArgs(
"--disable-print-preview",
"--no-pings",
"--no-zygote",
// Memory
"--force-gpu-mem-available-mb=4096",
// Memory — scale GPU budget to available system RAM
`--force-gpu-mem-available-mb=${getGpuMemBudgetMb()}`,
"--disk-cache-size=268435456",
...getLowMemoryFlags(),
// Disable features that add overhead
"--disable-features=AudioServiceOutOfProcess,IsolateOrigins,site-per-process,Translate,BackForwardCache,IntensiveWakeUpThrottling",
];
Expand Down
Loading