# Keep On-Device LLMs Alive on Real Phones: Lesson 02. Load one model at a time

Lesson id: `on-device-llm-survival/02-one-model-load-at-a-time`
Human lesson: https://edgefde.dev/courses/on-device-llm-survival/02-one-model-load-at-a-time.html

## Goal

Put all model loads behind one serialized owner that frees memory first and unloads on memory pressure.

## Prerequisites

- Lesson 01 memory gate
- A loader closure for your runtime

## Inputs

- Model specs
- Runtime load and close functions

## Outputs and artifacts

- `ModelOwner` actor (Swift)
- `ModelOwner` with Mutex and `ComponentCallbacks2` (Kotlin)
- Written fallback ladder

## Steps

1. Create the Swift `ModelOwner` actor with one `current` model and one `inFlight` task.
2. Inside `model(_:load:)`, wait for any in-flight load, free the old model, run the memory gate, then load.
3. Add `MemoryPressureWatcher` that calls `unloadAll` on `didReceiveMemoryWarningNotification`.
4. On Android, create `ModelOwner` with a `Mutex`, close the old model before loading, and register it with `registerComponentCallbacks`.
5. Unload on `onTrimMemory` at `TRIM_MEMORY_BACKGROUND` or higher.
6. Replace every direct model load in the app with a call to the owner.
7. Write the fallback ladder in code comments and in the feature spec.

## Constraints

- No direct model loads outside the owner.
- Swift for iOS and Kotlin for Android.

## Acceptance checks

- Two features that request models at the same time produce one load at a time in the logs.
- Simulate a memory warning (Debug > Simulate Memory Warning in the Simulator) and see the unload log.
- The app keeps running after the warning.

## Key concepts

- Model load is the peak memory moment. Two loads at once can nearly double it.
- One owner (Swift actor or Kotlin Mutex) loads, keeps, and unloads all models.
- Free the old model before loading the new one.
- Unload on `didReceiveMemoryWarningNotification` on iOS and on high `onTrimMemory` levels on Android.

## Takeaways

- No feature loads a model directly. They all ask the owner.
- A memory warning should drop the model, not the app.
- Write a fallback ladder so a refused load still gives the user an answer or a clear message.
