Serving model & pricing
How a model is served
Every family (SDXL, Z-Image) keeps one resident skeleton per GPU: the model graph built once, weights preallocated in GPU memory. Serving a specific checkpoint means copying its compiled weights into those slots — an in-place memory copy, not a model load. That's why switching between checkpoints of the same family takes ~300 ms, not minutes, and why renders are bitwise deterministic: same model, seed, and params produce the same bytes on every pod.
A model moves through tiers, visible in timing.tier_hit on every
response:
| tier | meaning | what you experience |
|---|---|---|
live |
weights are in the GPU slots now | 200 immediately, swap_ms: null |
warm |
compiled weights pinned in host RAM | 200, swap_ms ≈ 300 for SDXL |
cold |
on the pod's NVMe | short wake, then warm |
frozen |
in object storage only | 202 model_waking with eta_s |
The 202 contract: model_waking and queue_backlog mean nothing was
enqueued and nothing was charged — retry after Retry-After.
still_processing means the render IS running: poll
GET /v1/requests/{request_id}?wait=30 for the result. Billing happens
exactly once, at completion, on every path.
Pricing
Two parts, both deterministic before the render:
floor = floor_fixed + floor_per_step_mp × steps × megapixels
charged = floor × multiplier
- The floor is the compute price, set per family. SDXL example:
$0.0005 + $0.00008 × 25 steps × 1.0 MP = $0.0025for a 1024×1024, 25-step image. Fewer steps or smaller images cost proportionally less. Every registry card carries aprice_tablewith the exact price at common presets. - The multiplier (k ≥ 1) is set by the model's owner when they list
it. The spread —
floor × (k − 1)— is the owner's earnings on every third-party render. You pay the floor only when you generate on your own models, unlisted grants, or sponsored links.
The billing object on every response shows what you paid; GET
/v1/usage itemizes it. Composed endpoints extend the same formula —
see Composition.