# Keep On-Device LLMs Alive on Real Phones: Lesson 01. Fit the model in the memory budget

Lesson id: `on-device-llm-survival/01-memory-budget-and-jetsam`
Human lesson: https://edgefde.dev/courses/on-device-llm-survival/01-memory-budget-and-jetsam.html

## Goal

Add a memory gate that decides, before each load, whether a model fits in the app's current memory budget.

## Prerequisites

- Xcode 27, iOS 27 device
- A model you can already load
- Its footprint measured on device after one long prompt

## Inputs

- Model name and measured footprint in bytes
- Optional smaller fallback model

## Outputs and artifacts

- `MemoryGate.swift` with `decide(for:)`
- Log lines with available and needed bytes
- Entitlements file with increased-memory-limit and extended-virtual-addressing if you test them

## Steps

1. Measure the model footprint on a real device with Xcode's memory gauge after a long prompt. Write it into a `ModelSpec`.
2. Create `MemoryGate` that reads `os_proc_available_memory()` and compares it with `measuredFootprintBytes` times a share (start at 0.6).
3. Call the gate right before every load. On `.tooBig`, try the smaller model, then the server path.
4. Log `available` and `needed` on every decision.
5. Add the Increased Memory Limit capability. If the runtime memory maps large files, also test Extended Virtual Addressing. Re-run the gate and compare numbers.
6. Collect jetsam event reports from test devices and adjust the share.

## Constraints

- Do not cache the value from `os_proc_available_memory()`.
- Do not use file size as the footprint.
- Do not claim the share is an Apple number.
- Swift only for iOS code.

## Acceptance checks

- A forced low-memory case (load a big buffer first) makes the gate pick the fallback.
- Every load has a log line with both byte counts.
- The app still works when the entitlement gives no extra memory.

## Key concepts

- A jetsam event ends your app to get memory back. It looks like a crash but has no backtrace.
- `os_proc_available_memory()` gives bytes left before your app's limit. Call it before each load and do not cache it.
- The increased-memory-limit entitlement raises the limit only on some devices. The extended-virtual-addressing entitlement gives more address space for large memory maps.
- Use the measured runtime footprint, not the file size.

## Takeaways

- Gate every model load on available memory and a measured footprint.
- The 60% share is a starting choice. Tune it from field jetsam reports.
- Always have a smaller model or a server path ready when the gate says no.
