How Helen Gets Made A making-of, not the live show Watch her live

Frigate · retention · plain language, real numbers

How much disk a 24/7 cat cam really eats, and how we set retention

Three days of everything and twenty-one days of anything with a cat in it: that shape is why eleven cameras fit on one spinning drive.

The numbers here are measured on our drive, not estimated from a bitrate chart. The config they come from is on the config page.

Helen, a dilute tortoiseshell calico, at the water bowl; the clip of this moment is kept for 21 days, the empty bowl before it for 3
The cat is worth three weeks. The empty room around her is worth three days. Retention is deciding which is which.

One always-on 1440p Tapo writes 16.4 GiB a day. Nine cameras wrote 107.3 GiB on 2026-09-01. Those two numbers, from adding up a day's files and then checking against Frigate's own per-camera accounting, are the ones to size a drive from, and an earlier version of this page had the first of them wrong by nearly three times (the correction is under Measured, below). The rest is retention: how many of those days to keep, and of what. The YAML in context with the other ten cameras is the record block on the config page; the drive it lands on is described on the WSL2 setup page.

The shape we use

Frigate can keep two different things: continuous recording (every second from every camera) and event recording (only the segments where a tracked object was in frame, with a bit of padding). They have separate retention. The trick is to be stingy with the first and generous with the second, because the first is almost entirely empty room and the second is the only part you will ever open.

record: as it runs
record:
  enabled: true
  continuous:
    days: 3          # everything, from every recording camera
  alerts:
    retain:
      days: 21       # segments with a tracked object that qualified as an alert
  detections:
    retain:
      days: 21       # segments with any tracked object

snapshots:
  enabled: true
  retain:
    default: 21

# per-camera override for the house cameras
cameras:
  front_door:
    record:
      enabled: true
      continuous:
        days: 21

On the cat cameras that reads: three days of tape you can scrub through if something odd happened, and three weeks of every visit to every bowl. The three house cameras (front door, back yard, carport) override it to 21 days continuous, because a house is a different question and nothing is tracked on them anyway. Snapshots follow the events at 21 days so a visit always has a still to review.

Measured

The arithmetic, from two measurements taken 2026-09-03 (GiB = 1024³ bytes throughout)
1. One full day on disk, per camera (find -printf %s over recordings/2026-09-01/*/<cam>, 00:27 UTC):
  cat_water_bowl       16.4 GiB   8,638 segments   continuous 1440p main stream, Tapo
  cat_food_bowl        16.3 GiB   8,638
  cat_scratching_pad   16.4 GiB   8,637
  helen_food_face      16.4 GiB   8,636
  cat_treat_dispenser  15.5 GiB   8,600
  bed_cam               6.6 GiB   7,008            offline for part of the day
  playroom_cam          3.4 GiB   8,628            lower main-stream bitrate on that camera
  front_door            8.2 GiB   8,628            house camera, Tapo, lower main-stream bitrate
  carport               8.1 GiB   8,630
  back_yard               -                        offline
  ---------------------------------
  the set              107.3 GiB  written in one day, nine cameras

2. Frigate's own accounting, GET /api/recordings/storage (00:31 UTC).
   usage = sum of its segment sizes, in MiB; bandwidth = MiB per hour averaged over the last 100 segments:
  cat_water_bowl       usage 51,466   bandwidth 705.16     (705 x 24 / 1024 = 16.5 GiB/day; matches 1.)
  cat_food_bowl        usage 55,914   bandwidth 706.23
  cat_scratching_pad   usage 54,626   bandwidth 702.08
  helen_food_face      usage 53,426   bandwidth 701.39
  cat_treat_dispenser  usage 49,993   bandwidth 704.46
  bed_cam              usage 17,128   bandwidth 399.27
  playroom_cam         usage 11,242   bandwidth 206.85
  front_door           usage 70,845   bandwidth 191.08     (a night-time average; the day on disk says 8.2 GiB)
  carport              usage 65,792   bandwidth 181.49
  back_yard            usage    224   bandwidth 225.97
  total                430,657 MiB = 420.6 GiB of recordings

Per camera, continuous, 1440p Tapo main stream:   16.4 GiB / day   (= 1.63 Mbit/s average)
General formula:   GB per day = Mbit/s x 10.8   (86,400 s / 8 bits / 1,000; 1.63 Mbit/s = 17.6 GB = 16.4 GiB)
                   a camera set to 4 Mbit/s writes 43 GB (40 GiB) a day

What the tiers cost on this box today:
  cat camera, 3 d continuous + 21 d events:   3 x 16.4 = 49 GiB, plus about 1 GiB of event segments so far
                                              (the water cam's 50.3 GiB minus its 3 continuous days; the event
                                               tier is still filling, at roughly 0.2 GiB a day at current visit rates)
  house camera, 21 d continuous at 8.2 GiB/d:  ~172 GiB when full; the drive shows full coverage since 2026-08-27,
                                              so front_door's 69 GiB is 7 full days plus sparse older segments

Worked examples, continuous, at the measured 16.4 GiB per camera per day:
  4 cams x  7 days   =  ~460 GiB    fits a 1 TB drive (931 GiB) with the event tier on top
  7 cams x 21 days   =  ~2.4 TiB    needs a 4 TB drive (3.6 TiB); a 2 TB drive (1.8 TiB) is not enough
  7 cams x  3 days   =  ~345 GiB    + 21 days of events on top (our shape for the seven cat cams)

The number to carry away is the per-camera one: 16.4 GiB per camera per day of continuous main-stream H.264 from a 1440p Tapo at the bitrate ours run at, measured by adding up one day of one camera's files, and confirmed by Frigate's own MiB-per-hour figure. Two of our cameras write half that and one a fifth of it, so the same camera family does not mean the same bitrate: measure one day of yours before you buy the drive. Two things this page said before 2026-09-03 were wrong and are worth naming so nobody sizes from a cached copy: the "902 GB" in /api/stats is the whole D: drive as the filesystem reports it, not the recordings (Frigate's own count is 420 GiB), and dividing that by cameras and days produced "6 GB per camera per day", which under-sizes a continuous 1440p camera by nearly three times.

  1. Decide what you open. It is events; nobody scrubs six hours of an empty bowl. Keep a few days of everything and many days of events.
  2. Set the global record block. Continuous 3, alerts 21, detections 21, snapshots 21. For a pet camera there is nothing else to set.
  3. Override per camera where history matters. A door, a driveway, a gate: continuous: days: 21 on that camera only. Leave the cat cameras on the global three.
  4. Size the drive from the per-camera number. About 16.4 GiB per camera per day if it is always on at 1440p. Four cameras for a week is about 460 GiB. Seven cameras for three weeks continuous is 2.4 TiB, a 4 TB drive; seven cameras with our shape is about 345 GiB plus the cat.
  5. Check after a week, then after three. GET /api/recordings/storage is Frigate's own per-camera count (usage in MiB, bandwidth in MiB per hour); du on one day folder tells the truth on disk. service.storage in /api/stats is the whole filesystem, not the recordings, and on a shared drive it will mislead you. Retention has not really happened until the oldest day has been deleted once; on our box the house cameras have had 21-day continuous on since 2026-08-27, so their tier is still filling.
  6. When it fills, cut continuous days first. Then per-camera overrides. Then event days, last. Every knob is one number in the file and takes effect on the next cleanup pass.

Where the files live, and the two memory settings

Ours are on an NTFS drive on a Windows machine, reached from the Linux side through WSL's 9p file sharing; Frigate reports the mount as mount_type: 9p. Our own build plan from July said not to do that. At 107 GiB a day across nine cameras it has been fine for weeks, with the caveat that Docker's own files must not be there (they are on the Linux disk). Two settings in the compose file matter for recording and are easy to get wrong: a 1 GB tmpfs at /tmp/cache, where Frigate assembles segments before they are moved to the drive, and shm_size, which Frigate sizes for you and prints at startup as min_shm (234 MB on our box, computed from the camera_frame_size: 9.2 and shm_frame_count: 22 it reports; we give it 256). Both are on the setup page.

What to change first when the drive fills

Diagnose, then turn one knob
# 1. what Frigate thinks it has, per camera (usage MiB, bandwidth MiB/hour) - fast
curl -s http://127.0.0.1:5000/api/recordings/storage | python -c "import sys,json; [print(k, v) for k, v in json.load(sys.stdin).items()]"

# 2. what is actually on the drive, one day at a time. The compose binds /mnt/d/frigate/media
#    to /media/frigate, so the host path has no second "frigate" in it. Through 9p a whole day
#    of nine cameras is ~77,000 files and takes about a minute; du over the whole tree takes far longer.
du -sh /mnt/d/frigate/media/recordings/2026-09-01/*/cat_water_bowl | tail -n 3
ls /mnt/d/frigate/media/recordings/

# 3. the filesystem, which is NOT the recordings if anything else lives on the drive
curl -s http://127.0.0.1:5000/api/stats | python -c "import sys,json; print(json.load(sys.stdin)['service']['storage'])"

# 4. the first knob: continuous days. 3 -> 2 frees a third of the always-on tape overnight.
#    The second knob: per-camera continuous overrides on cameras you do not need history for.
#    The last knob: event days. Cut it only if you have already cut the other two.

And the lesson we learned on a different machine, which applies to any NVR: any automation that makes copies must also delete them. A backup script with no retention filled a server to 100 % and crashed it. Frigate prunes its own recordings; anything you add beside it — snapshot exports, clip backups, the Shorts pipeline's working folder — needs a keep-newest-N rule of its own before it is allowed to run unattended.