Cost & estimates
Call estimate() to see what a render will cost before you start it. Set
maxCost, and a render that could cost more is refused before anything is
charged.
Get the price before you render
const cost = await bakery3.estimate({ quality: 'studio', width: 2048, height: 2048 });
cost.estimatedCost; // 0.12, expected charge
cost.maximumCost; // 0.16, the most you can be charged
cost.estimatedSeconds; // 7
cost.compatibilityScore; // 0.97maximumCost is 35% above the estimate, because a noisy scene can take longer
than expected. You are never charged more than the maximum. The more your
project renders, the closer its estimates come to what it is charged.
Set a budget with maxCost
await bakery3.render({ maxCost: 0.14 });maxCost is compared with maximumCost, not with estimatedCost. If the
maximum is higher, the render is refused and nothing is charged:
RenderBudgetExceeded: This render could cost up to $0.16, which exceeds maxCost $0.14 (estimated $0.12)
Why: maxCost is held against the maximum a render can be charged,
not its estimate, so that it is a ceiling. The render was
refused before any GPU work started, and nothing was charged.
Fix: Raise maxCost, lower the quality preset, or reduce the output
resolution.Catch it to offer your user something cheaper:
import { RenderBudgetExceeded } from '@oeave/bakery3';
try {
await bakery3.render({ maxCost: budgetRemaining });
} catch (error) {
if (error instanceof RenderBudgetExceeded) {
// number | undefined: a refusal from a browser token's own cap names no price
return offerCheaperPreset(error.maximumCost);
}
throw error;
}The refusal can come from your maxCost, which the SDK checks before it
uploads anything, or from the API, for example when a browser token has less
left than the render could cost. Both are instanceof RenderBudgetExceeded.
maximumCost, estimatedCost and maxCost on it are set when they are known.
Set a default once and every render uses it:
createBakery3({ token, defaults: { quality: 'studio', maxCost: 0.5 } });defaults.output sets a size for every render, and estimate() quotes at that
size too, so the price you show is the price of the render that follows.
See what you were charged
const result = await job.result();
result.cost; // 0.13, what was charged, not the estimateYou are charged for the render that actually ran, and never more than the
maximumCost it was accepted under.
What drives the price
The price follows the output pixels, the quality preset and how big the scene
is. A scene inside a room costs more than one on an open set, and a room you
modeled yourself is priced the same way as a preset room. Doubling the long
edge gives four times the pixels and roughly four times the price. Dropping
from ultra to studio is the biggest single saving.
| preview | studio | ultra | |
|---|---|---|---|
| Max samples | 32 | 256 | 2048 |
| Adaptive threshold | 0.08 | 0.02 | 0.005 |
| Max bounces | 4 | 8 | 16 |
| Diffuse / glossy / transmission | 2 / 4 / 4 | 3 / 8 / 8 | 6 / 16 / 16 |
| Default size, long edge | 1024 px | 2048 px | 4096 px |
| Quick preview first | no | yes, 24 samples | yes, 32 samples |
| Denoised | no | yes | yes |
A preview costs at least $0.04, a studio render at least $0.08 and an ultra render at least $0.20.
Every render also has a small fixed start-up cost, so a tiny preview and a small
studio image are closer in price than their pixel counts suggest.
The same render twice is free
A render that comes from the cache costs nothing, as long as the first one is still stored. Results are kept for 30 days by default. See Assets & caching.
When your balance is too low
Rendering is prepaid. A render is only accepted if your credit covers its
maximumCost, so your balance cannot go below zero.
InsufficientBalance: This render could cost up to $0.16 and you have $0.10 available. Top up at https://bakery3.com/billing.You can also set a hard monthly limit on the account and on each project. See Limits.
Estimate a video
Pass the frame count:
const cost = await bakery3.estimate({
quality: 'studio',
width: 1920,
height: 1080,
frames: 96,
});A video pays the start-up cost once, and each frame costs about a fifth of an
image the same size. maxCost on renderVideo() is checked against the video's maximum.
See Render video.
Estimating a bake
Pass the same settings you would give bake(). The quote covers exactly the
objects the bake would include.
const cost = await bakery3.estimate({
bake: { quality: 'standard', textureSize: 1024, exclude: ['glass-vitrine'] },
});A bake is priced at twice the rate of an image per GPU second, and
maxCost works the same way. This is what moves the price:
| What | How it changes the price |
|---|---|
| Texels | Every included object at its texture size, squared. Half the texture size is a quarter of the texels. |
| Quality | preview traces a quarter of the samples of standard, and high four times as many. |
| Number of objects | Each lightmap has a fixed cost, so many small maps cost more than a few large ones with the same texels. |
| Scene weight | What a sample costs is set by the scene the light bounces around in, so a heavy room costs more per texel than a bare one. This is usually the largest number in the quote. |
| Geometry you bake | The unwrap is priced per triangle of the objects you include, not of the whole scene. |
deliverGlb | The portable .glb is a second pass per object and roughly doubles the price. |
atlas | Costs the same as separate maps with the same texels. Its texels are size squared. |
The quote prices every object at its full texture size. We may choose a smaller lightmap for a small object, so the charge can come in under the quote. Baking the same scene again from the same camera with the same settings comes from the cache and is free, while the first bake is still stored.
Estimates are fitted against real bakes and are within about a third either way.
Whatever happens, you pay the metered price or maximumCost, whichever is
lower.
See Pricing for example bake prices, and Bake a scene for the settings.
In the dev panel
The dev panel shows the estimate next to the render button and updates it when the scene changes. See Devtools.
