> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ns.rocks/llms.txt
> Use this file to discover all available pages before exploring further.

# Template Warm Pools

> Build a ready custom template, keep pool capacity warm, and create machines with explicit checkout modes.

This example builds a custom FastAPI template, creates a template warm pool,
waits for ready capacity, launches machines with `prefer` and `require`, then
drains the pool.

<Warning>
  Template builds and template warm pools require microVM-runtime/private-beta
  deployment support.
</Warning>

## Python SDK

Runnable source:
[`examples/python/demo_template_warm_pools.py`](https://github.com/catamaran-research/nullspace/blob/main/examples/python/demo_template_warm_pools.py)

```python theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
from nullspace import Machine, Template, TemplateWarmPool, wait_for_port

builder = (
    Template.from_python_image("3.12")
    .pip_install(["fastapi", "uvicorn"])
    .copy("./app.py", "/workspace/app.py")
    .set_workdir("/workspace")
    .set_start_cmd(
        "uvicorn app:app --host 0.0.0.0 --port 8080",
        readiness=wait_for_port(8080),
    )
)

build = Template.build(builder, name="review-api", tags=["stable"])

pool = TemplateWarmPool.create(
    build.canonical_ref,
    name="review-api-small",
    min_ready=2,
    max_ready=4,
    vcpus=2,
    memory_mb=1024,
)
pool.wait_until_ready(min_ready=2)

preferred = Machine.create(
    template=build.canonical_ref,
    warm_pool=pool.id,
    warm_pool_mode="prefer",
    warm_pool_wait_ms=1500,
)
strict = Machine.create(
    template=build.canonical_ref,
    warm_pool=pool.id,
    warm_pool_mode="require",
    warm_pool_wait_ms=3000,
)

print(preferred.get_info().warm_pool_checkout)
print(strict.get_info().warm_pool_checkout)

pool.drain()
pool.delete()
```

Use `warm_pool_mode="prefer"` when cold fallback is acceptable. Use
`warm_pool_mode="require"` when the request should fail with
`warm_pool_unavailable` instead of cold creating.

## CLI

Use `--json` for agent-friendly output:

```bash theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
nullspace template warm-pool create team/review-api:stable \
  --name review-api-small \
  --min-ready 2 \
  --max-ready 4 \
  --vcpus 2 \
  --memory 1024 \
  --json

nullspace template warm-pool wait twp_review_api_small --min-ready 2 --json

nullspace machine create \
  --template team/review-api:stable \
  --warm-pool twp_review_api_small \
  --warm-pool-mode prefer \
  --warm-pool-wait 1500 \
  --json

nullspace machine create \
  --template team/review-api:stable \
  --warm-pool twp_review_api_small \
  --warm-pool-mode require \
  --warm-pool-wait 3000 \
  --json
```

## Track A Tag

Use `track_tag` when the pool should follow a moving template tag:

```bash theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
nullspace template warm-pool create team/review-api:stable \
  --name review-api-stable \
  --min-ready 2 \
  --max-ready 4 \
  --version-policy track_tag \
  --track-tag stable \
  --json
```

When `stable` moves, the pool records a rollout generation, drains old ready or
warming inventory, and fills the new build. Already claimed old-build
machines continue as normal machines.

## Cleanup

```bash theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
nullspace template warm-pool drain twp_review_api_small --json
nullspace template warm-pool delete twp_review_api_small --json
```

## Related

* [Template Warm Pools](../templates/warm-pools)
* [Template build example](./template-build)
* [Create machine](../cli/create-machine)
