Last updated:
A self-hosted Lunora app runs on your own Cloudflare account, and Workers and Durable Objects bill by usage. A retry loop, a Durable Object that never goes idle, or a crawler hammering an endpoint can run for weeks before the invoice shows it. This page sets up the alerts that tell you within a day instead.
You need a Cloudflare API token with two permissions:
- Notifications Write: creates the usage alerts.
- Account Analytics Read: reads last month's usage so the thresholds sit above your normal traffic, not below it.
export CLOUDFLARE_API_TOKEN=… # the token above
export CLOUDFLARE_ACCOUNT_ID=… # or set account_id in wrangler.jsonc1. See where you stand
lunora cloudflare alertsThis prints last month's usage for Workers requests and CPU time, Durable
Objects requests, duration, and rows read and written, and D1 rows read and
written. Next to each one it says whether a usage alert already covers it. If a
figure reads unavailable, the reason follows it. Usually the token lacks
Account Analytics Read, or the analytics schema has no field for that metric.
2. Create the usage alerts
Preview first:
lunora cloudflare alerts setup --email you@example.com --dry-runsetup creates two alerts on its own: Workers requests and Durable
Objects requests. Each fires at 3× last month by default (--multiplier
changes that), rounded up to two significant figures. A threshold is never set
below the monthly allowance included with Workers Paid: 10 million Workers
requests, 1 million Durable Object requests. A quiet month therefore never
gives you an alert that fires on ordinary growth.
If last month's usage cannot be read, for example because the token lacks
Account Analytics Read, setup writes no alert for that metric and exits
non-zero. Falling back to the floor there would be wrong for a busy account,
which would trip a 10-million-request alert every month. Pass
--threshold workers-requests=<n> to choose the limit, or --allow-floor to
accept the floor anyway.
The other metered products take a limit only from you:
lunora cloudflare alerts setup --email you@example.com --threshold do-duration=500000 --dry-runDurable Objects duration and storage reads/writes are billed in units that
cannot be matched to the usage status shows, so setup will not guess one.
Cloudflare has no usage alert at all for D1 or for Workers CPU time; the
budget alert in the next step is what guards them.
Cloudflare does not document the unit of a usage alert's limit either. After
writing, setup reads every alert back and prints the limit Cloudflare stored.
Compare it with the dashboard the first time.
When the plan looks right:
lunora cloudflare alerts setup --email you@example.com --yesPass --email more than once for several recipients, or
--webhook <destination-id> to deliver to a webhook destination you created in
the dashboard. The alerts are named Lunora usage: …. Re-running setup, for
example after a month of growth, updates those alerts in place rather than
duplicating them. It adds new recipients to the ones already there; pass
--replace-recipients to replace them, and the plan shows exactly who is added
or removed. A product you already alert on yourself is left alone, unless your
alert is disabled.
The product identifiers are the ones Cloudflare lists for its Terraform provider
(v4.52.0); when your account offers its own
list, setup uses that instead. Usage alerts are only offered to Pay-as-you-go accounts. On an ineligible account setup says so and writes nothing.
3. Add the budget alert by hand
Usage alerts watch one product each. A budget alert watches the whole
account's spend in dollars, and Cloudflare offers it only in the dashboard. It
has no API, so lunora cloudflare alerts can neither create one nor tell you whether you
have one:
- In the Cloudflare dashboard, go to Manage Account > Billing > Billable Usage.
- Select Create budget alert.
- Set a USD threshold comfortably above a normal month, and add the recipients.
Usage is processed daily, so a budget alert fires the day after its threshold is crossed.
4. Check delivery
lunora cloudflare alerts testCloudflare's API cannot send a test notification, either to email or to a webhook, so this command does not pretend to. Instead it shows what the API does know:
- when each webhook destination last received a notification and when one last failed;
- the notifications Cloudflare actually sent for the
Lunora usage: …alerts.
To test a webhook for real, create it in the dashboard (Alerts > Destinations, then Create on the Webhooks card) and finish with Save and Test. Email has no test send, so make sure the addresses on the alerts are right and that mail from Cloudflare is not filtered as spam.
In CI
Every subcommand takes --format json and exits with a documented
code. For example, lunora cloudflare alerts --format json in a
scheduled job can flag a product whose usage has grown past the alert you set
months ago.