Fig. 1 Usage billing Replay
Usage billing
Usage drops fall into a graduated basin and raise its level a step at a time as the month's days pass; at the month's end the basin drains through a narrow outlet into a meter that prints the invoice slip line by line, and the total shows once it is out.
16.5 || r < 0.5) v = 0.6; // its edges
else if (r < 1.5) v = j > 1.5 && j < 9.5 ? 1.15 : (j > 11.5 && j < 15.5 ? 0.6 : P); // header, date
else if (abs(r - 4.0) < 0.5 || abs(r - 16.0) < 0.5) v = mod(j, 2.0) < 0.5 ? 0.6 : P; // rules
else if (r > 5.5 && r < 14.5 && mod(r - 6.0, 3.0) < 0.5) { // four line items: what was used, and its amount
float len = floor(hash(vec2(r, 3.0)) * 4.0);
v = j > 1.5 && j < 5.5 + len ? 0.95 : (j > 11.5 && j < 15.5 ? 1.05 : P);
}
else if (abs(r - 19.0) < 0.5) v = j > 1.5 && j < 6.5 ? 1.15 : (j > 9.5 && j < 15.5 ? 1.2 : P); // the total
else if (abs(r - 23.0) < 0.5) v = mod(j, 2.0) < 0.5 ? 0.6 : 0.0; // torn foot
return v;
}
float field(vec2 p, float t) {
if (p.x < 18.0 || p.x > 702.0 || p.y < 18.0 || p.y > 442.0) return 0.0;
float ph = TAU * t / T;
float k = floor(p.y / 9.4);
float c = floor((p.x - 4.0) / 7.0 + 0.5);
float v = 0.0;
// the level, in graduations: up one per landed drop, down as it drains
float lvl = ease((t - 0.47) / 0.15) + ease((t - 0.77) / 0.15) + ease((t - 1.07) / 0.15) + ease((t - 1.37) / 0.15) + ease((t - 1.67) / 0.15) + ease((t - 1.97) / 0.15);
float dr = ease((t - 2.3) / 1.1);
lvl -= 6.0 * dr;
float surf = 31.0 - 3.0 * lvl; // the surface row
float draining = step(2.3, t) * step(t, 3.4);
float open = sm(2.25, 2.32, t) * (1.0 - sm(3.5, 3.6, t));
// the feed rail: a churning manifold over a dense bar, six nozzles under it
if (p.x > 126.0 && p.x < 262.0) {
if (k == 3.0) v += 0.3 + 0.3 * noise(vec2(p.x * 0.09 + 2.0 * cos(ph), 2.0 * sin(ph)));
if (k == 4.0) v += 1.05;
if (k == 5.0 && mod(c - 19.0, 3.0) < 0.5) v += 0.6;
}
// the basin: slanted walls with a lip, a floor with the outlet in it
float L = xl(p.y), R = xr(p.y);
if (k >= 8.0 && k <= 30.0) {
if ((p.x >= L - 8.0 && p.x < L) || (p.x > R && p.x <= R + 8.0)) v += 1.05;
else if ((p.x >= L - 16.0 && p.x < L) || (p.x > R && p.x <= R + 16.0)) v += 0.7;
if (k == 8.0 && ((p.x >= L - 30.0 && p.x < L - 16.0) || (p.x > R + 16.0 && p.x <= R + 30.0))) v += 1.0;
}
if ((k == 31.0 || k == 32.0) && p.x >= L - 16.0 && p.x <= R + 16.0) {
if (c == 28.0) v += 1.05 * (1.0 - open) + 0.95 * open;
else v += k == 31.0 ? 1.0 : 0.7;
}
// graduations: ticks out from the left wall, long every other one, and a dotted level line inside at each
for (int i = 0; i <= 6; i++) {
float gk = 31.0 - 3.0 * float(i);
if (k == gk && i > 0) {
bool major = mod(float(i), 2.0) < 0.5;
if (p.x < L - 16.0 && p.x >= L - 16.0 - (major ? 21.0 : 10.0)) v += major ? 0.7 : 0.6;
if (p.x > L + 3.0 && p.x < R - 3.0 && mod(c, 2.0) < 0.5) v += 0.18;
}
if (k == gk && i == 0 && p.x < L - 16.0 && p.x >= L - 37.0) v += 0.7;
}
// the contents: a dense surface, denser with depth, streaming toward the outlet while it drains
if (k < 31.0 && p.x >= L && p.x <= R && k >= surf - 0.5) {
float depth = clamp((k - surf) / 18.0, 0.0, 1.0);
v += k < surf + 0.5 ? 1.05 : 0.42 + 0.3 * depth;
float d = length((p - vec2(200.0, 294.9)) / vec2(1.0, 1.6));
v += draining * 0.35 * step(0.62, fract(d / 26.0 + 5.0 * t)) * sm(2.3, 2.4, t);
}
{
// drop 1: forms at its nozzle, falls gathering speed, lands on the surface, ripples out
float u = (t - 0.15) / 0.32;
float g = (t - 0.03) / 0.12;
if (g > 0.0 && u < 0.0) v += blob(p, vec2(179.0, 58.0), 8.0, 1.1 * g);
if (u >= 0.0 && u < 1.0) v += blob(p, vec2(179.0, mix(58.0, 285.4, u * u)), 9.0, 1.15 * (1.0 - sm(0.9, 1.0, u)));
float w = (t - 0.47) / 0.4;
if (w > 0.0 && w < 1.0) {
float sk = 27.0;
if (k == sk && p.x > L && p.x < R) v += 0.7 * (1.0 - w) * exp(-pow(abs(p.x - 179.0) - 120.0 * w, 2.0) / 120.0);
if (k == sk - 1.0 && w < 0.4 && abs(abs(p.x - 179.0) - 9.0) < 4.0) v += 0.7;
}
}
{
// drop 2: forms at its nozzle, falls gathering speed, lands on the surface, ripples out
float u = (t - 0.45) / 0.32;
float g = (t - 0.33) / 0.12;
if (g > 0.0 && u < 0.0) v += blob(p, vec2(221.0, 58.0), 8.0, 1.1 * g);
if (u >= 0.0 && u < 1.0) v += blob(p, vec2(221.0, mix(58.0, 257.2, u * u)), 9.0, 1.15 * (1.0 - sm(0.9, 1.0, u)));
float w = (t - 0.77) / 0.4;
if (w > 0.0 && w < 1.0) {
float sk = 24.0;
if (k == sk && p.x > L && p.x < R) v += 0.7 * (1.0 - w) * exp(-pow(abs(p.x - 221.0) - 120.0 * w, 2.0) / 120.0);
if (k == sk - 1.0 && w < 0.4 && abs(abs(p.x - 221.0) - 9.0) < 4.0) v += 0.7;
}
}
{
// drop 3: forms at its nozzle, falls gathering speed, lands on the surface, ripples out
float u = (t - 0.75) / 0.32;
float g = (t - 0.63) / 0.12;
if (g > 0.0 && u < 0.0) v += blob(p, vec2(137.0, 58.0), 8.0, 1.1 * g);
if (u >= 0.0 && u < 1.0) v += blob(p, vec2(137.0, mix(58.0, 229.0, u * u)), 9.0, 1.15 * (1.0 - sm(0.9, 1.0, u)));
float w = (t - 1.07) / 0.4;
if (w > 0.0 && w < 1.0) {
float sk = 21.0;
if (k == sk && p.x > L && p.x < R) v += 0.7 * (1.0 - w) * exp(-pow(abs(p.x - 137.0) - 120.0 * w, 2.0) / 120.0);
if (k == sk - 1.0 && w < 0.4 && abs(abs(p.x - 137.0) - 9.0) < 4.0) v += 0.7;
}
}
{
// drop 4: forms at its nozzle, falls gathering speed, lands on the surface, ripples out
float u = (t - 1.05) / 0.32;
float g = (t - 0.93) / 0.12;
if (g > 0.0 && u < 0.0) v += blob(p, vec2(200.0, 58.0), 8.0, 1.1 * g);
if (u >= 0.0 && u < 1.0) v += blob(p, vec2(200.0, mix(58.0, 200.8, u * u)), 9.0, 1.15 * (1.0 - sm(0.9, 1.0, u)));
float w = (t - 1.37) / 0.4;
if (w > 0.0 && w < 1.0) {
float sk = 18.0;
if (k == sk && p.x > L && p.x < R) v += 0.7 * (1.0 - w) * exp(-pow(abs(p.x - 200.0) - 120.0 * w, 2.0) / 120.0);
if (k == sk - 1.0 && w < 0.4 && abs(abs(p.x - 200.0) - 9.0) < 4.0) v += 0.7;
}
}
{
// drop 5: forms at its nozzle, falls gathering speed, lands on the surface, ripples out
float u = (t - 1.35) / 0.32;
float g = (t - 1.23) / 0.12;
if (g > 0.0 && u < 0.0) v += blob(p, vec2(242.0, 58.0), 8.0, 1.1 * g);
if (u >= 0.0 && u < 1.0) v += blob(p, vec2(242.0, mix(58.0, 172.6, u * u)), 9.0, 1.15 * (1.0 - sm(0.9, 1.0, u)));
float w = (t - 1.67) / 0.4;
if (w > 0.0 && w < 1.0) {
float sk = 15.0;
if (k == sk && p.x > L && p.x < R) v += 0.7 * (1.0 - w) * exp(-pow(abs(p.x - 242.0) - 120.0 * w, 2.0) / 120.0);
if (k == sk - 1.0 && w < 0.4 && abs(abs(p.x - 242.0) - 9.0) < 4.0) v += 0.7;
}
}
{
// drop 6: forms at its nozzle, falls gathering speed, lands on the surface, ripples out
float u = (t - 1.65) / 0.32;
float g = (t - 1.53) / 0.12;
if (g > 0.0 && u < 0.0) v += blob(p, vec2(158.0, 58.0), 8.0, 1.1 * g);
if (u >= 0.0 && u < 1.0) v += blob(p, vec2(158.0, mix(58.0, 144.4, u * u)), 9.0, 1.15 * (1.0 - sm(0.9, 1.0, u)));
float w = (t - 1.97) / 0.4;
if (w > 0.0 && w < 1.0) {
float sk = 12.0;
if (k == sk && p.x > L && p.x < R) v += 0.7 * (1.0 - w) * exp(-pow(abs(p.x - 158.0) - 120.0 * w, 2.0) / 120.0);
if (k == sk - 1.0 && w < 0.4 && abs(abs(p.x - 158.0) - 9.0) < 4.0) v += 0.7;
}
}
// the outlet and the pipe: narrow walls, and the flow along them once the outlet is open
float wl = 0.42;
if (c == 27.0 && k > 32.0 && k <= 41.0) v += wl;
if (c == 29.0 && k > 32.0 && k <= 39.0) v += wl;
if (k == 39.0 && c > 29.0 && c < 62.0) v += wl;
if (k == 41.0 && c >= 27.0 && c < 62.0) v += wl;
float sd = -1.0; // how far along the flow's path this cell is
if (c == 28.0 && k > 32.0 && k <= 40.0) sd = (k - 32.0) * 9.4;
if (k == 40.0 && c > 28.0 && c < 62.0) sd = 75.2 + (c - 28.0) * 7.0;
if (sd >= 0.0) {
float at = sd / 1566.0;
float on = step(2.3 + at, t) * step(t, 3.4 + at);
v += on * (fract((sd - 900.0 * t) / 28.0) < 0.55 ? 1.05 : 0.55);
}
// the meter: a slot on top, a body with vents, its intake and a light that is on while it prints
float printing = step(2.5, t) * step(t, 3.6);
if (c >= 62.0 && c <= 88.0 && k >= 38.0 && k <= 42.0) {
if (k == 38.0) v += c >= 66.0 && c <= 85.0 ? 0.2 : 1.0;
else if (k == 39.0 || k == 42.0) v += 0.7;
else if (c >= 86.0 && c < 88.0) v += 0.42 + 0.68 * printing;
else if (c == 62.0) v += 0.42 + 0.63 * step(2.5, t) * step(t, 3.6);
else v += mod(c, 2.0) < 0.5 ? 0.7 : 0.3;
}
// the slip: last month's lifts off and fades at the month's end; the new one comes out of the slot a row at a time
if (c >= 67.0 && c <= 84.0 && k < 38.0) {
float top = 13.0, a = 1.0, rows = 25.0;
if (t >= 2.12 && t < 2.5) {
float u = clamp((t - 2.12) / 0.28, 0.0, 1.0);
top -= floor(2.0 * ease(u) + 0.5);
a = 1.0 - ease(u);
} else if (t >= 2.5) {
rows = floor(25.0 * ease((t - 2.5) / 1.1) + 0.001);
top = 38.0 - rows;
}
float r = k - top;
if (r >= 0.0 && r < rows) v += a * slip(r, c - 67.0);
}
// the month: 30 days, each lit as it passes; day 30 the month's end; cleared left to right for the new month
if (k == 45.0 && c >= 14.0 && c < 44.0) {
float d = c - 13.0;
float lit = step(0.15 + 0.065 * d, t) * (1.0 - step(3.62 + 0.006 * d, t));
v += 0.2 + lit * (d > 29.5 ? 0.9 : 0.55);
}
return v;
}]]>
Each run adds its usage to the month as it ends. On the last day the month settles into one invoice, line by line, with the total at the bottom.
A run uses two things: sandbox minutes , from the moment the sandbox is ready until it is wiped, and model tokens , for every step the agent takes. Both are counted when the run ends and added to the month.
Routing keeps the token part small. Most steps go to a small model, and only the hard ones reach the large one. See Model routing .
Hobby Team Enterprise Price $0 $40 per seat a month Custom Runs 100 a month Unlimited Unlimited Repos 1 Unlimited Unlimited Concurrent runs 1 20 Set by contract Sandbox timeout 1 hour 24 hours 24 hours Trace history 7 days 90 days 1 year
Set a monthly cap per workspace in Settings → Billing . When usage reaches it, new runs wait in the queue instead of starting, and you get an email at 80% and 100%. Runs already in progress always finish.
Tip Put a lower cap on one repo with rate limits . A busy repo then can't use up the whole team's month.