Serving & Availability
By default, a fine-tuned model sleeps when nobody uses it and wakes automatically on the first request (the wake-up takes roughly 8–12 minutes and is not billed). That suits occasional use perfectly — you pay nothing while the model is idle and only per token when it answers.
If your team relies on a model during business hours, waiting for a wake-up every morning isn't ideal. This page explains how to keep a model warm on your own terms — and what it costs.
The three modes
| Mode | What happens | Best for |
|---|---|---|
| On-demand (default) | Wakes on first request (~8–12 min, free), sleeps after ~15 min idle | Occasional / unpredictable use |
| Scheduled | Kept warm inside recurring windows you define (e.g. weekdays 07:00–17:00, your timezone); on-demand behaviour outside the window | Business-hours workflows |
| Always | Kept warm continuously; cancel any time by switching back to on-demand | Critical, round-the-clock workloads |
All configuration is done through the Fine-Tuning API and is attached to the model's Training Log — so it travels with the model and is fully scriptable. Changes take effect within ~2 minutes.
How long a wake-up takes
A cold wake-up provisions a dedicated inference instance for your model's base, pulls the serving container, downloads the base model from an in-region mirror, loads it, and passes health checks. Measured end-to-end on a small-tier lane:
| Phase | Typical time |
|---|---|
| Instance provisioning + container start | ~3–5 min |
| Base-model download + engine load | ~3–5 min |
Health checks to ready | ~1–2 min |
| Total, request → answering | ~8–12 min (~9 min measured) |
Two extras worth knowing:
- The first request after the lane is ready loads your LoRA adapter — a one-off ~30 seconds. Every request after that answers in ~1–2 s.
- Larger bases (70B-class) take longer to load — expect roughly 10–20 minutes to ready.
The wake-up itself is never billed. When you hold the lane yourself
(power on), the clock starts when you make the call — the wake-up minutes
are inside your first hour.
Reading the current configuration
curl "https://api.toothfairyai.com/finetuning/serving/{trainingLogId}" \
-H "x-api-key: YOUR_API_KEY"
{
"modelId": "ToothFairyAI/gemma-3-1b-abcd1234",
"mode": "scheduled",
"schedule": {"days": ["mon","tue","wed","thu","fri"], "start": "07:00", "end": "17:00", "timezone": "Australia/Sydney"},
"lane": {"status": "ready", "port": 8100, "pinned_until": 1760000000},
"warm_seconds_accrued": 7200
}
The lane object is the live state: stopped (asleep), starting/creating
(waking up), or ready (warm and answering instantly).
Option A: a recurring schedule (no cron needed)
Set once and forget — the platform turns the model on at the start of each window and lets it sleep after the end:
curl -X POST "https://api.toothfairyai.com/finetuning/serving/{trainingLogId}" \
-H "x-api-key: YOUR_API_KEY" -H "Content-Type: application/json" \
-d '{
"mode": "scheduled",
"schedule": {
"days": ["mon", "tue", "wed", "thu", "fri"],
"start": "07:00",
"end": "17:00",
"timezone": "Australia/Sydney"
}
}'
Rules: days is any list of mon…sun or ["everyday"]; start/end are
HH:MM in your chosen timezone; end must be later than start (overnight
windows are not supported). "mode": "always" keeps the model warm around the
clock; "mode": "on-demand" switches back to the default behaviour and
clears any stored schedule.
Option A+: a cron rule (maximum flexibility)
If a day/time window isn't expressive enough, put a cron rule on the
schedule instead. When cron is set it takes precedence over the
days/start/end window — you can even omit the window entirely:
curl -X POST "https://api.toothfairyai.com/finetuning/serving/{trainingLogId}" \
-H "x-api-key: YOUR_API_KEY" -H "Content-Type: application/json" \
-d '{
"mode": "scheduled",
"schedule": {
"cron": "0 7 * * 1-5",
"holdHours": 2,
"timezone": "Australia/Sydney"
}
}'
Semantics: every time the rule fires, the model's lane is woken and held
warm for holdHours (default 1, maximum 24, billed in 1-hour units). After
the hold elapses the model goes back to on-demand behaviour. The example above
wakes the model at 07:00 on weekdays and keeps it warm for 2 hours.
The rule is a standard 5-field cron expression — minute hour day-of-month month day-of-week — and accepts mon…sun names, ranges (1-5), lists
(0,30), steps (*/15) and the @hourly, @daily, @weekly, @monthly
and @yearly shortcuts. Times are evaluated in the schedule's timezone.
Invalid expressions are rejected with a 400 and a clear error message.
A day/time window keeps the model warm for the whole window, which is
usually what business-hours use wants. Reach for cron when you need something
a window can't express — e.g. */30 9-17 * * 1-5 (every 30 minutes during
office hours) or 0 6 * * 1 (Monday 6 am batch run, warm for the hold only).
To remove a cron schedule, switch back to "mode": "on-demand" (or set a
plain window again) — the cron rule is cleared with it.
Option B: on/off from your own scheduler
Prefer to drive it yourself? Turn the model on and off exactly when you want:
# 07:00 — your cron: warm it up for the next 10 hours
curl -X POST "https://api.toothfairyai.com/finetuning/serving/{trainingLogId}/power" \
-H "x-api-key: YOUR_API_KEY" -H "Content-Type: application/json" \
-d '{"state": "on", "hours": 10}'
# 17:00 — your cron: release it for the evening
curl -X POST "https://api.toothfairyai.com/finetuning/serving/{trainingLogId}/power" \
-H "x-api-key: YOUR_API_KEY" -H "Content-Type: application/json" \
-d '{"state": "off"}'
state: "on" triggers the wake-up and holds the model warm for hours
(minimum 1). The call returns immediately — poll GET /serving/{trainingLogId}
until lane.status is "ready". Holds extend each other, never shorten:
booking 3 hours and then 1 more keeps it warm for 4 hours total. state: "off" releases the hold right away; the model then sleeps after the normal
short idle grace.
What warm time costs
Warm hours are billed in 1-hour units (minimum 1 unit, rounded up) at your model's size-tier hourly rate, on top of normal per-token usage: Small 220 · Medium 360 · Large 520 · Extra large / Largest 2,440 UoI per hour (1 UoI = $0.01 USD).
A few mechanics worth knowing:
- Billing runs once per day at 03:00 UTC and charges the accrued time to your UoI credit balance — a 10-minute hold bills as one full hour.
- Releasing the hold (
state: "off"or the end of a window) stops the meter immediately, but already-accrued partial time still rounds up at the daily run. - Accrued, not-yet-billed time is visible any time as
warm_seconds_accruedon the serving status call (also shown in the platform's fine-tuned model panel).
Full rate tables, worked examples and the per-token prices live in
Your Fine-Tuned Models — Consumption & Pricing.
The programmatic rate table is available at GET /finetuning/pricing (per
tier, per base model, or resolved for one of your training logs; values are
returned in USD — multiply by 100 for UoI).
Deleting a training log
If the Training Log is deleted, its schedule is automatically disabled and
the model's lane switches off within ~2 minutes — it will not keep waking up
and billing warm hours for a deleted model. Warm time that already ran is
still billed (it was real compute). The serving endpoints return
404 Training log not found for deleted logs, so no new schedules or holds
can be placed on them.