Skip to content

Commit 441cce1

Browse files
committed
Use process RSS + env limit for memory throttling
1 parent b6ca4ce commit 441cce1

File tree

1 file changed

+15
-13
lines changed

1 file changed

+15
-13
lines changed

apps/media-server/src/lib/job-manager.ts

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,10 @@ const configuredMaxProcesses =
6666
) || 0;
6767

6868
const cpuCount = os.cpus().length;
69-
const totalMemoryMB = os.totalmem() / (1024 * 1024);
7069

7170
const CPU_LOAD_THRESHOLD = 0.8;
72-
const MEMORY_FREE_THRESHOLD = 0.15;
71+
const PROCESS_RSS_LIMIT_MB =
72+
Number.parseInt(process.env.MEDIA_SERVER_MEMORY_LIMIT_MB ?? "0", 10) || 0;
7373

7474
function isActivePhase(phase: JobPhase): boolean {
7575
return phase !== "complete" && phase !== "error" && phase !== "cancelled";
@@ -96,19 +96,20 @@ export interface SystemResources {
9696
cpuCount: number;
9797
loadAvg1m: number;
9898
cpuPressure: number;
99-
totalMemoryMB: number;
100-
freeMemoryMB: number;
101-
memoryUsagePercent: number;
99+
processRssMB: number;
100+
processHeapMB: number;
101+
processRssLimitMB: number;
102102
configuredMax: number;
103103
effectiveMax: number;
104104
throttleReason: string | null;
105105
}
106106

107107
export function getSystemResources(): SystemResources {
108108
const loadAvg1m = os.loadavg()[0];
109-
const freeMemoryMB = os.freemem() / (1024 * 1024);
110109
const cpuPressure = loadAvg1m / cpuCount;
111-
const memoryUsagePercent = 1 - freeMemoryMB / totalMemoryMB;
110+
const mem = process.memoryUsage();
111+
const processRssMB = Math.round(mem.rss / (1024 * 1024));
112+
const processHeapMB = Math.round(mem.heapUsed / (1024 * 1024));
112113
const max = getMaxConcurrentVideoProcesses();
113114

114115
let effectiveMax = max;
@@ -122,21 +123,22 @@ export function getSystemResources(): SystemResources {
122123
throttleReason = `CPU load ${cpuPressure.toFixed(2)} exceeds ${CPU_LOAD_THRESHOLD} threshold`;
123124
}
124125

125-
if (memoryUsagePercent > 1 - MEMORY_FREE_THRESHOLD) {
126-
const memMax = Math.max(1, Math.floor(max * (1 - memoryUsagePercent)));
126+
if (PROCESS_RSS_LIMIT_MB > 0 && processRssMB > PROCESS_RSS_LIMIT_MB * 0.85) {
127+
const memPressure = processRssMB / PROCESS_RSS_LIMIT_MB;
128+
const memMax = Math.max(1, Math.floor(max * (1 - memPressure)));
127129
if (memMax < effectiveMax) {
128130
effectiveMax = memMax;
129-
throttleReason = `Memory usage ${(memoryUsagePercent * 100).toFixed(0)}% exceeds ${((1 - MEMORY_FREE_THRESHOLD) * 100).toFixed(0)}% threshold`;
131+
throttleReason = `Process RSS ${processRssMB}MB exceeds 85% of ${PROCESS_RSS_LIMIT_MB}MB limit`;
130132
}
131133
}
132134

133135
return {
134136
cpuCount,
135137
loadAvg1m,
136138
cpuPressure,
137-
totalMemoryMB: Math.round(totalMemoryMB),
138-
freeMemoryMB: Math.round(freeMemoryMB),
139-
memoryUsagePercent,
139+
processRssMB,
140+
processHeapMB,
141+
processRssLimitMB: PROCESS_RSS_LIMIT_MB,
140142
configuredMax: configuredMaxProcesses,
141143
effectiveMax,
142144
throttleReason,

0 commit comments

Comments
 (0)