Fix docs shm calculator (#24649)
CI / AMD64 Build (push) Waiting to run
CI / ARM Build (push) Waiting to run
CI / Jetson Jetpack 6 (push) Waiting to run
CI / AMD64 Extra Build (push) Blocked by required conditions
CI / ARM Extra Build (push) Blocked by required conditions
CI / Synaptics Build (push) Blocked by required conditions
CI / Assemble and push default build (push) Blocked by required conditions

* match the docs shm calculator to the backend's minimum

The calculator left out the room Frigate reserves for 2 cameras added at runtime, counted the per-frame overhead once per camera instead of per frame, and reserved 40mb instead of 50mb for logs and the nginx cache, so a setup sized with it got well under 20 frames and the "SHM size is too small" warning. It now computes the same minimum as calculate_shm_requirements() and also shows the size for the full 50 frame cache.

* size the docs shm calculator for 25 frames

Sizing to the backend's 20 frame minimum could land at 19 frames from float rounding and still show the warning.
This commit is contained in:
Josh Hawkins
2026-10-12 13:51:21 -06:00
committed by GitHub
parent cf67f08913
commit 41d9577d72
2 changed files with 51 additions and 32 deletions
+2 -2
View File
@@ -78,9 +78,9 @@ Users of the Snapcraft build of Docker cannot use storage locations outside your
Frigate utilizes shared memory to store frames during processing. The default `shm-size` provided by Docker is **64MB**. Frigate utilizes shared memory to store frames during processing. The default `shm-size` provided by Docker is **64MB**.
The default shm size of **128MB** is fine for setups with **2 cameras** detecting at **720p**. If Frigate is exiting with "Bus error" messages, it is likely because you have too many high resolution cameras and you need to specify a higher shm size, using [`--shm-size`](https://docs.docker.com/engine/reference/run/#runtime-constraints-on-resources) (or [`service.shm_size`](https://docs.docker.com/compose/compose-file/compose-file-v2/#shm_size) in Docker Compose). If raising the shm size does not help, check your [process and file limits](#process-and-file-limits) as well. Frigate needs about **210MB** for **2 cameras** detecting at **720p**. If Frigate is exiting with "Bus error" messages, it is likely because you have too many high resolution cameras and you need to specify a higher shm size, using [`--shm-size`](https://docs.docker.com/engine/reference/run/#runtime-constraints-on-resources) (or [`service.shm_size`](https://docs.docker.com/compose/compose-file/compose-file-v2/#shm_size) in Docker Compose). If raising the shm size does not help, check your [process and file limits](#process-and-file-limits) as well.
The Frigate container also stores logs in shm, which can take up to **40MB**, so make sure to take this into account in your math as well. The Frigate container also stores logs and an nginx cache in shm, which can take up to **50MB**. The calculator below includes this, along with room for 2 cameras added while Frigate is running. Its result holds about 25 frames per camera, a little above the 20 frame minimum Frigate warns below. Frigate keeps up to 50 when there is room, which gives slow processes more time to read each frame.
<ShmCalculator/> <ShmCalculator/>
+47 -28
View File
@@ -2,42 +2,53 @@ import React, { useState, useEffect } from "react";
import Admonition from "@theme/Admonition"; import Admonition from "@theme/Admonition";
import styles from "./styles.module.css"; import styles from "./styles.module.css";
// follows calculate_shm_requirements() in frigate/util/services.py, but sizes
// for 25 frames so float rounding can't land under its 20 frame warning
const MB = 1048576;
const RESERVED_MB = 50; // logs + nginx cache
const TARGET_FRAMES = 25;
const DEFAULT_FRAMES = 50;
const frameMb = (width, height) =>
Math.round(((width * height * 1.5 + 270480) / MB) * 10) / 10;
// room for 2 cameras added at runtime, sized as 720p
const addedCamerasMb = 2 * frameMb(1280, 720);
const ShmCalculator = () => { const ShmCalculator = () => {
const [width, setWidth] = useState(1280); const [width, setWidth] = useState(1280);
const [height, setHeight] = useState(720); const [height, setHeight] = useState(720);
const [cameraCount, setCameraCount] = useState(1); const [cameraCount, setCameraCount] = useState(1);
const [result, setResult] = useState("26.32MB"); const [result, setResult] = useState("-");
const [singleCameraShm, setSingleCameraShm] = useState("26.32MB"); const [singleCameraShm, setSingleCameraShm] = useState("-");
const [totalShm, setTotalShm] = useState("26.32MB"); const [addedCamerasShm, setAddedCamerasShm] = useState("-");
const [fullRingShm, setFullRingShm] = useState("-");
const calculate = () => { const calculate = () => {
if (!width || !height || !cameraCount) { if (!width || !height || !cameraCount) {
setResult("Please enter valid values"); setResult("Please enter valid values");
setSingleCameraShm("-"); setSingleCameraShm("-");
setTotalShm("-"); setAddedCamerasShm("-");
setFullRingShm("-");
return; return;
} }
// Single camera base SHM calculation (excluding logs) const cameraFramesMb = cameraCount * frameMb(width, height) + addedCamerasMb;
// Formula: (width * height * 1.5 * 20 + 270480) / 1048576
const singleCameraBase =
(width * height * 1.5 * 20 + 270480) / 1048576;
setSingleCameraShm(`${singleCameraBase.toFixed(2)}mb`);
// Total SHM calculation (multiple cameras, including logs) setSingleCameraShm(formatMb(frameMb(width, height) * TARGET_FRAMES));
const totalBase = singleCameraBase * cameraCount; setAddedCamerasShm(formatMb(addedCamerasMb * TARGET_FRAMES));
const finalResult = totalBase + 40; // Default includes logs +40mb setResult(formatMb(Math.round(RESERVED_MB + cameraFramesMb * TARGET_FRAMES)));
setFullRingShm(
formatMb(Math.round(RESERVED_MB + cameraFramesMb * DEFAULT_FRAMES)),
);
};
setTotalShm(`${(totalBase + 40).toFixed(2)}mb`); const formatMb = (value) => {
if (value >= 1024) {
// Format result return `${(value / 1024).toFixed(2)}gb`;
if (finalResult < 1) {
setResult(`${(finalResult * 1024).toFixed(2)}kb`);
} else if (finalResult >= 1024) {
setResult(`${(finalResult / 1024).toFixed(2)}gb`);
} else {
setResult(`${finalResult.toFixed(2)}mb`);
} }
return `${Number(value.toFixed(2))}mb`;
}; };
const formatWithUnit = (value) => { const formatWithUnit = (value) => {
@@ -147,19 +158,27 @@ const ShmCalculator = () => {
</div> </div>
<div className={styles.formulaDisplay}> <div className={styles.formulaDisplay}>
<p> <p>
<strong>Single Camera:</strong> {formatWithUnit(singleCameraShm)} <strong>Per Camera:</strong> {formatWithUnit(singleCameraShm)}
</p> </p>
<p> <p>
<strong>Formula:</strong> (width × height × 1.5 × 20 + 270480) ÷ <strong>Formula:</strong> (width × height × 1.5 + 270480) ÷
1048576 1048576 × {TARGET_FRAMES} frames
</p> </p>
{cameraCount > 1 && (
<p> <p>
<strong>Total ({cameraCount} cameras):</strong> {formatWithUnit(totalShm)} <strong>Room for 2 Added Cameras:</strong>{" "}
{formatWithUnit(addedCamerasShm)}
</p> </p>
)}
<p> <p>
<strong>With Logs:</strong> + 40<span className={styles.unit}>mb</span> <strong>Logs and Cache:</strong> + {RESERVED_MB}
<span className={styles.unit}>mb</span>
</p>
<p>
<strong>Birdseye Restream:</strong> + 8
<span className={styles.unit}>mb</span> if enabled
</p>
<p>
<strong>For {DEFAULT_FRAMES} Frames:</strong>{" "}
{formatWithUnit(fullRingShm)}
</p> </p>
</div> </div>
</div> </div>