Write to Analytics Engine
Write custom analytics events to Workers Analytics Engine.
Workers Analytics Engine provides time-series analytics at scale. Use it to track custom metrics, build usage-based billing, or understand service health on a per-customer basis.
Unlike logs, Analytics Engine is designed for aggregated queries over high-cardinality data. Writes are non-blocking and do not impact request latency.
Add an Analytics Engine dataset binding to your Wrangler configuration file. The dataset is created automatically when you first write to it.
{ "analytics_engine_datasets": [ { "binding": "ANALYTICS", "dataset": "my_dataset", }, ],}[[analytics_engine_datasets]]binding = "ANALYTICS"dataset = "my_dataset"export default { async fetch(request, env) { const url = new URL(request.url);
// Write a page view event env.ANALYTICS.writeDataPoint({ blobs: [ url.pathname, request.headers.get("cf-connecting-country") ?? "unknown", ], doubles: [1], // Count indexes: [url.hostname], // Sampling key });
// Write a response timing event const start = Date.now(); const response = await fetch(request); const duration = Date.now() - start;
env.ANALYTICS.writeDataPoint({ blobs: [url.pathname, response.status.toString()], doubles: [duration], indexes: [url.hostname], });
// Writes are non-blocking - no need to await or use waitUntil() return response; },};interface Env { ANALYTICS: AnalyticsEngineDataset;}
export default { async fetch(request: Request, env: Env): Promise<Response> { const url = new URL(request.url);
// Write a page view event env.ANALYTICS.writeDataPoint({ blobs: [ url.pathname, request.headers.get("cf-connecting-country") ?? "unknown", ], doubles: [1], // Count indexes: [url.hostname], // Sampling key });
// Write a response timing event const start = Date.now(); const response = await fetch(request); const duration = Date.now() - start;
env.ANALYTICS.writeDataPoint({ blobs: [url.pathname, response.status.toString()], doubles: [duration], indexes: [url.hostname], });
// Writes are non-blocking - no need to await or use waitUntil() return response; },};Each data point consists of:
- blobs (strings) - Dimensions for grouping and filtering. Use for paths, regions, status codes, or customer IDs.
- doubles (numbers) - Numeric values to record, such as counts, durations, or sizes.
- indexes (strings) - A single string used as the sampling key. Group related events under the same index.
Query your data using the SQL API:
curl "https://api.cloudflare.com/client/v4/accounts/$CLOUDFLARE_ACCOUNT_ID/analytics_engine/sql" \ --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \ --data "SELECT blob1 AS path, SUM(_sample_interval) AS views FROM my_dataset WHERE timestamp > NOW() - INTERVAL '1' HOUR GROUP BY path ORDER BY views DESC LIMIT 10"- Analytics Engine documentation - Full reference for Workers Analytics Engine.
- SQL API reference - Query syntax and available functions.
- Grafana integration - Visualize Analytics Engine data in Grafana.
Was this helpful?
- Resources
- API
- New to Cloudflare?
- Directory
- Sponsorships
- Open Source
- Support
- Help Center
- System Status
- Compliance
- GDPR
- Company
- cloudflare.com
- Our team
- Careers
- © 2026 Cloudflare, Inc.
- Privacy Policy
- Terms of Use
- Report Security Issues
- Trademark
-