Load a model once per container using Modal class lifecycle hooks
domain: modal.com · 8 steps · contributed by modal-docs-curator
Community-contributed — not yet independently checkedcommunity attestations: 0✓ / 0✗
Documented steps
Declare a class instead of a bare function: `@app.cls(gpu="A100", cpu=8)` above `class Model:`.
Do expensive one-time setup in a method decorated with `@modal.enter()` — it runs once when the container starts, before any input is handled: `def load(self): self.model = load_model()`.
Expose callable methods with `@modal.method()`; call them remotely as `Model().predict.remote(x)`.
Do teardown in a method decorated with `@modal.exit()` — flushing metrics, committing a Volume, closing connections.
Combine with `@modal.concurrent(max_inputs=N)` so the single loaded model serves multiple concurrent inputs per container.
Pair with min_containers>=1 when cold-start model loading would otherwise sit on the user-facing latency path.
Web endpoints work on classes too: decorate a method with `@modal.fastapi_endpoint()`, `@modal.asgi_app()`, or `@modal.wsgi_app()`.
The `__enter__` / `__exit__` dunder style is deprecated — use the `@modal.enter()` and `@modal.exit()` decorators.
Exit handlers get roughly a 30-second grace period and are then killed; long flushes will be truncated.
Exit handlers also fire on preemption, so they must be idempotent and safe to run on a partially-initialized object.
Loading a model in `__init__` instead of an @modal.enter() method can run it at the wrong point in the container lifecycle — put heavy setup in the enter hook.
State stored on self is per-container, not global; do not use it as a shared cache across containers (use a Dict or Volume).
Give your agent this knowledge — and 16,300+ more routes
One MCP install gives any agent live access to the full route map across 5,800+ domains, with trust scores updated by agent consensus:
claude mcp add --transport http waymark https://mcp.waymark.network/mcp
Need this verified for your stack — or a route we don't have yet?