Measure
Bounded collectors scan fast telemetry every minute and reconcile authoritative billing daily.
Cloudflare cost control, self-hosted
Brolly catches runaway Workers, Durable Objects, storage, and AI usage before it becomes an invoice—then gives your team audited, reversible controls to contain it.
One account per installation. Your policies, credentials, incidents, and audit history stay in your Cloudflare account.
Every billable Cloudflare service. One safety net.
How it works
Brolly separates measurement from enforcement, so missing telemetry can never masquerade as a healthy account.
Bounded collectors scan fast telemetry every minute and reconcile authoritative billing daily.
Every incident names the asset, observed window, configured limit, evidence source, and freshness.
Prepare, approve, and roll back controls. Automatic mode acts only on classified, fuse-ready resources.
Resume restores saved state. Quarantine preserves resources, storage, messages, and history.
Install
The Deploy button creates your own Git repository, provisions Brolly's D1 database, builds the guard Worker, and opens your private dashboard. The universal site you are reading is not copied into your account.
Choose a Git account, give the Worker a name, and let Cloudflare provision its private D1 database.
BROLLY_CREDENTIAL_KEY protects OAuth and notification credentials stored in your D1 database.
Authorize exactly one account, review the requested scopes, and define limits for discovered products, Workers, and namespaces.
Billing reconciliation is optional. Fast telemetry works with OAuth. A separate Billing Read token enables authoritative invoice comparison because Cloudflare does not expose that permission through its OAuth scope catalog.
Limits and modes
Define warning, critical, and emergency limits at the account, product, Worker, Durable Object namespace, and exact-object levels. More specific policies override broad defaults.
Precise shutdown
Monitoring works without application changes. Exact Worker and Durable Object quarantine uses the tiny @standardagents/brolly-runtime package. Its hot path only parses a deployment binding and compares IDs—no HTTP, KV, D1, or Durable Object storage operation.
pnpm add @standardagents/brolly-runtimeconstructor(ctx: DurableObjectState, env: Env) {
super(ctx, env)
brollyDurableObject(ctx, env)
}brollyWorker(env)
const id = env.ROOMS.idFromName(name)
brollyWorker(env, { durableObjectId: id.toString() })
return env.ROOMS.get(id).fetch(request)Object SQLite rows, messages, queues, and history remain intact.
Only the named target ejects; unrelated object IDs continue serving.
Resume removes the fuse target through a new audited deployment.
Notifications
Configure Discord, Slack, or Twilio SMS with independent minimum severity, pause controls, deduplication, and delivery-rate limits.
Safety model
Every pass has hard limits: 150 Cloudflare API calls, 25,000 Brolly D1 row operations, 20,000 samples, and 45 seconds. Brolly never wakes every object or reads customer-object SQLite to monitor it.
Put up the umbrella
Deploy one self-hosted Brolly per Cloudflare account.
Deploy to Cloudflare