Budget
A Budget is a per-app monthly spend cap, alert threshold, at-cap action, and persisted cap-trip recovery state. The Budget primitive ships with 3.24.6 and is rack-managed; it lives outside the per-app convox.yml to avoid coupling the cap value to deploy lifecycles. Cap values, threshold percent, at-cap action, and pricing adjustment are set via convox budget set (or the Console budget tab); the auto-shutdown runtime fields below are read fresh from the manifest at simulate/tick time and take effect on the next deploy.
Fields
The Budget primitive's schema is declared in convox.yml under the budget
block (camelCase keys to match the established Convox manifest convention).
The wire/annotation JSON form uses kebab-case (e.g. monthly-cap-usd); the
CLI param form on convox budget set and convox budget cap raise matches
the wire form. See convox.yml budget block
for the full schema reference.
Persistence semantics: enforcement-bearing fields (monthlyCapUsd,
alertThresholdPercent, atCapAction, pricingAdjustment) are set via
convox budget set or the Console — convox releases promote validates the
manifest's budget: block but does not auto-write these fields, so a deploy
cannot silently overwrite an operator-set cap. Auto-shutdown runtime fields
(atCapWebhookUrl, notifyBeforeMinutes, shutdownGracePeriod, recoveryMode,
shutdownOrder, neverAutoShutdown) are read fresh from the manifest each
accumulator tick and take effect on the next deploy without requiring a
separate convox budget set call.
| Field | Type | Description |
|---|---|---|
monthlyCapUsd |
float |
Monthly hard cap in USD. The accumulator compares the running month-to-date spend against this value on every tick and trips the cap-state when spend exceeds it. |
alertThresholdPercent |
float |
Threshold percentage of monthlyCapUsd at which the :threshold event is emitted (range 1-100 inclusive). Set to 100 to fire only at exact cap; set lower for early-warning alerts. Defaults to 80. |
atCapAction |
string |
One of alert-only, block-new-deploys, or auto-shutdown. Controls what happens when spend crosses the cap. See Budget Caps for the recovery flow per action. |
atCapWebhookUrl |
string |
Optional URL the rack POSTs to when the cap fires. Configured at the manifest's top-level budget: block (the field is per-app, not per-service). Empty means no cap-fire webhook for this app. |
pricingAdjustment |
float |
Multiplier applied to the rack's pricing table for the app's spend rollup. Used when the app runs on instance types not in the canonical pricing table; the multiplier scales the canonical rate. Defaults to 1.0. |
notifyBeforeMinutes |
int |
(auto-shutdown only) Notification window in minutes between :armed event firing and :fired shutdown enforcement. Defaults to 30. |
shutdownGracePeriod |
string |
(auto-shutdown only) Pod terminationGracePeriodSeconds applied to the scale-to-0 patch (e.g. 30s). Defaults to 5m if unset; bounds the SIGTERM-to-SIGKILL window for service pods during budget-fire shutdown. |
recoveryMode |
string |
(auto-shutdown only) auto-on-reset (default) restores replicas immediately on convox budget reset; manual requires the operator to scale services back up explicitly. |
shutdownOrder |
string |
(auto-shutdown only) largest-cost (default) shuts down highest-cost-per-hour services first; newest shuts down most-recently-deployed services first. |
neverAutoShutdown |
[]string |
(auto-shutdown only) Service names that must remain running through a cap-fire (e.g. ["api"]). Listed services are excluded from the shutdown plan and continue to consume budget after :fired. |
State
The Budget primitive maintains two pieces of persisted state, both stored as namespace annotations on the app's Kubernetes namespace:
convox.com/budget-config— the user-configured fields above (serialized in kebab-case asmonthly-cap-usd,alert-threshold-percent,at-cap-action,pricing-adjustment,notify-before-minutes) plus alast-cap-mutation-byaudit field.convox.com/budget-state— the runtime state machine:current-month-spend-usd,current-month-spend-as-of,circuit-breaker-tripped,circuit-breaker-ack-by,alert-fired-at-threshold,alert-fired-at-cap,warning-count.
When atCapAction: auto-shutdown is set and the cap trips, a third annotation appears:
convox.com/budget-shutdown-state— the auto-shutdown lifecycle state machine (ARMED → ACTIVE → RECOVERED / FAILED / EXPIRED) plus the per-service replica snapshot used for restore.
A fourth annotation, convox.com/budget-recovery-banner-dismissed, is written transiently when a Console user dismisses the post-recovery RECOVERED banner. The rack stale-annotation GC clears it alongside the shutdown-state annotation when the cycle's terminal state ages out (one tick interval, default 10 minutes).
CLI Commands
Setting a budget
$ convox budget set --monthly-cap 500 --at-cap-action auto-shutdown --alert-at 80 myapp
Setting budget for myapp... OK
Showing the current budget
$ convox budget show myapp
App myapp
MonthlyCapUSD $500.00
AlertThresholdPercent 80
AtCapAction auto-shutdown
NotifyBeforeMinutes 30
PricingAdjustment 1.00
CurrentMonthSpend $312.40
SpendAsOf 2026-04-27 13:42:18 UTC
CircuitBreakerTripped false
Raising the cap
The cap can be raised in-place without rewriting other fields:
$ convox budget cap raise --monthly-cap-usd 1000 myapp
Raising cap for myapp from $500.00 to $1000.00... OK
Resetting after a cap-trip
When the breaker has tripped (spend over monthlyCapUsd), reset re-enables the configured at-cap-action:
$ convox budget reset myapp
Resetting budget cap for myapp... OK
Dismissing the RECOVERED banner
After an auto-shutdown recovery completes (:restored event fires), a sticky RECOVERED banner appears in the Console. Dismiss it via:
$ convox budget dismiss-recovery myapp
Dismissing recovery banner for myapp... OK
Simulating an auto-shutdown
Dry-run the auto-shutdown logic against the current cluster state without modifying replicas:
$ convox budget simulate-shutdown myapp
SIMULATION (dry-run): myapp would scale-to-0 the following services:
- web (3 replicas → 0)
- worker (2 replicas → 0)
Estimated cost saved per hour: $1.84
Lifecycle Events
The Budget primitive emits 13 distinct webhook event types over its lifecycle. See Budget Caps for the full event reference, payload shape, and receiver migration notes.
See Also
- Budget Caps for the operator-facing setup, recovery, and troubleshooting flow
- Cost Tracking for the per-service spend rollup that feeds the Budget primitive's
current-month-spend-usd convox budgetfor the full CLI command surface