Monitoring
Watch your instance's health, traffic, errors, resource usage, and audit trail from the System area.
#Monitoring
The System area (sidebar → System) is your window into what the instance is doing right now and what it has been doing lately.
#The dashboard
The System landing page gives you the at-a-glance picture:
- Traffic (24h) — requests, error rate, average and P99 latency
- Instance stats — collections, records, users, storage
- System version — the running version and whether a newer release exists (see Updates)
- Quick actions — jump-offs to common admin tasks
Prefer a custom layout? Turn on Use Lens Dashboard in Settings → System and the dashboard becomes an editable Lens page.
#The live monitor
System → Monitor is the deeper diagnostic view — what the instance is doing right now:
- Request volume and latency charts
- Collections — per-collection record counts, storage estimates, and read attribution
There's also a one-click Report Bug action that captures the current diagnostic context.
It reports the rate things are happening at. The individual entries — traces, audit rows, and every request including the refused ones — live one click away in System → Logs, so that opening the charts does not run three log queries you did not ask for.
#The logs
System → Logs is the three logs in one place. They answer different questions and are easy to mistake for each other:
| Tab | Answers | Covers reads? | Covers refusals? | Deletable? |
|---|---|---|---|---|
| Access | Who did what, when — every request that reached the gateway | Yes | Yes | No |
| Audit | What people changed, durably | No | No | Yes |
| Errors | Requests the gateway could not complete, with the trace | n/a | No | n/a |
A refusal is not an error: a 403 the permission model produced on purpose is
an access-log entry, not an error-console entry. See
Analytics and logs for the full comparison, retention,
and cost.
#The audit log
Sensitive operations — user and role changes, settings updates, schema changes, update triggers, and more — are recorded with the acting user, action, resource, and timestamp. The log is searchable and paginated, and reading it requires the system/audit-logs:read permission, so you can give an operations role visibility without granting any write access.
#Where the numbers come from
Two different Cloudflare systems feed these pages, and knowing which is which explains most surprises:
| Source | Powers | Retention |
|---|---|---|
| Cloudflare GraphQL Analytics API | Monitor charts, stat cards, resource gauges, Usage → Cost | ~30 days; longer ranges read EmuView's own daily R2 archives |
| Workers Analytics Engine | Usage → Performance: per-endpoint and per-collection attribution, drill-down, single-event receipts | 90 days |
Both need Cloudflare API credentials. If a panel is empty while another shows data, it is almost always one of these two being unconfigured rather than the instance being idle — the Monitor charts fall back to EmuView's own hourly counters when the GraphQL API returns nothing.
#Records, deleted records, and storage
Deleting a record soft-deletes it by default: the row stays in the table with a deleted_at timestamp so it can be restored. That has two consequences worth knowing before you read a number:
- Record counts show live records only — the same figure the data browser lists. Monitor → Collections shows soft-deleted rows in a separate Deleted column, because they still occupy storage.
- Deleting records does not shrink D1 storage. Soft-deleted rows are still rows, and SQLite does not return freed pages to the file even after a hard delete. Purging a collection's tombstones reclaims the space for reuse by that database, but the reported database size will not drop immediately.
#Background jobs
Everything above measures requests. Your instance also does work when nobody is asking it to — an hourly maintenance tick that re-arms scheduled flows, reaps orphaned runs, and takes your scheduled backups.
That work produces no HTTP traffic, so none of the charts on this page move when it stops. The Scheduled maintenance panel on System → Monitor → Health is the check that does: it reports when the tick last landed and the result of each task on that run. Its Overdue state is the one to act on — see Scheduled tasks for what runs and what breaks when it doesn't.
For alerting from outside the app, poll GET /health and watch .cron.stale, .cron.stalled and .cron.failing — all three, because they fail in different ways. stale catches the tick stopping; stalled catches one task dropping out of a tick that is otherwise fine, which is the failure that reports nothing else at all; failing catches a task that ran and threw. Any of them reports the instance as degraded.
#What GET /health actually checks
bindings answers "is this Worker configured?" — one boolean per binding, from the deployment. probes answers the different question "is the thing it is bound to answering?", for the four dependencies whose loss is fatal: the database (a SELECT 1), both KV namespaces (a read) and the file bucket (a head). Each reports ok, unreachable (bound, not answering) or absent (not bound at all), and the two faults are listed separately under missing.required and missing.unreachable because the remedies differ — one is a deploy that never bound the resource, the other is a resource that is down.
Status codes. unhealthy answers HTTP 503; healthy and degraded both answer 200. Degraded is deliberately not an outage: a stalled maintenance tick or an unconfigured optional binding does not stop the API serving, and this endpoint drives uptime alerting. A monitor that reads only the status line will therefore page on a dead dependency and stay quiet for a missing optional one.
#Usage & cost
System → Usage owns everything about quota and cost. Its Cost & Usage tab carries the resource gauges, the storage trend, and the cost breakdown; the Performance tab surfaces slow queries and hot paths (see Performance for the tuning guide).
Quota gauges used to appear on Monitor as well. They live in one place now — consumption against an allowance is a budget question rather than a "is it up right now" question, and the same numbers on two pages is precisely how the two pages came to disagree. Monitor links across to them.
Each gauge links to the attribution that explains it: D1 row gauges open the Performance tab grouped by collection, request and operation gauges group by endpoint. Storage has no per-request attribution, so it has no drill-down — its growth trend sits alongside instead.
#Storage growth
Storage is the only quota with a hard ceiling you cannot buy past on the free plan, so the Cost & Usage tab tracks it as a trend rather than a single number: current level, growth per day, and the projected date it fills at the current rate.
The trend is fitted from daily archives with a least-squares regression, so one spiky day does not dominate the projection. Until at least two days have been archived it reports "not enough history" rather than a reassuring 0% — an empty trend is not a clean bill of health. Archives are written by the analytics archival flow; without it you get the current level but no projection.
Every consumption figure is reported as a rate against the limit's own period, not as a raw total for whatever range you selected. Pick 7 days and a daily gauge shows the daily average across that week, annotated "measured over 7d"; the Cost tab's monthly projection scales from the same window. Picking a wider range gives you a more reliable number, not a bigger one.
On the free plan the Cost tab reports $0.00 even when a resource is projected past its allowance, and says so in the notes: Cloudflare throttles free-plan overage rather than billing it. The dollar figures are what the same usage would cost on a paid plan.
#What you learned
- The System dashboard is the at-a-glance view; Monitor is the diagnostic one
- Errors and the audit trail are visible in-app — no Cloudflare dashboard required for day-to-day questions
- Request charts say nothing about background work; the Scheduled maintenance panel is what covers it
- Usage tracking turns cost into a trend you watch, not a surprise
- Record counts are live records; deleted rows are shown separately and still cost storage
- Every panel names the system it read and how old the sample is, so two numbers that disagree can be told apart