Skip to content

Warn when a model load causes new macOS swap growth #2501

Description

@jjang-ai

Problem

On smaller-memory Macs, users may already have browsers, Docker, chat apps, IDEs, and other memory-heavy applications open. Loading an Osaurus model can then push macOS into new swap activity and make model load, TTFT, and decode extremely slow with no clear explanation.

This is distinct from static low-RAM feasibility and from the existing generic host-pressure advisory. A Mac may have old swap allocated while currently healthy. The signal needed here is new swap growth during an Osaurus cold model-load / first-prefill window, relative to a sample taken immediately before that load.

Current gap

HostMemoryPressureProbe already records swapUsedBytes and swapins, but MemoryPressureAdvisory.evaluate deliberately triggers only from low free memory plus decompression rate. It does not compute a per-load swap delta. The existing RAM feasibility banner predicts whether a model fits; it does not tell the user that loading the selected model has just caused system swap usage to increase.

Required behavior

  1. Take a host-memory baseline immediately before a real cold model load begins. Do not start a new attribution window for an already-resident model.
  2. Sample during model loading and through first prefill / first output.
  3. Compute monotonic swapGrowthBytes = max(0, current.swapUsedBytes - baseline.swapUsedBytes) and retain model name, load phase, elapsed time, free/compressed memory, decompression rate, and swap-in rate.
  4. When new swap growth crosses a meaningful noise floor or rises rapidly, show a prominent one-time popup for that load. Use tiered warning/severe thresholds rather than total swap percentage; exact thresholds should be calibrated with fault-injected samples and at least one small-RAM Mac.
  5. Suggested copy:

Loading MODEL caused macOS swap usage to grow by X GB. This can make the model dramatically slower and increase SSD activity. Close memory-heavy apps, unload other models, or choose a smaller model.

  1. Popup actions:
    • Open Activity Monitor (Memory view) so the user can identify applications to quit.
    • Unload Model.
    • Keep Running.

The app must never automatically quit another application. It may assist the user in identifying memory-heavy apps, but the user decides what to close.

Attribution wording

The measurement is host-wide. Osaurus can prove that new swap growth occurred inside its model-load window, but macOS may choose pages belonging to other open applications for swap. Logs should say the load coincided with / triggered system swap growth, not claim that every swapped byte belongs to the Osaurus process.

Non-goals

  • Do not warn from historical swap usage or percentage alone.
  • Do not silently lower MLX.Memory.memoryLimit.
  • Do not enable JangPress or another model-family backend as a universal fix.
  • Do not block every load solely from this advisory.
  • Do not change sampler, prompt, reasoning, or model behavior.

Acceptance tests

  • High pre-existing swap with zero per-load growth: no popup.
  • Per-load swap growth above the warning threshold: popup names model and delta.
  • Rapid severe growth: severe wording and actions appear promptly.
  • Growth outside an active load/prefill attribution window: no model-attributed popup.
  • Already-resident model reuse: no new cold-load attribution window.
  • Unload/new model load resets the baseline and one-time suppression.
  • Probe failure or counter regression: no fabricated warning.
  • Popup does not refuse the load, alter MLX limits, or repeat continuously.
  • Fault-injected UI test proves all three actions.
  • Live small-RAM proof records baseline/current/delta, phys_footprint, memory pressure, TTFT, and token/s before this is called complete.

Relevant current code

  • Packages/OsaurusCore/Services/ModelRuntime/HostMemoryPressureProbe.swift
  • Packages/OsaurusCore/Models/Chat/MemoryPressureAdvisory.swift
  • Packages/OsaurusCore/Services/ModelRuntime.swift
  • Packages/OsaurusCore/Views/Chat/FloatingInputCard.swift
  • Packages/OsaurusCore/Tests/Chat/MemoryPressureAdvisoryTests.swift
  • Packages/OsaurusCore/Tests/Chat/MemoryPressureWiringTests.swift

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions