---
description: Access metadata and insights across Cloudflare products.
title: Analytics
image: https://developers.cloudflare.com/analytics/og.png?v=5912beeb3297756c
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Analytics

Last updated Oct 2, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

Cloudflare visualizes the metadata collected by our products in the Cloudflare dashboard. Refer to [Types of analytics](https://developers.cloudflare.com/analytics/types-of-analytics/) for more information about the various types of analytics and where they exist in the dashboard.

---

## Features

[Workers Analytics Engine](https://developers.cloudflare.com/analytics/analytics-engine/)

Send unlimited-cardinality data from your Worker to a time-series database. Query it with SQL.

Use Workers Analytics Engine

[Account and zone analytics](https://developers.cloudflare.com/analytics/account-and-zone-analytics/)

Provides details about the requests and traffic related to your Cloudflare accounts and zones.

Use Account and zone analytics

[Cloudflare Network Analytics](https://developers.cloudflare.com/analytics/network-analytics/)

Provides near real-time visibility into network and transport-layer traffic patterns and DDoS attacks.

Use Cloudflare Network Analytics

[GraphQL Analytics API](https://developers.cloudflare.com/analytics/graphql-api/)

Provides all of your performance, security, and reliability data from one endpoint. Select exactly what you need, from one metric for a domain to multiple metrics aggregated for your account.

Use GraphQL Analytics API

[SQL API](https://developers.cloudflare.com/analytics/sql-api/)

Query Cloudflare analytics datasets with a supported subset of SQL. Filter, aggregate, group, and sort analytics data through one API endpoint.

Use SQL API

---

## Related products

[Workers](https://developers.cloudflare.com/workers/)

Cloudflare Workers allows developers to build serverless applications and deploy instantly across the globe for exceptional performance, reliability, and scale.

[Logs](https://developers.cloudflare.com/logs/)

Detailed logs that contain metadata generated by Cloudflare products helpful for debugging, identifying configuration adjustments, and creating analytics.

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"WebPage","@id":"https://developers.cloudflare.com/analytics/#page","headline":"Analytics","description":"Access metadata and insights across Cloudflare products.","url":"https://developers.cloudflare.com/analytics/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/og.png?v=5912beeb3297756c","dateModified":"2026-10-02","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Explore the different analytics available in Cloudflare.
title: Types of analytics
image: https://developers.cloudflare.com/analytics/types-of-analytics/og.png?v=c2a3c86e383ef336
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Types of analytics

Last updated Oct 2, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/types-of-analytics/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

Cloudflare Analytics is a comprehensive product that encompasses all metadata generated by the Cloudflare network. You can access these insights through the Cloudflare dashboard. Depending on where in the dashboard you are, it will show you different aspects from the collected metadata.

## Account-level analytics

### Account Analytics (beta)

Available under **Observability** > **Analytics** in your Cloudflare dashboard when you log in, Account Analytics (beta) shows you an [overview of traffic for all domains](https://developers.cloudflare.com/analytics/account-and-zone-analytics/account-analytics/) under your Cloudflare account, such as requests and bandwidth by country, information related to security, cache, and errors, among others. To access Account Analytics, [log in to the Cloudflare dashboard ↗︎](https://dash.cloudflare.com/login), select the appropriate account, and go to **Observability** > **Analytics** > **Account analytics**.

### Network Analytics

Network Analytics provides [visibility into network and transport-layer traffic patterns, and DDoS attacks](https://developers.cloudflare.com/analytics/network-analytics/).

The Network Analytics dashboard is only available for customers with an Enterprise domain plan who use [Spectrum](https://developers.cloudflare.com/spectrum/), [Magic Transit](https://developers.cloudflare.com/magic-transit/), or [Bring Your Own IP (BYOIP)](https://developers.cloudflare.com/byoip/).

### Web Analytics

Web Analytics (formerly known as Browser Insights) [provides free, privacy-first analytics for your website](https://developers.cloudflare.com/web-analytics/). Web Analytics does not collect your visitor's personal data, and allows you to have a detailed view into the performance of web pages as experienced by your visitors.

### Carbon Impact Report

Carbon Impact Report gives you a [report on carbon savings ↗︎](https://blog.cloudflare.com/understand-and-reduce-your-carbon-impact-with-cloudflare/) from using Cloudflare services versus Internet averages for your usage volume.

Cloudflare is committed to use 100% renewable energy sources, but also to [remove all greenhouse gases emitted ↗︎](https://blog.cloudflare.com/cloudflare-committed-to-building-a-greener-internet/) as a result of powering our network since 2010.

## Analytics related to specific properties

Access aggregated traffic, security, and performance metrics for each domain proxied through Cloudflare. To access these analytics, [log in to the Cloudflare dashboard ↗︎](https://dash.cloudflare.com/login), select your account and domain, and go to **Analytics**.

Data available under **Analytics** includes:

- **HTTP Traffic** - Requests, Data transfer, Page views, Visits, and API requests.
- **Security** - Total Threats, Top Crawlers/Bots, Rate Limiting, Total Threats Stopped.
- **Performance** - Origin Performance, Bandwidth Saved.
- **Edge Reachability** - [Last mile insights](https://developers.cloudflare.com/network-error-logging/) for Enterprise customers.
- **Workers** - [Detailed information](https://developers.cloudflare.com/workers/observability/metrics-and-analytics/) related to your Workers per zone, and Workers KV per account.
- **Logs** - [Detailed logs](https://developers.cloudflare.com/logs/) of the metadata generated by Cloudflare products for Enterprise customers.
- **Instant logs** - [Live stream of traffic](https://developers.cloudflare.com/logs/instant-logs/) for your domain. Enterprise customers can access this live stream from the Cloudflare dashboard or from a command-line interface (CLI).

## Product analytics

Beyond the analytics provided for your properties, you can also access analytics related to specific products:

- [Bot Analytics](https://developers.cloudflare.com/bots/bot-analytics/) - Shows which requests are associated with known bots, likely automated traffic, likely human traffic, and more.
- [Cache Analytics](https://developers.cloudflare.com/cache/performance-review/cache-analytics/) - Insights to that help determine if resources are missing from cache, expired, or ineligible for caching.
- [DNS Analytics](https://developers.cloudflare.com/dns/additional-options/analytics/) - Provides insights about DNS queries to your zone.
- [Load Balancing Analytics](https://developers.cloudflare.com/load-balancing/reference/load-balancing-analytics/) - Features metrics to help gain insights into traffic load balancer steering decisions.
- [Security Events](https://developers.cloudflare.com/waf/analytics/security-events/) - Highlights attack and mitigation metrics detected by the Cloudflare WAF and HTTP DDoS protection systems.
- [Security Analytics](https://developers.cloudflare.com/waf/analytics/security-analytics/) - Displays information about all incoming HTTP requests, including those not affected by security measures (for example, from the WAF and DDoS protection systems).

## GraphQL APIs

If you would like to have more control over how you visualize the analytic and log information available on the Cloudflare dashboard, use the [GraphQL Analytics API](https://developers.cloudflare.com/analytics/graphql-api/) to build customized views. This API replaces and expands on the previous Zone Analytics API.

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/types-of-analytics/#page","headline":"Types of analytics","description":"Explore the different analytics available in Cloudflare.","url":"https://developers.cloudflare.com/analytics/types-of-analytics/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/types-of-analytics/og.png?v=c2a3c86e383ef336","dateModified":"2026-10-02","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Understand how Cloudflare uses sampling for analytics.
title: Understanding sampling in Cloudflare Analytics
image: https://developers.cloudflare.com/analytics/sampling/og.png?v=242840609cb3b2e7
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Understanding sampling in Cloudflare Analytics

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/sampling/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

[Sampling ↗︎](<https://en.wikipedia.org/wiki/Sampling_(statistics)>) is a technique used in analytics to analyze a subset of data rather than processing every individual data point. In Cloudflare Analytics, sampling ensures efficient performance and scalability while maintaining high accuracy and reliability. This document provides a comprehensive overview of how sampling works, why it is used, and its impact on analytics across different Cloudflare tools.

## How sampling works

We use a sampling method called [Adaptive Bit Rate (ABR) ↗︎](https://blog.cloudflare.com/explaining-cloudflares-abr-analytics/) to ensure that queries complete quickly, even when working with large datasets. ABR dynamically adjusts the level of detail in the data retrieved based on query complexity and duration. This approach ensures fairness by preventing large or complex queries from consuming a disproportionate amount of computing resources, which could otherwise slow down or block smaller queries. By distributing resources more equitably, ABR allows the system to maintain consistent performance for all users, regardless of the dataset size.

To make this possible, data is stored at multiple resolutions (100%, 10%, 1%), each representing different sampling percentages. When a query is run, ABR selects the best resolution based on the query's complexity and number of rows to retrieve. By dynamically adjusting the data resolution, ABR optimizes performance and prevents delays. This sets it apart from systems that struggle with timeouts, errors, or high costs when dealing with large datasets.

## Why sampling is applied

Cloudflare's data pipeline handles [over 700 million events per second ↗︎](https://blog.cloudflare.com/how-we-make-sense-of-too-much-data) (and growing) across its global network. Processing and storing all this data in real-time would be prohibitively expensive and time-consuming. By leveraging carefully designed sampling methods, Cloudflare Analytics delivers accurate and actionable data, balancing precision with performance.

Sampling enables:

- **Scalability**: Reduces the volume of data processed without compromising insights.
- **Performance**: Speeds up query execution for analytics.
- **Cost-Efficiency**: Minimizes resource usage and storage needs.

## Can I trust sampled data?

Sampled data is highly reliable, and can provide insights that are as dependable as those derived from full datasets. Cloudflare designs sampling techniques to ensure we capture the essential characteristics of the entire dataset, delivering results you can trust.

Sampling is an approach similarly used in other domains, for instance:

- Google Maps: Just as online maps display lower-resolution images when zoomed out and higher-resolution images when zoomed in — keeping the total number of pixels relatively constant — Cloudflare Analytics dynamically adjusts sampling rates to efficiently provide insights, ensuring queries return consistent and accurate results regardless of dataset size.
- Opinion Polls: Similar to how pollsters sample a subset of the population to predict election outcomes, Cloudflare samples a portion of your data to provide accurate, system-wide insights.
- Movie Frames: Watching a movie at 30 frames per second (fps) instead of 60 fps does not change the overall experience, much like how analyzing fewer data points still reveals the same patterns and trends in your analytics dataset.

We acknowledge it can be challenging to verify the exact resolution of ABR query results at this time. However, as a general rule, you can check the number of rows read. A higher number of rows read will result in higher resolution results. For example, results based on thousands of rows are highly likely to be representative, while those based on just a few rows may not be as reliable.

In the near future, we plan to expose confidence intervals along with query results, so you can see precisely how accurate your results are.

## Additional considerations

**When sampling occurs**

- Sampling is typically applied to very high-traffic datasets where full data analysis would be impractical.
- For smaller datasets, full data analysis is often performed without sampling.

**Sampling rates**

- Sampling rates vary depending on the dataset and product.
- Cloudflare ensures that sampling rates are consistent within a single dataset to maintain accuracy across queries.

**Impact on metrics**

- While sampling reduces the volume of processed data, aggregated metrics like totals, averages, and percentiles are extrapolated based on the sample size. This ensures the reported metrics represent the entire dataset accurately.

**Limitations**

- Sampling may not capture extremely rare events with very low occurrence rates.

**Sampling in analytics interfaces**

- GraphQL API: Sampling metadata is included in the query response. For more information, refer to the sampling [GraphQL Analytics API](https://developers.cloudflare.com/analytics/graphql-api/sampling/) documentation.
- Workers Analytics Engine: For more information, refer to the [Workers Analytics Engine](https://developers.cloudflare.com/analytics/analytics-engine/sampling/) documentation.
- Dashboard Analytics: Displays an icon with the sampled percentage of data, if sampled data was used for the visualization.

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/sampling/#page","headline":"Understanding sampling in Cloudflare Analytics","description":"Understand how Cloudflare uses sampling for analytics.","url":"https://developers.cloudflare.com/analytics/sampling/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/sampling/og.png?v=242840609cb3b2e7","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Create custom dashboards from analytics, log, and Workers Observability data.
title: Custom dashboards
image: https://developers.cloudflare.com/analytics/custom-dashboards/og.png?v=537b3d095c257183
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Custom dashboards

Last updated Oct 2, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/custom-dashboards/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

Custom dashboards allow you to build personalized views that highlight the metrics most critical to your infrastructure and security posture. Move beyond standard product dashboards and consolidate data from multiple Cloudflare products into a single, unified view.

[Go to **Custom dashboards** ↗](https://dash.cloudflare.com/?to=/:account/analytics/dashboards)

## What you can do

Monitor security threats by tracking WAF blocks, bot scores, and threat patterns across your zones. Combine HTTP traffic data with security events to correlate attack patterns with traffic spikes.

Analyze application performance by visualizing origin response times, cache hit ratios, and error rates. Identify slow endpoints and understand how latency varies by region or device type.

Track business metrics by monitoring API usage, bandwidth consumption, and traffic patterns. Build executive dashboards that surface the KPIs that matter to your organization.

Investigate incidents so that when something goes wrong, you can create focused dashboards that combine the specific signals relevant to your investigation. Chart Workers logs and traces next to HTTP traffic and security events, and Log Explorer customers can select Log Explorer datasets to create charts from raw, unsampled log data.

## Availability

Custom Dashboards are available to all Cloudflare customers. Each account can have up to 100 dashboards.

## Get started

### Start from a template

Templates are the fastest way to get value from Custom Dashboards. Each template is designed around a specific use case and includes pre-configured charts that surface the most relevant metrics.

| Template | Use case |
| --- | --- |
| **Bot monitoring** | Understand what automated traffic is hitting your site — distinguish good bots (search engines, monitoring) from bad actors |
| **API Security** | Monitor your API endpoints for anomalies, track data transfer volumes, and identify unexpected access patterns |
| **Account takeover** | Watch for credential stuffing attacks by tracking failed login attempts, leaked credential usage, and suspicious authentication patterns |
| **API Performance** | Identify slow API endpoints, track error rates by endpoint, and monitor latency percentiles to catch regressions before users complain |
| **Performance monitoring** | Find bottlenecks in your origin infrastructure — which hosts are slow, which paths have high TTFB, and how performance trends over time |

After selecting a template, you can customize it by adding, removing, or modifying charts to fit your specific needs.

### Build from scratch

For specialized monitoring needs, create a blank dashboard and add charts that query exactly the data you need.

Custom Dashboards support three kinds of data source:

- Over 100 datasets available via the Cloudflare GraphQL API, including HTTP traffic, security events, Workers analytics, R2 Storage metrics, Load Balancing health, Zero Trust logs, DNS queries, and more.
- [Workers Observability logs and traces](#workers-observability-data) for Workers that have Workers Logs or Workers Traces turned on.
- [Log Explorer datasets](#log-explorer-data), for Log Explorer customers.

## Create charts

### Natural language prompts

Describe what you want to see in plain English, and AI will construct the appropriate visualization:

- "Show me error rates by country for the last 24 hours."
- "Compare cached vs uncached requests over time."
- "What are my top 10 paths by request volume?"
- "Display WAF blocks grouped by rule ID."

This is the fastest way to explore your data when you have a question but are not sure which dataset or metric to use.

### Manual configuration

For precise control, configure each element of your chart:

- **Dataset** — The data source to query (HTTP requests, security events, Workers Observability logs and traces, Log Explorer datasets)
- **Metrics** — What to measure (requests, bytes, duration) and how to aggregate it (sum, average, percentiles)
- **Dimensions** — How to break down the data (by country, status code, hostname, etc.)
- **Filters** — Conditions to narrow the data (specific paths, IP ranges, user agents, etc.)

### Chart types

Choose the visualization that best fits your data:

| Chart type | Best for |
| --- | --- |
| **Timeseries** | Trends and patterns over time — traffic spikes, latency changes, error rate fluctuations |
| **Bar** | Comparing values across categories — requests by country, errors by status code |
| **Donut** | Understanding proportions — cache hit ratio, traffic distribution by content type |
| **Map** | Geographic patterns — where your traffic originates, regional performance differences |
| **Stat** | Single important numbers — total requests today, current error rate, p99 latency |
| **Percentage** | Ratios and rates — cache hit percentage, bot traffic proportion |
| **Top N** | Rankings — busiest endpoints, most blocked IPs, top user agents |

#### Example: Build a security overview chart

To track blocked requests by WAF rule:

1. Select the **Security Events** dataset.
2. Choose **Events** as the metric with **Total** aggregation.
3. Add **Rule ID** as a dimension to group by rule.
4. Filter to **Action equals Block** to focus on blocked traffic.
5. Select **Bar** chart to compare rule effectiveness.

The result shows which WAF rules are triggering most frequently, helping you understand your threat landscape and tune your security configuration.

## Dashboard filters

Dashboard filters apply to all charts at once, making it easy to focus your entire dashboard on a specific segment of traffic.

Common uses:

- **Time range** — Zoom into a specific incident window across all charts
- **Hostname** — Focus on a single domain when you manage multiple properties
- **Country** — Analyze traffic patterns for a specific region
- **Status code** — Investigate error spikes by filtering to `5xx` responses

When you add a filter, every chart on the dashboard updates to reflect the narrowed scope.

## Workers Observability data

You can chart Workers Observability telemetry alongside your analytics data. When creating a chart, select one of the following datasets:

| Dataset | What it contains | Dimensions | Metrics |
| --- | --- | --- | --- |
| **Workers Observability — Logs** | Invocation and log events from Workers with [Workers Logs](https://developers.cloudflare.com/workers/observability/logs/workers-logs/) turned on | Service, level, status code, error, region, trigger, URL, script name, outcome, event type, entrypoint, execution model | Events, CPU time, wall time, duration |
| **Workers Observability — Traces (OTel)** | Spans from Workers with [Workers Traces](https://developers.cloudflare.com/workers/observability/traces/) turned on | Service, span name, status code, error, region, transaction name | Spans, duration |

Workers Observability datasets are available for every Worker in the account that has Workers Logs or Workers Traces turned on. They follow the retention of the underlying Workers Observability data, so a dashboard time range that extends past that retention returns no data for those charts.

For example, to track Worker errors by service:

1. Select the **Workers Observability — Logs** dataset.
2. Choose **Events** as the metric.
3. Add **Service** as a dimension.
4. Filter to **Level equals error**.
5. Select **Timeseries** to see how errors change over time.

## Log Explorer data

Note

This feature is available to Log Explorer customers only.

Log Explorer customers can create charts and dashboards using their raw, unsampled log data. This is useful when precision matters — for example, when monitoring for specific error conditions, tracking exact request counts for compliance reporting, or analyzing low-volume but high-impact events that might be missed in sampled data.

Standard analytics datasets use sampled data, which provides fast, accurate trends for high-volume metrics. But for use cases like:

- **Exact counts** — "How many requests from this specific IP hit our API today?"
- **Rare events** — Monitoring for specific error codes or attack signatures that occur infrequently
- **Compliance and auditing** — When you need precise numbers, not estimates
- **Low-traffic endpoints** — Analyzing paths that do not generate enough volume for reliable sampling

Log Explorer data gives you charts built from every logged event, not a statistical sample.

When creating a chart, Log Explorer customers can select from Log Explorer datasets alongside the standard GraphQL analytics datasets and Workers Observability datasets.

## Manage dashboards

Dashboards belong to the account, so everyone with access to the account can view them, and they are organized in a list view where you can see all dashboards in your account. From any dashboard, you can add, remove, or rearrange charts, and changes are saved automatically when you exit edit mode.

Each chart has a menu with options to edit its configuration, duplicate it, or drill down into related data in Security Analytics or Log Search.

## Further analysis

Custom Dashboards are designed to work alongside other Cloudflare analytics tools:

- **Security Analytics** — When a chart reveals suspicious traffic, drill down to investigate individual requests and see full request details
- **Log Search** — Move from aggregated metrics to raw logs when you need to understand exactly what happened during an incident

This workflow supports the typical investigation pattern: start with high-level dashboards to identify anomalies, then drill into detailed logs to understand root cause.

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/custom-dashboards/#page","headline":"Custom dashboards","description":"Create custom dashboards from analytics, log, and Workers Observability data.","url":"https://developers.cloudflare.com/analytics/custom-dashboards/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/custom-dashboards/og.png?v=537b3d095c257183","dateModified":"2026-10-02","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Monitor network and transport-layer traffic and DDoS attacks.
title: Network analytics
image: https://developers.cloudflare.com/analytics/network-analytics/og.png?v=1d0e01401c7f5978
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Network analytics

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/network-analytics/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

Cloudflare Network Analytics (version 2) provides near real-time visibility into network and transport-layer traffic patterns and DDoS attacks. Network Analytics visualizes packet and bit-level data, the same data available via the Network Analytics dataset of the GraphQL Analytics API.

Requirements

Network Analytics requires the following:

- A Cloudflare Enterprise plan.
- Cloudflare Magic Transit or Spectrum.
- Cloudflare WAN.

For a technical deep-dive into Network Analytics, refer to our [blog post ↗︎](https://blog.cloudflare.com/building-network-analytics-v2/).

## Remarks

- The Network Analytics logs refer to IP traffic of Magic Transit customer prefixes/leased IP addresses or Spectrum applications. These logs are not directly associated with the [zones](https://developers.cloudflare.com/fundamentals/concepts/accounts-and-zones/#zones) in your Cloudflare account.
- The data retention for Network Analytics is 16 weeks. Additionally, data older than eight weeks might have lower resolution when using narrow time frames.

## Related resources

- [Cloudflare GraphQL API](https://developers.cloudflare.com/analytics/graphql-api/)
- [Cloudflare Logpush](https://developers.cloudflare.com/logs/logpush/)
- [Migrating from Network Analytics v1 to Network Analytics v2](https://developers.cloudflare.com/analytics/graphql-api/migration-guides/network-analytics-v2/)

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"WebPage","@id":"https://developers.cloudflare.com/analytics/network-analytics/#page","headline":"Network analytics","description":"Monitor network and transport-layer traffic and DDoS attacks.","url":"https://developers.cloudflare.com/analytics/network-analytics/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/network-analytics/og.png?v=1d0e01401c7f5978","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Filter and configure Network Analytics dashboard data.
title: Adjust the displayed data
image: https://developers.cloudflare.com/analytics/network-analytics/configure/displayed-data/og.png?v=8eb3533c715ad2c6
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Adjust the displayed data

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/network-analytics/configure/displayed-data/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

## Select the appropriate tab

To perform a broad analysis of layer 3/4 traffic and DDoS attacks, use the **All traffic** tab.

To focus on a specific mitigation system, select one of the [other available tabs](https://developers.cloudflare.com/analytics/network-analytics/understand/main-dashboard/#available-tabs). The tabs displayed in the dashboard depend on your Cloudflare services.

## Select high-level metric

To toggle your view of the data, select the **Total packets** or **Total bytes** side panels.

![Network Analytics side panels allowing you to use packets or bits/bytes as the base unit for the dashboard.](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=1440,height=602,format=webp/_astro/high-level-metrics.DFUDKbKH.png)

*Note: Labels in this image may reflect a previous product name.*

The selected metric will determine the base units (packets or bits/bytes) used in the several dashboard analytics panels.

## Select a dimension

Under **Packets summary** or **Bits summary**, select one of the [available dimensions](https://developers.cloudflare.com/analytics/network-analytics/understand/main-dashboard/#available-dimensions) to view the data along that dimension. The default dimension is **Action**.

## Apply filters

You can apply multiple filters and exclusions to adjust the scope of the data displayed in Network Analytics. Filters affect all the data displayed in the dashboard.

There are two ways to filter Network Analytics data: select **Add filter** or select one of the stat filters.

### Select Add filter

Select **Add filter** to open the **New filter** popover. Specify a field, an operator, and a value to complete your filter expression. Select **Apply** to update the view.

Notes about filtering

When applying filters, observe these guidelines:

- Wildcards are not supported.
- You do not need to wrap values in quotes.
- When specifying an ASN number, leave out the `AS` prefix. For example, enter `1423` instead of `AS1423`.

### Select a stat filter

To filter based on the type of data associated with one of the Network Analytics stats, use the **Filter** and **Exclude** buttons that display when you hover over the stat.

## Create a Network Firewall rule from the applied filters

Note

This feature is only available to Magic Transit and Cloudflare WAN (formerly Magic WAN) users.

Select **Create Network Firewall rule** to create a [Network Firewall](https://developers.cloudflare.com/cloudflare-network-firewall/) rule that will block all traffic matching the selected filters in Network Analytics.

Note that some filters will not be added to the new Network Firewall rule definition. However, you can further configure the rule in Network Firewall.

## Show IP prefix events

Enable the **Show annotations** toggle to show or hide annotations for advertised/withdrawn IP prefix events in the **Network Analytics** view. Select each annotation to get more details.

![Network Analytics chart displaying IP prefix-related annotations.](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=785,height=555,format=webp/_astro/view-annotations.D18njKAr.png)

## View logged or monitored traffic

[Network DDoS managed rules](https://developers.cloudflare.com/ddos-protection/managed-rulesets/network/) and [Advanced DDoS Protection systems](https://developers.cloudflare.com/ddos-protection/advanced-ddos-systems/overview/) provide a `log` or `monitoring` mode that does not drop traffic. These `log` and `monitoring` mode events are based on **Verdict** and **Outcome**/**Action** fields.

To filter for these traffic events:

1. In the Cloudflare dashboard, go to the **Network Analytics** page. [Go to **Network analytics** ↗](https://dash.cloudflare.com/?to=/:account/networking-insights/analytics/network-analytics/transport-analytics)
2. Go to **DDoS managed rules** tab.
3. Select **Add filter**.
   - Set `Verdict equals drop`.
   - Set `Action equals pass`.
4. Select **Apply**.

By setting `verdict` to `drop` and `outcome` as `pass`, we are filtering for traffic that was marked as a detection (that is, verdict was `drop`) but was not dropped (for example, outcome was `pass`).

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/network-analytics/configure/displayed-data/#page","headline":"Adjust the displayed data","description":"Filter and configure Network Analytics dashboard data.","url":"https://developers.cloudflare.com/analytics/network-analytics/configure/displayed-data/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/network-analytics/configure/displayed-data/og.png?v=8eb3533c715ad2c6","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Share filters and export Network Analytics data.
title: Share and export data
image: https://developers.cloudflare.com/analytics/network-analytics/configure/share-export/og.png?v=22d2afbb6d71e896
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Share and export data

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/network-analytics/configure/share-export/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

## Share Network Analytics filters

When you add filters and specify a time range in Network Analytics, the URL changes to reflect those parameters.

To share your view of the data, copy the URL and send it to other users so that they can work with the same view.

## Export sample log data

You can export up to 100 raw events from the **Packet sample log** at a time. This option is useful when you need to combine and analyze Cloudflare data with data stored in a separate system or database, such as a SIEM system.

To export log data:

1. Select **Export**.
2. Choose either CSV or JSON format for rendering exported data. The downloaded file name will reflect the selected time range, using this pattern:

```txt
network-analytics-attacks-<START_TIME>-<END_TIME>.json
```

## Export a Network Analytics report

To print or download a snapshot report from Network Analytics, select **Print report**. Your web browser's print interface displays options for printing or saving as a PDF.

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/network-analytics/configure/share-export/#page","headline":"Share and export data","description":"Share filters and export Network Analytics data.","url":"https://developers.cloudflare.com/analytics/network-analytics/configure/share-export/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/network-analytics/configure/share-export/og.png?v=22d2afbb6d71e896","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Change the time range in Network Analytics.
title: Adjust the time range
image: https://developers.cloudflare.com/analytics/network-analytics/configure/time-range/og.png?v=e2675c88417ce12b
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Adjust the time range

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/network-analytics/configure/time-range/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

## Using the timeframe drop-down list

Use the timeframe drop-down list to change the time range over which Network Analytics displays data. When you select a timeframe, the entire view is updated to reflect your choice.

In the Network Analytics dashboard, the range of historical data you can query is 112 days.

When you select *Previous 30 minutes*, the **Network Analytics** card will show the data from the last 30 minutes, refreshing every 20 seconds. A *Live* notification appears next to the statistic drop-down list to let you know that the view keeps updating automatically:

![Timeframe drop-down with Previous 30 minutes selected.](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=279,height=65,format=webp/_astro/timeframe-selector.CKN2F0gt.png)

## Zooming in the chart

To zoom in a specific period, select and drag to define a region in the **Packets summary** (or **Bits summary**) chart. To zoom out, select **X** in the time range selector.

![User zooming in a given period in the Network Analytics traffic chart.](https://developers.cloudflare.com/images/analytics/network-analytics/chart-zoom-in.gif)

The effective resolution goes up when you zoom in and goes down when you zoom out, due to the [Adaptive Bit Rate](https://developers.cloudflare.com/analytics/network-analytics/understand/concepts/#adaptive-bit-rate-sampling). This means that a big packet burst that lasted a few seconds may look less impactful when analyzing a chart displaying data for 24 hours or more.

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/network-analytics/configure/time-range/#page","headline":"Adjust the time range","description":"Change the time range in Network Analytics.","url":"https://developers.cloudflare.com/analytics/network-analytics/configure/time-range/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/network-analytics/configure/time-range/og.png?v=e2675c88417ce12b","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Learn how to view and use data from Network Analytics.
title: Get started
image: https://developers.cloudflare.com/analytics/network-analytics/get-started/og.png?v=bc12057ae3200e6d
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Get started

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/network-analytics/get-started/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

Requirements

Network Analytics requires the following:

- A Cloudflare Enterprise plan.
- Cloudflare Magic Transit or Spectrum.
- Cloudflare WAN.

## View the Network Analytics dashboard

1. In the Cloudflare dashboard, go to the **Network Analytics** page. [Go to **Network analytics** ↗](https://dash.cloudflare.com/?to=/:account/networking-insights/analytics/network-analytics/transport-analytics)
2. Select an account that has access to Magic Transit or Spectrum.
3. Configure the displayed data. You can [adjust the time range](https://developers.cloudflare.com/analytics/network-analytics/configure/time-range/), [select the main metric](https://developers.cloudflare.com/analytics/network-analytics/configure/displayed-data/#select-high-level-metric) (total packets or total bytes), [apply filters](https://developers.cloudflare.com/analytics/network-analytics/configure/displayed-data/#apply-filters), and more.

## Get Network Analytics data via API

Use the [GraphQL Analytics API](https://developers.cloudflare.com/analytics/graphql-api/) to query data using the available [Network Analytics nodes](https://developers.cloudflare.com/analytics/graphql-api/migration-guides/network-analytics-v2/node-reference/).

## Send Network Analytics logs to a third-party service

[Create a Logpush job](https://developers.cloudflare.com/logs/logpush/logpush-job/enable-destinations/) that sends Network analytics logs to your storage service, SIEM solution, or log management provider.

## Limitations

Users with the `Analytics` role will have visibility to IDs but will not see the following on the Network Analytics dashboard:

- Tunnel names
- Prefix names
- [Cloudflare Network Firewall](https://developers.cloudflare.com/cloudflare-network-firewall/) rules
- [DDoS managed rulesets](https://developers.cloudflare.com/ddos-protection/managed-rulesets/)
- Override names

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/network-analytics/get-started/#page","headline":"Get started","description":"Learn how to view and use data from Network Analytics.","url":"https://developers.cloudflare.com/analytics/network-analytics/get-started/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/network-analytics/get-started/og.png?v=bc12057ae3200e6d","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Understand how Network Analytics collects packet data.
title: Data collection
image: https://developers.cloudflare.com/analytics/network-analytics/reference/data-collection/og.png?v=36a0c1287006e7c5
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Data collection

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/network-analytics/reference/data-collection/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

For the purposes of mitigating DDoS attacks and providing traffic visibility through the Network Analytics dashboard, Cloudflare collects data from different protocols such as IP, IPv6, TCP, UDP, ICMP, GRE, and DNS.

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/network-analytics/reference/data-collection/#page","headline":"Data collection","description":"Understand how Network Analytics collects packet data.","url":"https://developers.cloudflare.com/analytics/network-analytics/reference/data-collection/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/network-analytics/reference/data-collection/og.png?v=36a0c1287006e7c5","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Understand Network Analytics sampling and enrichment concepts.
title: Concepts
image: https://developers.cloudflare.com/analytics/network-analytics/understand/concepts/og.png?v=86c954fc883fe2b9
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Concepts

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/network-analytics/understand/concepts/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

## Adaptive Bit Rate sampling

With Adaptive Bit Rate (ABR) sampling, every analytics query that supports ABR will be calculated at a resolution matching the query. Depending on the size of your query, the ABR mechanism will choose the best sampling rate and fetch a response from one of the sample tables encapsulated behind each [Network Analytics node](https://developers.cloudflare.com/analytics/graphql-api/migration-guides/network-analytics-v2/node-reference/). The cardinality and accuracy are preserved even for historical data.

For more background information on Adaptive Bit Rate sampling, refer to the [Explaining Cloudflare's ABR Analytics ↗︎](https://blog.cloudflare.com/explaining-cloudflares-abr-analytics/) blog post.

## Edge Sample Enrichment

Network Analytics can provide accurate data due to the sample rate and to Edge Sample Enrichment.

Sample rates vary depending on the mitigation service. For example:

- The sample rate for `dosd` changes dynamically from 1/100 to 1/10,000 packets based on the volume of packets.
- The sample rate for Network Firewall events changes dynamically from 1/100 to 1/1,000,000 packets based on the number of packets.
- The sample rate for `flowtrackd` is 1/10,000 packets.

NA uses a data logging pipeline that relies on Edge Sample Enrichment. By delegating the packet sample enrichment and cross-referencing to the global data centers, the data pipeline’s resilience and tolerance against congestion are improved. Using this method, enriched packet samples are immediately stored in Cloudflare's core data centers as soon as they arrive.

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/network-analytics/understand/concepts/#page","headline":"Concepts","description":"Understand Network Analytics sampling and enrichment concepts.","url":"https://developers.cloudflare.com/analytics/network-analytics/understand/concepts/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/network-analytics/understand/concepts/og.png?v=86c954fc883fe2b9","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Navigate the Network Analytics dashboard sections.
title: Main dashboard
image: https://developers.cloudflare.com/analytics/network-analytics/understand/main-dashboard/og.png?v=5d7cbcd61dc847a3
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Main dashboard

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/network-analytics/understand/main-dashboard/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

The following sections are a guide on the different sections of the main Network Analytics dashboard.

## Available tabs

The **All traffic** tab displays global information about layer 3/4 traffic, DNS traffic, and DDoS attacks. The dashboard has additional tabs with specific information (and specific filters) for different mitigation systems.

The following table contains a summary of what is shown in each tab:

| Tab name | For Magic Transit users | For Spectrum users |
| --- | --- | --- |
| **All traffic** | Traffic dropped by DDoS managed rules, Advanced TCP Protection, Advanced DNS Protection, and Cloudflare Network Firewall, and traffic passed to the origin server. | Traffic dropped and passed by DDoS managed rules. |
| **DDoS managed <br>rules** | Traffic dropped and passed by [DDoS managed rules](https://developers.cloudflare.com/ddos-protection/managed-rulesets/). | Traffic dropped and passed by [DDoS managed rules](https://developers.cloudflare.com/ddos-protection/managed-rulesets/). |
| **TCP <br>Protection** | Traffic dropped and passed by the [Advanced TCP Protection](https://developers.cloudflare.com/ddos-protection/advanced-ddos-systems/overview/advanced-tcp-protection/) system. Does not include traffic dropped by DDoS managed rules. | N/A |
| **DNS <br>Protection** | Traffic dropped and passed by the [Advanced DNS Protection](https://developers.cloudflare.com/ddos-protection/advanced-ddos-systems/overview/advanced-dns-protection/) system. Does not include traffic dropped by DDoS managed rules. | N/A |
| **Cloudflare Network Firewall** | Traffic dropped by [Cloudflare Network Firewall](https://developers.cloudflare.com/cloudflare-network-firewall/) and traffic passed to the origin server. Does not include traffic dropped by DDoS managed rules, Advanced TCP Protection, or Advanced DNS Protection. | N/A |

Use these tabs to better understand the decisions made by each mitigation system, and which rules are being applied to mitigate attacks.

Note

Network Analytics will not show other traffic, such as:

- Traffic dropped by Spectrum
- Traffic dropped by the WAF/CDN service
- Traffic served from cache or from Workers

## High-level metrics

The side panels in the Network Analytics page provide a summary of activity over the period selected in the time frame drop-down list.

![Available high-level metrics in the Network Analytics dashboard](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=1440,height=602,format=webp/_astro/high-level-metrics.DFUDKbKH.png)

*Note: Labels in this image may reflect a previous product name.*

Selecting one of the metrics in the sidebar will define the base unit (packets or bits/bytes) for the data displayed in the dashboard.

## Executive summary

![Executive summary card in the Network Analytics dashboard.](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=980,height=232,format=webp/_astro/executive-summary-card.Bueo7FPl.png)

The executive summary provides top insights and trends about DDoS attacks targeting your network, including the amount of attacks, percentage of attacks traffic mitigated relative to your traffic, largest attack rates, total mitigated attack bytes, top source, and estimated duration of the attacks.

These insights are adaptive based on the selected time frame and the **Packets** or **Bytes** [metrics](#high-level-metrics) selector. The insights are also accompanied by the trends relative to the selected time period, visualized as period-over-period change in percentage and indicator arrows.

The executive summary also features a one-liner summary at the top, informing you about recent and ongoing attacks.

### Total attacks

The total number of attacks is based on unique attack IDs of mitigations issued by the [Network-layer DDoS Attack Protection managed ruleset](https://developers.cloudflare.com/ddos-protection/managed-rulesets/network/).

Since the mitigation system may generate several mitigation rules (and therefore several attack IDs) for a single attack, the actual number of attacks may seem higher in some cases.

To obtain the metadata of recently mitigated DDoS attacks, query the [`dosdAttackAnalyticsGroups`](https://developers.cloudflare.com/analytics/graphql-api/migration-guides/network-analytics-v2/node-reference/#dosdattackanalyticsgroups) GraphQL node.

Note about attack rates

Attack rates in the executive summary may seem lower than the ones displayed in the time series graph because they are calculated based on the maximum rate of unique attack events and only by the Network-layer DDoS Attack Protection managed ruleset. However, in practice, multiple attacks and mitigation systems can contribute to blocking a single attack, resulting in a larger rate than the one displayed.

Additionally, attack rates may change based on the sampling and adaptive bit rate (ABR) as you zoom in and out in the time series graph. Refer to [Concepts](https://developers.cloudflare.com/analytics/network-analytics/understand/concepts/) for more information.

## Filters

In the main dashboard card you can apply filters to the displayed data.

You can filter by the following parameters:

- Mitigation action taken by Cloudflare
- Mitigation system that performed the action
- Source IP, port, ASN, tunnel
- [Direction](#traffic-direction)
- Destination IP, port, IP range (description or CIDR of provisioned prefixes), tunnel
- Source Cloudflare data center and data center country of where the traffic was observed
- Packet size
- TCP flag
- TTL

Note that the IP Range filter currently has a limitation that only supports filtering /24 IPv4 Ranges and /64 IPv6 Ranges.

Dashboard tabs for [specific mitigation systems](https://developers.cloudflare.com/analytics/network-analytics/understand/main-dashboard/#available-tabs) (DDoS managed rules, Advanced TCP Protection, or Cloudflare Network Firewall) may have additional filter parameters.

### Traffic direction

The available values in the **Direction** filter have the following meaning, from the point of view of a specific customer's network:

- **Ingress**: Incoming traffic from the public Internet (ingress) to the customer's network via Cloudflare's network (for example, through [Magic Transit](https://developers.cloudflare.com/magic-transit/));
- **Egress**: Outgoing traffic leaving the customer's network through Cloudflare's network to the public Internet (for example, through [Magic Transit deployed with the egress option](https://developers.cloudflare.com/magic-transit/reference/egress/));
- **Lateral**: Traffic that stayed within the customer's network, routed through Cloudflare's network (for example, traffic between customer office branches or data centers routed through [Cloudflare WAN](https://developers.cloudflare.com/cloudflare-wan/)).

## Packets summary or Bits summary

Displays a plot of the traffic (in terms of bits or packets) in the selected time range according to the values of a given dimension. By default, Network Analytics displays data broken down by **Action**.

### Available dimensions

You can choose one of the following dimensions:

- Action
- Destination IP
- Destination IP range
- Destination port
- Destination tunnels
- Mitigation system
- Source ASN
- Data center country
- Source data center
- Source IP
- Source port
- Source tunnels
- Packet size
- Protocol
- TCP flag

Dashboard tabs for [specific mitigation systems](https://developers.cloudflare.com/analytics/network-analytics/understand/main-dashboard/#available-tabs) (DDoS managed rules, Advanced TCP Protection, or Cloudflare Network Firewall) may have additional dimensions.

## Mitigation system distribution

The **Mitigation System Distribution** card displays the amount of traffic (in terms of packets or bits) that was mitigated by each mitigation system.

## Packet sample log

The Network Analytics **Packet sample log** shows up to 100 log events — including both allowed and dropped packets — in the currently selected time range, paginated with 10 results per page per time range view (the [GraphQL Analytics API](https://developers.cloudflare.com/analytics/graphql-api/) does not have this limitation).

Expand each row to display event details, including the full packet headers and metadata.

Dashboard tabs for [specific mitigation systems](https://developers.cloudflare.com/analytics/network-analytics/understand/main-dashboard/#available-tabs) (DDoS managed rules, Advanced TCP Protection, or Cloudflare Network Firewall) may have additional fields in the expanded event details.

## Data center country/Source data center

Displays the top source [Cloudflare data centers ↗︎](https://www.cloudflare.com/en-gb/network/) where the displayed traffic was ingested. The same card can also display the country associated with these top source data centers.

To switch between **Data center country** and **Source data center** information, use the dropdown in the card.

## Top insights

The different panels in **Top insights** display the top items in each dimension. To filter by a given value or exclude a value from displayed data, hover the value stats and select **Filter** or **Exclude**.

To set the number of items to display for each dimension, open the drop-down list associated with the view and select the desired number of items.

## TCP flag

The **TCP Flag** panel displays the TCP flags set for all the traffic currently displayed in the dashboard, including both allowed and mitigated traffic.

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/network-analytics/understand/main-dashboard/#page","headline":"Main dashboard","description":"Navigate the Network Analytics dashboard sections.","url":"https://developers.cloudflare.com/analytics/network-analytics/understand/main-dashboard/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/network-analytics/understand/main-dashboard/og.png?v=5d7cbcd61dc847a3","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Query Cloudflare analytics data using GraphQL.
title: GraphQL Analytics API
image: https://developers.cloudflare.com/analytics/graphql-api/og.png?v=d0a231757d66f4b6
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# GraphQL Analytics API

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/graphql-api/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

The GraphQL Analytics API provides data regarding HTTP requests passing through Cloudflare's network, as well as data from specific products, such as Firewall or Load Balancing. Network Analytics users also have access to packet-level data. Use the GraphQL Analytics API to select specific datasets and metrics of interest, filter and aggregate the data along various dimensions, and integrate the results with other applications.

The basis of the API is the [GraphQL framework ↗︎](https://graphql.org/), created and open-sourced by Facebook. There is an active developer community for GraphQL and powerful clients for running queries, which makes it easy to get started. GraphQL is especially useful for building visualizations and powers the analytics in the Cloudflare dashboard.

GraphQL models a business domain as a graph using a schema. In the schema, there are logical definitions for different types of nodes and their connections (edges). These nodes are the datasets you use for your analytics. You write queries in GraphQL much like in SQL: you specify the dataset (table), the metrics to retrieve (such as requests and bytes), and filter or group by dimensions (for example, a time period).

GraphQL differs from a traditional API: it has one single endpoint:

```txt
https://api.cloudflare.com/client/v4/graphql
```

You pass the query parameters as a JSON object in the payload of a `POST` request to this endpoint.

You can use `curl` to make requests to the GraphQL Analytics API. Alternatively, you can use a GraphQL client to construct queries and pass requests to the GraphQL Analytics API.

## Clients

We are using [GraphiQL ↗︎](https://github.com/skevy/graphiql-app) for our example GraphQL queries. There are many other popular open-source clients that you can find online, such as [Altair ↗︎](https://altairgraphql.dev) and [Insomnia ↗︎](https://insomnia.rest).

## Limitations

The purpose of the GraphQL API is to provide aggregated analytics about various Cloudflare products. These datasets should not be used as a measure for usage that Cloudflare uses for billing purposes. Billable traffic [excludes things like DDoS traffic ↗︎](https://blog.cloudflare.com/unmetered-mitigation), while GraphQL is a measure of overall consumption/usage, so it will include all measurable traffic.

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"WebPage","@id":"https://developers.cloudflare.com/analytics/graphql-api/#page","headline":"GraphQL Analytics API","description":"Query Cloudflare analytics data using GraphQL.","url":"https://developers.cloudflare.com/analytics/graphql-api/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/graphql-api/og.png?v=d0a231757d66f4b6","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Apply GraphQL Analytics API rate limits per account and per zone, so usage scales with the number of resources you query.
title: Account-based rate limiting
image: https://developers.cloudflare.com/analytics/graphql-api/account-based-rate-limiting/og.png?v=6ed71cd97cafb4e5
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Account-based rate limiting

Last updated Aug 25, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/graphql-api/account-based-rate-limiting/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

By default, the GraphQL Analytics API applies rate limits per user or per API token. As you grow — adding more zones and accounts — all of your analytics traffic competes for that single per-credential quota.

**Account-based rate limiting** applies limits per account and per zone instead. Each account and zone gets its own independent budget, so a single user or token can query many resources at once without exhausting one shared quota. This is the recommended model if you query analytics across multiple zones or accounts.

## Benefits

- **Scales with your footprint.** Throughput grows with the number of accounts and zones you query, instead of being capped by a single per-credential limit.
- **Higher quotas for Enterprise.** Enterprise customers receive higher default per-account (15 rps) and per-zone (10 rps) quotas.
- **Easy limit increases.** Need more headroom? Get in touch, we can accommodate needed increases to your limits.

## Enable account-based rate limiting

Send the following HTTP header with your requests to the existing GraphQL API endpoint (`https://api.cloudflare.com/client/v4/graphql`):

```txt
X-Rate-Limit-Type: account-based
```

Your endpoint URL and credentials stay the same. Requests without this header continue to use the default per-user / per-token limits, so you can adopt this gradually.

## Limits

| Scope | Default limit |
| --- | --- |
| Each account | 1 request per second (300 requests per 5-minute window) |
| Each zone | 1 request per second (300 requests per 5-minute window) |

A single `accounts` block counts one request against the referenced account. A single `zones` block counts one request against the referenced zone; if the `zones` block is nested inside an `accounts` block, it counts against that account instead.

Because limits apply per resource, the total throughput available to one user or token scales with the number of distinct accounts and zones you query.

Note

If you send more than one request per second sustained to a **single** account or zone, request a higher limit for that resource (refer to [Request higher limits](#request-higher-limits)).

## Query requirements

Most queries work unchanged. Only queries that select a **list** or **range** of zones at the top (`viewer`) level need adjusting: nest those zones inside a single `accounts` block. The adjusted queries are valid under **both** rate limiting models.

Querying a single zone — no change:

```graphql
{
  viewer {
    zones(filter: { zoneTag: "<ZONE_TAG>" }) {
      # ...
    }
  }
}
```

Querying a single account — no change:

```graphql
{
  viewer {
    accounts(filter: { accountTag: "<ACCOUNT_TAG>" }) {
      # ...
    }
  }
}
```

Querying a list or range of zones — nest inside the owning account:

```graphql
# Not supported: a list of zones at the viewer level
{
  viewer {
    zones(filter: { zoneTag_in: ["<ZONE_A>", "<ZONE_B>"] }) {
      # ...
    }
  }
}

# Supported: the same zones nested inside their account
{
  viewer {
    accounts(filter: { accountTag: "<ACCOUNT_TAG>" }) {
      zones(filter: { zoneTag_in: ["<ZONE_A>", "<ZONE_B>"] }) {
        # ...
      }
    }
  }
}
```

The same applies to range filters such as `zoneTag_gt`. The query semantics are identical — you only need the account tag that owns the zones, which you already have.

## Request higher limits

If you need more than the default per-account or per-zone throughput, contact your Cloudflare account team to request an increase for the specific accounts and zones you query. Increases under this model are applied per resource and take effect quickly, without an engineering release.

## Rate limit errors

When a limit is exceeded, the API returns an error with `extensions.code` set to `budget`, naming the account or zone that was throttled:

```json
{
  "data": null,
  "errors": [
    {
      "extensions": { "code": "budget", "timestamp": "2026-01-01T01:01:01Z" },
      "message": "Account <ACCOUNT_TAG> has exceeded its rate limit. Please try again after 5 minutes. Refer to this page for more details about rate limits: https://developers.cloudflare.com/analytics/graphql-api/limits/",
      "path": null
    }
  ]
}
```

The equivalent zone error reports `Zone <ZONE_TAG> has exceeded its rate limit`. Retry after the 5-minute window, spread traffic across resources, or [request a higher limit](#request-higher-limits).

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/graphql-api/account-based-rate-limiting/#page","headline":"Account-based rate limiting","description":"Apply GraphQL Analytics API rate limits per account and per zone, so usage scales with the number of resources you query.","url":"https://developers.cloudflare.com/analytics/graphql-api/account-based-rate-limiting/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/graphql-api/account-based-rate-limiting/og.png?v=6ed71cd97cafb4e5","dateModified":"2026-08-25","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Understand GraphQL Analytics API error formats.
title: Error responses
image: https://developers.cloudflare.com/analytics/graphql-api/errors/og.png?v=0831ad0117bcd00d
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Error responses

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/graphql-api/errors/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

The GraphQL Analytics API is a RESTful API based on HTTPS requests and JSON responses, and will return familiar HTTP status codes (for example, `404`, `500`, `504`). However, in contrast to the common REST approach, a `200` response can contain an error, conforming to the [GraphQL specification ↗︎](https://graphql.github.io/graphql-spec/June2018/#sec-Errors).

All responses contain an `errors` array, which will be `null` if there are no errors, and include at least one error object if there was an error. Non-null error objects will contain the following fields:

- `message`: a string describing the error.
- `path`: the nodes associated with the error, starting from the root. Note that the number included in the path array, for example, `0` or `1`, specifies to which zone the error applies; `0` indicates the first zone in the list (or only zone, if only one is being queried).
- `timestamp`: UTC datetime when the error occurred.

## Example

```json
{
  "data": null,
  "errors": [
    {
      "message": "cannot request data older than 2678400s",
      "path": ["viewer", "zones", "0", "firewallEventsAdaptiveGroups"],
      "extensions": {
        "timestamp": "2019-12-09T21:27:19.195060142Z"
      }
    }
  ]
}
```

## Common error types

### Service unavailability

Sample error messages:

- `unable to execute query, please try again later` (HTTP `503`)
- `too many queries in progress, please try again later` (HTTP `503`)

These messages indicate a temporary server-side issue. The first message typically means the upstream database is unreachable or returned an error. The second message means the server has reached its maximum number of concurrent queries.

Retry the request after a short delay. If the error persists, check the [Cloudflare status page ↗︎](https://www.cloudflarestatus.com/) for ongoing incidents.

### Dataset accessibility limits exceeded

Sample error messages:

- `cannot request data older than...` (HTTP `400`)
- `number of fields can't be more than...` (HTTP `400`)
- `limit must be positive number and not greater than...` (HTTP `400`)
- `query time range is too large...` (HTTP `400`)

These messages indicate that the query exceeds what is allowed for the particular dataset under the current [plan ↗︎](https://www.cloudflare.com/plans/), and an upgrade should be considered. Refer to [Node limits](https://developers.cloudflare.com/analytics/graphql-api/limits/#node-limits-and-availability) for details.

### Parsing issues

Sample error messages:

- `error parsing args...` (HTTP `400`)
- `scalar fields must have no selections` (HTTP `400`)
- `object field must have selections` (HTTP `400`)
- `unknown field...` (HTTP `400`)
- `query contains error, please review it and retry` (HTTP `400`)

These messages indicate that the query cannot be processed because it is malformed. Check the query syntax against the [GraphQL schema](https://developers.cloudflare.com/analytics/graphql-api/getting-started/explore-graphql-schema/) and correct the invalid fields or structure.

### Rate limits exceeded

Sample error messages:

- `rate limiter budget depleted, try again after 5 minutes` (HTTP `429`)
- `in combination, your request queries too many nodes, zones and accounts` (HTTP `429`)
- `query consumed excessive resources, please try running smaller queries which consume fewer resources` (HTTP `429`)

These messages indicate the query exceeded rate or resource limits. Reduce the query complexity, the number of zones or accounts per request, or wait before retrying. Refer to the [Limits](https://developers.cloudflare.com/analytics/graphql-api/limits/) section for more details about rate limits.

### Authentication and authorization errors

Sample error messages:

- `Unauthorized` (HTTP `401`)
- `not authorized for that account` (HTTP `403`)
- `zones [...] are not authorized` (HTTP `403`)
- `does not have access to the path...` (HTTP `403`)

An `Unauthorized` response means the API token or bearer token is missing, expired, or invalid. Verify that you are passing a valid token in the `Authorization` header.

A `403` response means the token does not have the required permissions for the requested account or zone. Verify the token has the **Analytics: Read** permission for the relevant resources. Refer to the [Tokens](https://developers.cloudflare.com/fundamentals/api/get-started/create-token/) section for more details.

### Internal server errors

Sample error message:

- `Internal server error` (HTTP `500`)

This is a generic error indicating an unexpected failure. If it persists, contact [Cloudflare Support ↗︎](https://support.cloudflare.com/) with the full request and response, including the `Ray-ID` header from the HTTP response.

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/graphql-api/errors/#page","headline":"Error responses","description":"Understand GraphQL Analytics API error formats.","url":"https://developers.cloudflare.com/analytics/graphql-api/errors/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/graphql-api/errors/og.png?v=0831ad0117bcd00d","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Request confidence intervals for sampled data.
title: Confidence Intervals
image: https://developers.cloudflare.com/analytics/graphql-api/features/confidence-intervals/og.png?v=8d0555b09ffb64f0
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Confidence Intervals

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/graphql-api/features/confidence-intervals/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

Confidence intervals help assess accuracy and quantify uncertainty in results from sampled datasets. When querying sum or count fields on adaptive datasets, you can request a confidence interval to understand the possible range around an estimate. For example, specifying a confidence level of `0.95` returns the estimate, along with the range of values that likely contains the true value 95% of the time.

## Availability

- **Supported datasets**: Adaptive (sampled) datasets only.
- **Supported fields**: All `sum` and `count` fields.
- **Usage**: Confidence `level` must be provided as a decimal between 0 and 1 (for example, `0.90`, `0.95`, `0.99`).
- **Default**: If no confidence level is specified, intervals are not returned.

## Usage example

The following example shows how to query a confidence interval and interpret the response.

### Request

To request a confidence interval, use the `confidence(level: X)` argument in your query.

*A GraphQL querygraphql*

```graphql
query SingleDatasetWithConfidence($zoneTag: string, $start: Time, $end: Time) {
  viewer {
    zones(filter: {zoneTag: $zoneTag}) {
      firewallEventsAdaptiveGroups(
        filter: {datetime_gt: $start, datetime_lt: $end}
        limit: 1000
      ) {
        count
        avg {
          sampleInterval
        }
        confidence(level: 0.95) {
          count {
            estimate
            lower
            upper
            sampleSize
          }
        }
      }
    }
  }
}
```

### Response

The response includes the following values:

- `estimate`: The estimated value, based on sampled data.
- `lower`: The lower bound of the confidence interval.
- `sampleSize`: The number of sampled data points used to calculate the estimate.
- `upper`: The upper bound of the confidence interval.

In this example, the interpretation of the response is that, based on a sample of 40,054, the estimated number of events is 42,939, with 95% confidence that the true value lies between 42,673 and 43,204.

```json
{
  "data": {
    "viewer": {
      "zones": [
        {
          "firewallEventsAdaptiveGroups": [
            {
              "avg": {
                "sampleInterval": 1.0720277625205972
              },
              "confidence": {
                "count": {
                  "estimate": 42939,
                  "lower": 42673.44115335711,
                  "sampleSize": 40054,
                  "upper": 43204.55884664289
                }
              },
              "count": 42939
            }
          ]
        }
      ]
    }
  },
  "errors": null
}
```

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/graphql-api/features/confidence-intervals/#page","headline":"Confidence Intervals","description":"Request confidence intervals for sampled data.","url":"https://developers.cloudflare.com/analytics/graphql-api/features/confidence-intervals/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/graphql-api/features/confidence-intervals/og.png?v=8d0555b09ffb64f0","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Explore available GraphQL Analytics API datasets.
title: Datasets (tables)
image: https://developers.cloudflare.com/analytics/graphql-api/features/data-sets/og.png?v=ed56f32fc1d62b2d
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Datasets (tables)

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/graphql-api/features/data-sets/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

Cloudflare Analytics offers a range of datasets, including both general and product-specific ones. Datasets use a consistent naming scheme that explicitly identifies the type of data they return:

- **Domain** - Each dataset is named after the field it describes and is associated with a set of nodes. Product-specific data nodes incorporate the name of the relevant product, for instance `loadBalancingRequests*` nodes.
- **Adaptive Sampling** - Nodes that represent data acquired using adaptive sampling incorporate the `Adaptive` suffix. For more details, refer to [sampling](https://developers.cloudflare.com/analytics/graphql-api/sampling/).
- **Aggregated data** - Nodes that represent aggregated data include the `Groups` suffix. For example, the `loadBalancingRequestsAdaptiveGroups` node represents aggregated data for Load Balancing requests. Aggregated data is returned in an array of `...Group` objects. Please note: we have a node that currently excluded from that naming convention - `workersInvocationsAdaptive` (beta).
- **Raw data** - Raw data nodes, such as `loadBalancingRequestsAdaptive`, are not aggregated and so do not incorporate the `Groups` suffix. Raw data is returned in arrays containing objects of the relevant data type. For example, a query to `loadBalancingRequestsAdaptive` returns a variety of `LoadBalancingRequest` objects.

To find out more information about datasets, availability, beta, and deprecation statuses, please refer to GraphQL [discovery](https://developers.cloudflare.com/analytics/graphql-api/features/discovery/) features.

## Working with datasets

### Aggregated fields

This example illustrates the structure for Groups:

```graphql
type WhateverGroup {
    count # No subfields, it is just the group size. Not available for roll-up tables.
    sum {
        # fields that support summing (numbers, maps of numbers)
    }
    avg {
        # fields that support averaging (numbers)
    }
    uniq {
        # fields that support uniqueing (numbers, strings, enums, IPs, dates, etc.)
    }
}
```

Unique values are not available as a dimension but can be queried as demonstrated in this example:

```graphql
{
  # Get number of bytes and unique IPs in each minute.
  httpRequests1mGroups {
    sum {
      bytes
    }
    uniq {
      uniques # unique IPs
    }
    dimensions {
      datetimeMinute
    }
  }

  # Count the number of events in each hour.
  firewallEventsAdaptiveGroups {
    count
    dimensions {
      datetimeHour
    }
  }
}
```

### Schema type definitions

Every exposed table has a GraphQL type definition. Type definitions observe the following rules:

- Regular fields represent themselves.
- Every field, including nested fields, has a type and represents a list of that type.
- The `enum` type represents an enumerated field.

Here is an example type definition for `ContentTypeMapElem`:

```graphql
type ContentTypeMapElem {
    edgeResponseContentType: UInt32!
    requests: UInt64!
    bytes: UInt64!
}

# An array of httpRequestsGroup is the result of httpRequests1hGroups or
# httpRequests1mGroups query.
type httpRequestsGroup {
    date: Date!
    timeslot: DateTime!
    requests: UInt64!
    contentTypeMap: [ContentTypeMapElem!]!
    # ... other fields
}

enum TrustedClientCategory {
    UNKNOWN
    REAL_BROWSER
    HONEST_BOT
}

# An array of Request is the result of httpRequests query.
type Request {
    trustedClientCategory: TrustedClientCategory!
    # ... other fields
}
```

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/graphql-api/features/data-sets/#page","headline":"Datasets (tables)","description":"Explore available GraphQL Analytics API datasets.","url":"https://developers.cloudflare.com/analytics/graphql-api/features/data-sets/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/graphql-api/features/data-sets/og.png?v=ed56f32fc1d62b2d","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Discover available GraphQL Analytics API nodes and limits.
title: Discovery
image: https://developers.cloudflare.com/analytics/graphql-api/features/discovery/og.png?v=31f73636db1c8c47
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Discovery

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/graphql-api/features/discovery/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

GraphQL API supports [introspection](https://developers.cloudflare.com/analytics/graphql-api/features/discovery/introspection/) to explore nodes and provides a way to retrieve the user's [limits](https://developers.cloudflare.com/analytics/graphql-api/features/discovery/settings/) for every node.

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/graphql-api/features/discovery/#page","headline":"Discovery","description":"Discover available GraphQL Analytics API nodes and limits.","url":"https://developers.cloudflare.com/analytics/graphql-api/features/discovery/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/graphql-api/features/discovery/og.png?v=31f73636db1c8c47","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Explore the GraphQL schema using introspection.
title: Introspection
image: https://developers.cloudflare.com/analytics/graphql-api/features/discovery/introspection/og.png?v=2816ddfd1edec4dc
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Introspection

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/graphql-api/features/discovery/introspection/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

Cloudflare GraphQL API has a dynamic schema and exposes more than 70 datasets across zone and account scopes. We constantly expand the list and replace existing ones with more capable alternatives.

To tackle the schema question, GraphQL provides an [introspection ↗︎](https://graphql.org/learn/introspection/) mechanism. It is part of the GraphQL specification and allows you to explore the graph of the datasets and fields.

The introspection results provide an overview of ALL available nodes and fields, their descriptions and deprecation status.

Although GraphQL has `query`, `subscription`, and `mutation` operations, Cloudflare GraphQL API only supports `query` operation.

## Description and Beta mode

With details on data exposed by a given node or a field, descriptions also indicate whether it is in Beta mode. Beta nodes (or fields) are for testing and exploration and are usually available for customers on more extensive plans. Please do not rely on beta data nodes since they are subject to change or removal without notice.

## Deprecation

Introspection provides information about deprecation status. Cloudflare uses it as a notification about replacement plans. If the sunset date is provided, please migrate to a replacement node(s) before that date to avoid any disruption.

## Availability

Some of the nodes might only be available to query for some users. Please refer to the [settings](https://developers.cloudflare.com/analytics/graphql-api/features/discovery/settings/) node for more details about availability and personal limits on a given node.

## Explore documentation

The most convenient way to introspect the schema is to use a documentation [explorer](https://developers.cloudflare.com/analytics/graphql-api/getting-started/explore-graphql-schema/) that usually is a part of a GraphQL client (like GraphiQL, Altair, etc).

Alternatively, you can also do it manually by using `__schema` node with the needed directives.

*A typical introspection querygraphql*

```graphql
{
	__schema {
		queryType {
			name
		}
		mutationType {
			name
		}
		subscriptionType {
			name
		}
		types {
			...FullType
		}
		directives {
			name
			description
			locations
			args {
				...InputValue
			}
		}
	}
}
fragment TypeRef on __Type {
	kind
	name
	ofType {
		kind
		name
		ofType {
			kind
			name
			ofType {
				kind
				name
				ofType {
					kind
					name
					ofType {
						kind
						name
						ofType {
							kind
							name
							ofType {
								kind
								name
							}
						}
					}
				}
			}
		}
	}
}
fragment InputValue on __InputValue {
	name
	description
	type {
		...TypeRef
	}
	defaultValue
}
fragment FullType on __Type {
	kind
	name
	description
	fields(includeDeprecated: true) {
		name
		description
		args {
			...InputValue
		}
		type {
			...TypeRef
		}
		isDeprecated
		deprecationReason
	}
	inputFields {
		...InputValue
	}
	interfaces {
		...TypeRef
	}
	enumValues(includeDeprecated: true) {
		name
		description
		isDeprecated
		deprecationReason
	}
	possibleTypes {
		...TypeRef
	}
}
```

For more details on how to send a GraphQL request with curl, please refer to [Execute a GraphQL query with curl](https://developers.cloudflare.com/analytics/graphql-api/getting-started/execute-graphql-query/).

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/graphql-api/features/discovery/introspection/#page","headline":"Introspection","description":"Explore the GraphQL schema using introspection.","url":"https://developers.cloudflare.com/analytics/graphql-api/features/discovery/introspection/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/graphql-api/features/discovery/introspection/og.png?v=2816ddfd1edec4dc","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Query dataset-specific limits via the Settings node.
title: Settings node
image: https://developers.cloudflare.com/analytics/graphql-api/features/discovery/settings/og.png?v=e782841e23a15187
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Settings node

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/graphql-api/features/discovery/settings/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

Cloudflare GraphQL API exposes more than 70 datasets to its customers. These datasets represent different Cloudflare products with very different data shapes; thus, each has its configuration of [limits](https://developers.cloudflare.com/analytics/graphql-api/limits/).

Although we allow access to ALL plans for the essential datasets (like `httpRequestsAdaptiveGroups`, `firewallEventsAdaptive`, etc), users on larger plans benefit from an extended set of datasets and wider query limits.

In addition to [introspection](https://developers.cloudflare.com/analytics/graphql-api/features/discovery/introspection/), users can use the Settings node that is available for both zones and accounts scopes.

## Format

`Settings` node has all datasets from `zones` and `accounts` as fields.

*Using a settings node on accounts nodesgraphql*

```graphql
{
  viewer {
    accounts(filter: { accountTag : $accountTag }) {
      settings {
        # any dataset(s) from accounts
      }
    }
    zones(filter: { zoneTag : $zoneTag }) {
      settings {
        # any dataset(s) from zones
      }
    }
  }
}
```

Every subnode of `settings` node could consist of these fields:

- `enabled` - shows whether the node is available for a requester or not;
- `availableFields` - shows the list of fields available for a requester. If it is a nested field, the path will be returned, like `sum_requests`;
- `maxPageSize` - retrieves the maximum number of records that can be returned
- `maxNumberOfFields` - answers on how many fields could be used in a single query for that node;
- `notOlderThan` - returns a number of seconds on how far back in time a query can read;
- `maxDuration` - shows how wide the requested time range could be.

## A sample query

*Get boundaries of firewallEventsAdaptive nodegraphql*

```graphql
query SampleQuery($zoneTag: string) {
	viewer {
		zones(filter: { zoneTag: $zoneTag }) {
			settings {
				firewallEventsAdaptive {
					enabled
					maxDuration
					maxNumberOfFields
					maxPageSize
					notOlderThan
				}
			}
		}
	}
}
```

*firewallEventsAdaptive limits for a given userjson*

```json
{
	"data": {
		"viewer": {
			"zones": [
				{
					"settings": {
						"firewallEventsAdaptive": {
							"enabled": true,
							"maxDuration": 259200,
							"maxNumberOfFields": 30,
							"maxPageSize": 10000,
							"notOlderThan": 2678400
						}
					}
				}
			]
		}
	},
	"errors": null
}
```

To get more details on how to execute queries, please refer to our how to get started [guides](https://developers.cloudflare.com/analytics/graphql-api/getting-started/).

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/graphql-api/features/discovery/settings/#page","headline":"Settings node","description":"Query dataset-specific limits via the Settings node.","url":"https://developers.cloudflare.com/analytics/graphql-api/features/discovery/settings/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/graphql-api/features/discovery/settings/og.png?v=e782841e23a15187","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Apply filters to GraphQL Analytics API queries.
title: Filtering
image: https://developers.cloudflare.com/analytics/graphql-api/features/filtering/og.png?v=51747dce0cd39ece
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Filtering

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/graphql-api/features/filtering/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

Filters constrain queries to a particular account or set of zones, requests by date, or those from a specific user agent, for example. Without filters, queries can suffer performance degradation, results can exceed supported bounds, and the data returned can be noisy.

## Filter Structure

The GraphQL filter is represented by the [GraphQL Input Object ↗︎](https://graphql.github.io/graphql-spec/June2018/#sec-Input-Objects), which exposes Boolean algebra on nodes.

You can use filters as an argument on the following resources:

- zones
- accounts
- tables (datasets)

### Zone filter

Allows querying zone-related data by zone ID (`zoneTag`).

```graphql
zones(filter: {zoneTag: "your Zone ID"}) {
    ...
}
```

The zone filter must conform to the following grammar:

```graphql
filter
    { zoneTag: t }
    { zoneTag_gt: t }
    { zoneTag_in: [t, ...] }
```

Compound filters (comma-separated, `AND`, `OR`) are not supported.

Use the `zoneTag: t` and `zoneTag_in: [t, ...]` forms when you know the zone IDs. Use the `zoneTag_gt: t` form with limits to traverse all zones if the zone IDs are not known. Zones always sort alphanumerically.

Omit the filter to get results for all zones (up to the supported limit).

### Account filter

The account filter uses the same structure and rules as the zone filter, except that it uses the Account ID (`accountTag`) instead of the Zone ID (`zoneTag`).

You must specify an account filter when making an account-scoped query, and you cannot query multiple accounts simultaneously.

Note

Network Analytics queries require an Account ID (`accountTag`) filter.

### Table (dataset) filter

Table filters require that you query at least one node. Use the `AND` operator to create and combine multi-node filters. Table filters also support the `OR` operator, which you must specify explicitly.

The following grammar describes the table filter, where `k` is the GraphQL node on which to filter and `op` is one of the supported operators for that node:

```graphql
filter
  { kvs }
kvs
  kv
  kv, kvs
kv
  k: v
  k_op: v
  AND: [filters]
  OR: [filters]
filters
  filter
  filter, filters
```

### Operators

Operator support varies, depending on the node type and node name.

#### Array operators

The following operators are supported for all array types:

| Operator | Comparison |
| --- | --- |
| `has` | array contains a value |
| `hasall` | array contains all of a list of values |
| `hasany` | array contains at least one of a list of values |

#### Scalar operators

The following operators are supported for all scalar types:

| Operator | Comparison |
| --- | --- |
| `gt` | greater than |
| `lt` | less than |
| `geq` | greater or equal to |
| `leq` | less or equal to |
| `neq` | not equal |
| `in` | in |

#### String operators

The `like` operator is available for string comparisons and supports the `%` character as a wildcard.

## Examples

Note

Filtering times are based on event start timestamps, which means requests that end after the filter may be included in queries (as long as they start within the given time).

### General example

```graphql
query GeneralExample($zoneTag: string, $start: Time) {
	viewer {
		zones(filter: { zoneTag: $zoneTag }) {
			httpRequestsAdaptiveGroups(
				filter: { datetime_gt: $start, clientCountryName: "GB" }
				limit: 1
			) {
				count
			}
		}
	}
}
```

### Filter on a specific node

The following GraphQL example shows how to filter a specific node. The SQL equivalent follows.

#### GraphQL

```graphql
httpRequestsAdaptiveGroups(filter: {datetime: "2018-01-01T10:00:00Z"}) {
    ...
}
```

#### SQL

```sql
WHERE datetime="2018-01-01T10:00:00Z"
```

### Filter on multiple fields

The following GraphQL example shows how to apply a filter to multiple fields, in this case two datetime fields. The SQL equivalent follows.

#### GraphQL

```graphql
httpRequests1hGroups(filter: {datetime_gt: "2018-01-01T10:00:00Z", datetime_lt: "2018-01-01T11:00:00Z"}) {
    ...
}
```

#### SQL

```sql
WHERE (datetime > "2018-01-01T10:00:00Z") AND (datetime < "2018-01-01T10:00:00Z")
```

### Filter using the `OR` operator

The following GraphQL example demonstrates using the `OR` operator in a filter. This `OR` operator filters for the value `US` or `GB` in the `clientCountryName` field.

#### GraphQL

```graphql
httpRequestsAdaptiveGroups(
        filter: {
          datetime: "2018-01-01T10:00:00Z",
          OR:[{clientCountryName: "US"}, {clientCountryName: "GB"}]) {
    ...
}
```

#### SQL

```sql
WHERE datetime="2018-01-01T10:00:00Z"
  AND ((clientCountryName = "US") OR (clientCountryName = "GB"))
```

### Filter an array by one value

The following GraphQL examples show how to filter an array field to only return data that includes a specific value. The SQL equivalent follows.

#### GraphQL

```graphql
mnmFlowDataAdaptiveGroups(filter: {ruleIDs_has: "rule-id"}) {
    ...
}
```

#### SQL

```sql
WHERE has(ruleIDs, 'rule-id')
```

### Filter an array by multiple values

The following GraphQL examples show how to filter an array field to only return data that includes several values. The SQL equivalent follows.

#### GraphQL

```graphql
mnmFlowDataAdaptiveGroups(filter: {ruleIDs_hasall: ["rule-id-1", "rule-id-2"]}) {
    ...
}
```

#### SQL

```sql
WHERE has(ruleIDs, 'rule-id-1') AND has(ruleIDs, 'rule-id-2')
```

### Filter end users

Add the `requestSource` filter for `eyeball` to return request, data transfer, and visit data about only the end users of your website. This will exclude actions taken by Cloudflare products (for example, cache purge, healthchecks, Workers subrequests) on your zone.

## Subqueries (advanced filters)

Subqueries are not currently supported. You can use two GraphQL queries as a workaround for this limitation.

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/graphql-api/features/filtering/#page","headline":"Filtering","description":"Apply filters to GraphQL Analytics API queries.","url":"https://developers.cloudflare.com/analytics/graphql-api/features/filtering/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/graphql-api/features/filtering/og.png?v=51747dce0cd39ece","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Query arrays and maps in GraphQL Analytics API.
title: Nested Structures
image: https://developers.cloudflare.com/analytics/graphql-api/features/nested-structures/og.png?v=35565c21075c7332
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Nested Structures

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/graphql-api/features/nested-structures/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

Two kinds of nested structures that are supported: **arrays** and **maps**. Fields of either of these types are arrays; when they are part of a query result, which is already an array of objects, they become nested arrays.

## Arrays

The GraphQL API supports two different sorts of arrays:

- Some arrays contain scalar types (for example, `[String]`) and function like ordinary fields that [can be filtered](https://developers.cloudflare.com/analytics/graphql-api/features/filtering/)
- Some arrays contain more complex types (for example, `[Subrequest]`.) The following section describes their behaviour.

Arrays of non-scalar types behave as a single value. There is no way to paginate through, filter, filter by, group, or group by the array.

On the other hand, you can choose which fields of the underlying type you want fetched.

For example, given arrays like this:

```javascript
type SubRequest {
    url: String!
    status: Int
}

type Request {
    date: Date!
    datetime: DateTime!
    subRequests: [SubRequest!]!
}
```

You can run a query to get the status by subrequest:

```javascript
{
    requests {
        date
        subRequests {
            # discard the url, only need the status
            status
        }
    }
}
```

The results would be:

```javascript
{
    "requests": [
        {
            "date": "2018-01-01",
            "subRequests": [{"status": 404}, {"status": 200}, {"status": 404}]
        },
        {
            "date": "2018-01-01",
            "subRequests": [{"status": 200}]
        }
    ]
}
```

## Maps

Maps behave like arrays, but can be grouped using the `sum` function. They are used in aggregated datasets, such as `httpRequest1dGroups`.

Example maps:

```javascript
type URLStatsMapElem {
    url: String!
    requests: Int
    bytes: Int
}

type Request {
    date: Date!
    datetime: DateTime!
    urlStatsMap: [URLStatsMapElem!]!
}
```

Query:

```javascript
{
    requests {
        sum {
            urlStatsMap {
                url
                requests
                bytes
            }
        }
        dimensions {
            date
        }
    }
}
```

Response:

```javascript
{
    "requests": [
        {
            "sum": {
                "urlStatsMap": [
                    {
                        "url": "hello-world.org/1",
                        "requests": 123,
                        "bytes": 1024
                    },
                    {
                        "url": "hello-world.org/10",
                        "requests": 1230,
                        "bytes": 10240
                    }
                ]
            }
            "dimensions" {
                "date": "2018-10-19"
            }
        },
        ...
    ]
}
```

## Examples

Query array fields in raw datasets:

```graphql
query NestedFields($zoneTag: string, $start: Time, $end: Time) {
	viewer {
		zones(filter: { zoneTag: $zoneTag }) {
			events(limit: 2, filter: { datetime_geq: $start, datetime_leq: $end }) {
				matches {
					ruleId
					action
					source
				}
			}
		}
	}
}
```

Example response:

```javascript
{
  "data": {
    "viewer": {
      "zones": [
        {
          "events": [
            {
              "matches": [
                {
                  "action": "allow",
                  "ruleId": "rule-id-one",
                  "source": "asn"
                },
                {
                  "action": "block",
                  "ruleId": "rule-id-two",
                  "source": "asn"
                }
              ]
            }
          ]
        }
      ]
    }
  },
  "errors": null
}
```

Query maps fields in aggregated datasets:

```graphql
query MapCapacity(
	$zoneTag: string
	$dateStart: Date
	$dateEnd: Date
	$start: Time
	$end: Time
) {
	viewer {
		zones(filter: { zoneTag: $zoneTag }) {
			httpRequests1mGroups(
				limit: 10
				filter: {
					date_geq: $dateStart
					date_leq: $dateEnd
					datetime_geq: $start
					datetime_lt: $end
				}
			) {
				sum {
					countryMap {
						clientCountryName
						requests
						bytes
						threats
					}
				}
				dimensions {
					datetimeHour
				}
			}
		}
	}
}
```

Example response:

```javascript
{
  "data": {
    "viewer": {
      "zones": [
        {
          "httpRequests1mGroups": [
            {
              "dimensions": {
                "datetime": "2019-03-08T17:00:00Z"
              },
              "sum": {
                "countryMap": [
                  {
                    "bytes": 51911317,
                    "clientCountryName": "XK",
                    "requests": 4492,
                    "threats": 0
                  },
                  {
                    "bytes": 1816103586,
                    "clientCountryName": "T1",
                    "requests": 132423,
                    "threats": 0
                  },
                  ...
                ]
              }
            }
          ]
        }
      ]
    }
  },
  "errors": null
}
```

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/graphql-api/features/nested-structures/#page","headline":"Nested Structures","description":"Query arrays and maps in GraphQL Analytics API.","url":"https://developers.cloudflare.com/analytics/graphql-api/features/nested-structures/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/graphql-api/features/nested-structures/og.png?v=35565c21075c7332","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Paginate through GraphQL Analytics API results.
title: Pagination
image: https://developers.cloudflare.com/analytics/graphql-api/features/pagination/og.png?v=c9b4527ede6b18ca
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Pagination

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/graphql-api/features/pagination/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

Pagination – breaking up your query results into smaller parts – can be done using `limit`, `orderBy`, and filtering parameters. The GraphQL Analytics API does not support cursors for pagination.

- `limit` (integer) defines how many records to return.
- `orderBy` (string) defines the sort order for the data.

## Query pages without cursors

Our examples assume that the `date` and `clientCountryName` relationships are unique.

### Get the first *n* results of a query

To limit results, add the `limit` parameter as an integer. For example, query the first two records:

```javascript
firewallEventsAdaptive (limit: 2, orderBy: [datetime_ASC, clientCountryName_ASC]) {
    datetime
    clientCountryName
}
```

Note

Specifying a sort order by date returns less specific results than specifying a sort order by date and country.

**Response**

```javascript
{
  "firewallEventsAdaptive" : [
    {
      "datetime": "2018-11-12T00:00:00Z",
      "clientCountryName": "UM"
    },
    {
      "datetime": "2018-11-12T00:00:00Z",
      "clientCountryName": "US"
    }
  ]
}
```

### Query for the next page using filters

To get the next *n* results, specify a filter to exclude the last result from the previous query. Taking the previous example, you can do this by appending the greater-than operator (`_gt`) to the `clientCountryName` field and the greater-or-equal operator (`_geq`) to the `datetime` field. This is where being specific about sort order comes into play. You are less likely to miss results using a more granular sort order.

```javascript
firewallEventsAdaptive (limit: 2, orderBy: [datetime_ASC, clientCountryName_ASC], filter: {datetime_geq: "2018-11-12T00:00:00Z", clientCountryName_gt: "US"}) {
    datetime
    clientCountryName
}
```

**Response**

```javascript
{
  "firewallEventsAdaptive" : [
    {
      "datetime": "2018-11-12T00:00:00Z",
      "clientCountryName": "UY"
    },
    {
      "datetime": "2018-11-12T00:00:00Z",
      "clientCountryName": "UZ"
    }
  ]
}
```

### Query the previous page

To get the previous *n* results, reverse the filters and sort order.

```javascript
firewallEventsAdaptive (limit: 2, orderBy: [datetime_DESC, clientCountryName_DESC, filter: {datetime_leq: "2018-11-12T00:00:00Z", clientCountryName_lt: "UY"}]) {
  datetime
  clientCountryName
}
```

**Response**

```javascript
{
  "firewallEventsAdaptive" : [
    {
      "datetime": "2018-11-12T00:00:00Z",
      "clientCountryName": "US"
    },
    {
      "datetime": "2018-11-12T00:00:00Z",
      "clientCountryName": "UM"
    }
  ]
}
```

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/graphql-api/features/pagination/#page","headline":"Pagination","description":"Paginate through GraphQL Analytics API results.","url":"https://developers.cloudflare.com/analytics/graphql-api/features/pagination/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/graphql-api/features/pagination/og.png?v=c9b4527ede6b18ca","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Sort GraphQL Analytics API query results.
title: Sorting
image: https://developers.cloudflare.com/analytics/graphql-api/features/sorting/og.png?v=e06e125bef11f500
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Sorting

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/graphql-api/features/sorting/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

You can specify the order of the query result elements using the `orderBy` argument. By default, the results are sorted by the primary key of a dataset (table). If you specify another field to sort on, the primary key is also used in the sorting key, allowing results to remain consistent for pagination.

The default order for an aggregated dataset is by the fields on which the aggregated data is grouped. If you specify a different order, the aggregation group is appended to your specified ordering.

Note

Ordering within nested structures is not supported.

## Examples

### Raw data sorting

```graphql
firewallEventsAdaptive (orderBy: [clientCountryName_ASC]) {
    clientCountryName
}
```

### Raw data sorting using multiple fields

```graphql
firewallEventsAdaptive (orderBy: [clientCountryName_ASC, datetime_DESC]) {
    clientCountryName
    datetime
}
```

### Group sorting by aggregation function

```graphql
httpRequests1hGroups (orderBy: [sum_bytes_DESC]){
    sum {
        bytes
        requests
    }
    dimensions {
        datetime
    }
}
```

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/graphql-api/features/sorting/#page","headline":"Sorting","description":"Sort GraphQL Analytics API query results.","url":"https://developers.cloudflare.com/analytics/graphql-api/features/sorting/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/graphql-api/features/sorting/og.png?v=e06e125bef11f500","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Set up and access Network Analytics.
title: Get started
image: https://developers.cloudflare.com/analytics/graphql-api/getting-started/og.png?v=bc12057ae3200e6d
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Get started

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/graphql-api/getting-started/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

Use these articles to get started with the Cloudflare GraphQL API:

- [Authentication](https://developers.cloudflare.com/analytics/graphql-api/getting-started/authentication/) - walks you through the options and the steps required to set up your access to Cloudflare API successfully,
- [Querying basics](https://developers.cloudflare.com/analytics/graphql-api/getting-started/querying-basics/) - brings simple query examples for you to start exploring the GraphQL API,
- [Introspect the GraphQL schema](https://developers.cloudflare.com/analytics/graphql-api/getting-started/explore-graphql-schema/) - explains how-to surf the schema with GraphQL client,
- [Create a query in a GraphQL client](https://developers.cloudflare.com/analytics/graphql-api/getting-started/compose-graphql-query/) - describes how to build and run a query against the Cloudflare GraphQL API in the GraphQL clients,
- [Use curl to query the GraphQL API](https://developers.cloudflare.com/analytics/graphql-api/getting-started/execute-graphql-query/) - walks you through running a query against the Cloudflare GraphQL API from the command line.

For examples of how to build your own GraphQL Analytics dashboard and query specific information, such as Firewall and Workers events, please refer to [Tutorials](https://developers.cloudflare.com/analytics/graphql-api/tutorials/).

Data unavailability: Customer Metadata Boundary configuration

If you encounter a message on the dashboard indicating that your data is unavailable due to your account's Metadata Boundary configuration, this is because you are trying to access data that is not stored in your region (that is, you are in the US and trying to access data that is only stored in the EU, or vice versa). If you receive this error message while being in the region where your data is stored, there are two potential reasons why you might get this message:

- Your account has Customer Metadata Boundary (CMB) enabled, and your request is being directed to an incorrect region. For example, if you are in the EU and CMB is configured to store your data in the US.
- If you are trying to access your data from the correct region, such as being in the EU with CMB configured to save your data in the EU, the issue may be caused by network congestion. Typically, this problem resolves within a few minutes.

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/graphql-api/getting-started/#page","headline":"Get started","description":"Set up and access Network Analytics.","url":"https://developers.cloudflare.com/analytics/graphql-api/getting-started/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/graphql-api/getting-started/og.png?v=bc12057ae3200e6d","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Authenticate requests to the GraphQL Analytics API.
title: Authentication
image: https://developers.cloudflare.com/analytics/graphql-api/getting-started/authentication/og.png?v=e7e60ae9a0f67286
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Authentication

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/graphql-api/getting-started/authentication/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

Cloudflare separates service configuration by zone. When there are multiple accounts, each with many zones, it is important to restrict GraphQL Analytics API access to only those account and zone resources that are relevant for the task at hand.

To secure access to your GraphQL Analytics data, use a Cloudflare API key or token to authenticate an API request.

This table outlines the differences between Cloudflare API keys and tokens:

| Authentication Method | Description |
| --- | --- |
| [API Tokens](https://developers.cloudflare.com/fundamentals/api/get-started/create-token/) | Cloudflare recommends API Tokens as the preferred way to interact with Cloudflare APIs. You can configure the scope of tokens to limit access to account and zone resources, and you can define the Cloudflare APIs to which the token authorizes access. |
| [API Keys](https://developers.cloudflare.com/fundamentals/api/get-started/keys/) | Unique to each Cloudflare user and used only for authentication. API keys do not authorize access to accounts or zones. Use the Global API Key for authentication. |

To create and configure GraphQL Analytics API tokens, refer to [Configure an Analytics API token](https://developers.cloudflare.com/analytics/graphql-api/getting-started/authentication/api-token-auth/).

To find and retrieve API keys, as well as edit HTTP headers for authentication in GraphiQL, refer to [Authenticate with a Cloudflare API key](https://developers.cloudflare.com/analytics/graphql-api/getting-started/authentication/api-key-auth/).

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/graphql-api/getting-started/authentication/#page","headline":"Authentication","description":"Authenticate requests to the GraphQL Analytics API.","url":"https://developers.cloudflare.com/analytics/graphql-api/getting-started/authentication/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/graphql-api/getting-started/authentication/og.png?v=e7e60ae9a0f67286","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Learn about authenticate with a cloudflare api key in Cloudflare analytics.
title: Authenticate with a Cloudflare API key
image: https://developers.cloudflare.com/analytics/graphql-api/getting-started/authentication/api-key-auth/og.png?v=4e2c7232ab659181
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Authenticate with a Cloudflare API key

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/graphql-api/getting-started/authentication/api-key-auth/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

API keys are unique to each Cloudflare user and used only for authentication. An API key does not authorize access to accounts or zones. To ensure that the GraphQL Analytics API authenticates your queries, retrieve your Cloudflare Global API Key.

Learn how to [retrieve your API Key in the Cloudflare dashboard](https://developers.cloudflare.com/fundamentals/api/get-started/keys/).

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/graphql-api/getting-started/authentication/api-key-auth/#page","headline":"Authenticate with a Cloudflare API key","description":"Learn about authenticate with a cloudflare api key in Cloudflare analytics.","url":"https://developers.cloudflare.com/analytics/graphql-api/getting-started/authentication/api-key-auth/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/graphql-api/getting-started/authentication/api-key-auth/og.png?v=4e2c7232ab659181","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Learn about configure an analytics api token in Cloudflare analytics.
title: Configure an Analytics API token
image: https://developers.cloudflare.com/analytics/graphql-api/getting-started/authentication/api-token-auth/og.png?v=e2aae02de07bf1c2
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Configure an Analytics API token

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/graphql-api/getting-started/authentication/api-token-auth/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

Cloudflare recommends API tokens as the preferred authentication method with Cloudflare APIs. This article walks through creating API tokens for authentication to the GraphQL Analytics API.

For more details on API tokens and the full range of supported options, refer to [Creating API tokens](https://developers.cloudflare.com/fundamentals/api/get-started/create-token/).

To create an API token for authentication to the GraphQL Analytics API, use this workflow:

- [Access the Create API Token page](#access-the-create-api-token-page)
- [Configure a custom API token](#configure-a-custom-api-token)
- [Review and create your API token](#review-and-create-your-api-token)
- [Copy and test your API token](#copy-and-test-your-api-token)

## Access the Create API Token page

1. In the Cloudflare dashboard, go to the **Account API tokens** page. [Go to **Account API tokens** ↗](https://dash.cloudflare.com/?to=/:account/api-tokens)
2. Select **Create Token**.

![API Tokens tab](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=752,height=592,format=webp/_astro/user-profile-api-tokens-tab.Cfjm5UAa.png)

The **Create API Token** page displays.

![Clicking Get started in the Create API Token page](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=701,height=723,format=webp/_astro/create-api-token-page-display.DTQbXvJf.png)

The next section of this walkthrough shows you how to configure a custom token for access to the GraphQL Analytics API.

## Configure a custom API token

To configure a custom token, follow these steps:

1. Select **Get started** in the **Custom token** section of the **Create API Token** page:

![Clicking Get started in the Create API Token page](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=701,height=147,format=webp/_astro/create-api-token-get-started.BaVcSeWC.png)

The **Create Custom Token** page displays:

![Create Custom Token page](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=944,height=1022,format=webp/_astro/create-custom-api-token.CFX0TYIj.png)

2. Enter a descriptive name for your token in the **Token name** text input field.
3. To configure access to the GraphQL Analytics API, use the **Permissions** drop-down lists.
4. To set permissions for the GraphQL Analytics API, select *Account* in the first drop-down list, *Account Analytics* from the second drop-down list, and *Read* from the third.

This example scopes account-level permissions for read access to the Analytics API:

![Permissions configuration page](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=1226,height=200,format=webp/_astro/create-custom-token-permissions.C95JIEHR.png)

5. To configure the specific zones to which the token grants access, use the **Zone Resources** drop-down lists. In this example, the token is set to grant access to all zones:

![Resources configuration page](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=603,height=100,format=webp/_astro/create-custom-token-zone-resources.CfSpKkcP.png)

6. To restrict the API token to specific IP addresses, use the **Client IP Address Filtering** controls.

![IP Address Filtering configuration page](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=1218,height=262,format=webp/_astro/create-custom-token-ip-address-filtering.X4iaKSyi.png)

7. To define how long the token is valid, select the **TTL** (time-to-live) start/end date.

![TTL configuration page](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=734,height=104,format=webp/_astro/create-custom-token-ttl.Bo81ViQe.png)

8. Select **Continue to summary**.

The next section of this walkthrough covers how to review and test your API token.

## Review and create your API token

Once you select **Continue to summary**, the **API Token Summary** page displays.

Use the **API Token Summary** to confirm that you have scoped the API Token to the desired permissions and resources before creating it.

![API Token Summary page](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=580,height=336,format=webp/_astro/api-token-summary.BcCShVRo.png)

Once you have validated your API token configuration, select **Create Token**.

## Copy and test your API token

When you create a new token, a confirmation page displays that includes your token and a custom `curl` command.

![Page displaying your API token and the curl command to test your token](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=1204,height=940,format=webp/_astro/token-complete.Dg4S1W72.png)

To copy the token to your device's clipboard, select the **Copy** button.

Warning

The token displays only on the confirmation page, so copy the token and store it safely, since anyone who has the token can use it to access your data.

If you lose the token, you can [regenerate it from the API Tokens page](https://developers.cloudflare.com/fundamentals/api/get-started/create-token/), so that you do not have to configure all the permissions again.

To test your token, copy the `curl` command and paste it into a terminal.

When you have finished, select **View all API tokens**.

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/graphql-api/getting-started/authentication/api-token-auth/#page","headline":"Configure an Analytics API token","description":"Learn about configure an analytics api token in Cloudflare analytics.","url":"https://developers.cloudflare.com/analytics/graphql-api/getting-started/authentication/api-token-auth/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/graphql-api/getting-started/authentication/api-token-auth/og.png?v=e2aae02de07bf1c2","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Learn about configure graphql client endpoint and http headers in Cloudflare analytics.
title: Configure GraphQL client endpoint and HTTP headers
image: https://developers.cloudflare.com/analytics/graphql-api/getting-started/authentication/graphql-client-headers/og.png?v=c3d2471856d03c00
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Configure GraphQL client endpoint and HTTP headers

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/graphql-api/getting-started/authentication/graphql-client-headers/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

1. Launch [GraphiQL ↗︎](https://www.gatsbyjs.com/docs/how-to/querying-data/running-queries-with-graphiql/).
2. Select **Edit HTTP Headers**. ![Clicking Edit HTTP Headers](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=1018,height=721,format=webp/_astro/GraphiQL-edit-http-headers.Cc0SaBrH.png) The **Edit HTTP Headers** window appears. ![Editing HTTP Headers Window](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=921,height=212,format=webp/_astro/GraphiQL-edit-http-headers-window.D6rNIUCL.png)
3. Select **Add Header** to configure authentication. You can use Cloudflare Analytics API token authentication (recommended) or Cloudflare API key authentication.
   - **Token authentication**:

     Enter **Authorization** in the **Header Name** field, and enter `Bearer {your-analytics-token}` in the **Header value** field, then select **Save**.![Editing HTTP Headers](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=606,height=148,format=webp/_astro/GraphiQL-edit-http-headers-token.BRr3JTFE.png)
   - **Key authentication**:

     Enter `X-AUTH-EMAIL` in the **Header name** field and your email address registered with Cloudflare in the **Header value** field, and select **Save**.  

     Select **Add Header** to add a second header. Enter `X-AUTH-KEY` in the **Header Name** field, and paste your Global API Key in the **Header value** field, then select **Save**.  
4. Select anywhere outside the **Edit HTTP Headers** window in GraphiQL to close it and return to the main GraphiQL display.
5. Enter `https://api.cloudflare.com/client/v4/graphql` in the **GraphQL Endpoint** field. ![Editing GraphQL Endpoint](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=1007,height=712,format=webp/_astro/GraphiQL-response-pane.jm8FGlXL.png)

Note

The right-side response pane is empty when you enter your information correctly. An error displays when there are problems with your header credentials.

Now that you have configured authentication, you are ready to run queries using GraphiQL.

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/graphql-api/getting-started/authentication/graphql-client-headers/#page","headline":"Configure GraphQL client endpoint and HTTP headers","description":"Learn about configure graphql client endpoint and http headers in Cloudflare analytics.","url":"https://developers.cloudflare.com/analytics/graphql-api/getting-started/authentication/graphql-client-headers/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/graphql-api/getting-started/authentication/graphql-client-headers/og.png?v=c3d2471856d03c00","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Learn how to use a GraphiQL client to compose and execute a GraphQL query. This guide covers setting up a query, selecting the dataset, and configuring parameters and fields.
title: Compose a query in GraphiQL
image: https://developers.cloudflare.com/analytics/graphql-api/getting-started/compose-graphql-query/og.png?v=5bec0e950a04fec8
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Compose a query in GraphiQL

Last updated Aug 25, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/graphql-api/getting-started/compose-graphql-query/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

Many clients might need help using [the semantics](https://developers.cloudflare.com/analytics/graphql-api/getting-started/querying-basics/) of GraphQL and exploring the possibilities of Cloudflare GraphQL API.

This page details how to use a [GraphiQL client ↗︎](https://github.com/graphql/graphiql/tree/main/packages/graphiql#readme) to compose and execute a GraphQL query.

## Prerequisites

You can find all details on how to [configure](https://developers.cloudflare.com/analytics/graphql-api/getting-started/authentication/graphql-client-headers/) a client here.

## Set up a query and choose a dataset

Click on the editing pane of GraphiQL and add this base query, replacing `zone-id` with your Cloudflare zone ID:

![Adding a base query in the GraphiQL pane](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=623,height=217,format=webp/_astro/graphiql-base-query.fKm6YnqW.png)

Note

To find the zone's tag, log in to your Cloudflare account and select the site for which you want to obtain the tag. In the Cloudflare dashboard **Overview** page, scroll to the **API** section in the right sidebar, which displays your zone and account tags.

To assist query building, the GraphiQL client has word completion. Insert your cursor in the query, in this case on the line below `zones`, and start entering a value to engage the feature. For example, when you type `firewall`, a popup menu displays the datasets that return firewall information:

![GraphiQL word completion assistant to query building](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=624,height=285,format=webp/_astro/graphiql-word-completion.iSRM-VK6.png)

The text at the bottom of the list displays a short description of the data that the node returns.

Select the dataset you want to query and insert it. Either select the item in the list, or scroll using arrow keys and press the `Return` key.

## Supply required parameters

Hover your mouse over a field to display a tooltip that describes the dataset. In this example, hovering over the `firewallEventsAdaptive` node displays this description:

![Hovering the mouse over a field to display its description](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=619,height=223,format=webp/_astro/graphiql-set-up-base-query.1fPWncy2.png)

To display information about the dataset, including required parameters, select the dataset name (blue text). The **Documentation Explorer** opens and displays details about the dataset:

![Documentation Explorer window displaying dataset details](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=396,height=320,format=webp/_astro/graphiql-parameters.CM7npJ7C.png)

Note that the `filter` and `limit` arguments are required, as indicated by the exclamation mark (`!`) after their type definitions (gold text). In this example, the `orderBy` argument is not required, though when used it requires a value of type `ZoneFirewallEventsAdaptiveOrderBy`.

To browse a list of supported filter fields, select the filter type definition (gold text) in the Documentation Explorer. In this example, the type is `ZoneFirewallEventsAdaptiveFilter_InputObject`:

![Browsing GraphiQL filter fields](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=392,height=538,format=webp/_astro/graphiql-filter-fields.DeLcvFBV.png)

This example query shows the required `filter` and `limit` arguments for `firewallEventsAdaptive` (as well as for the rest of GraphQL nodes):

![Example of GraphiQL query arguments](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=614,height=279,format=webp/_astro/graphiql-filter-values.vYQN7N4B.png)

## Define the fields used by your query

To browse the fields you can use with your query, hover your cursor over the dataset name in your query, and in the tooltip that displays, select the data type definition (gold text):

![Hovering the mouse over a dataset to display available fields](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=619,height=223,format=webp/_astro/graphiql-set-up-base-query.1fPWncy2.png)

**The Documentation Explorer** opens and displays a list of fields:

![Documentation Explorer window displaying list of fields](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=391,height=575,format=webp/_astro/graphiql-return-fields.DaJ56iiT.png)

To add the data fields that you want to read, type an opening brace (`{`) after the closing parenthesis for the parameters, then start typing the name of a field that you want to fetch. Use word completion to choose a field.

This example query returns the `action`, `datetime`, `clientRequestHTTPHost`, and `userAgent` fields:

![Example query with return fields](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=592,height=388,format=webp/_astro/graphiql-query-return-field-values.D6RsP235.png)

Once you have entered all the fields you want to query, select the **Play** button to submit the query. The response pane will contain the data fetched from the configured GraphQL API endpoint:

![GraphiQL response pane](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=608,height=346,format=webp/_astro/create-query-fw-data-set-play.dQ7w2sGu.png)

## Variable substitution

The GraphiQL client allows you to use placeholders for value and supply them via the `variables` part of the payload.

Placeholder names should start with `$` character, and you do not need to wrap placeholders in quotes when you use them in the query.

Values for placeholders should be provided in JSON format, in which placeholders are addressed without `$` character. As an example, for a placeholder `$zoneTag` GraphQL API will read a value from the `zoneTag` field of supplied variables object.

To supply a value for a placeholder, select the **Query Variables** pane and edit a JSON object that defines your variables.

This example query uses the `zoneTag` query variable to represent the zone ID:

![Example of GraphiQL query variables](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=631,height=461,format=webp/_astro/graphiql-query-variables.D9uAtvLs.png)

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/graphql-api/getting-started/compose-graphql-query/#page","headline":"Compose a query in GraphiQL","description":"Learn how to use a GraphiQL client to compose and execute a GraphQL query. This guide covers setting up a query, selecting the dataset, and configuring parameters and fields.","url":"https://developers.cloudflare.com/analytics/graphql-api/getting-started/compose-graphql-query/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/graphql-api/getting-started/compose-graphql-query/og.png?v=5bec0e950a04fec8","dateModified":"2026-08-25","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Learn about execute a graphql query with curl in Cloudflare analytics.
title: Execute a GraphQL query with curl
image: https://developers.cloudflare.com/analytics/graphql-api/getting-started/execute-graphql-query/og.png?v=fc778c5f38caf70e
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Execute a GraphQL query with curl

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/graphql-api/getting-started/execute-graphql-query/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

Using a plain curl to send a query provides the ability to slice-n-dice with the results and apply post-processing if needed. For example, converting results received from GraphQL API into a CSV format.

For more functionality, like auto-completion, schema exploring, etc., you can look at GraphQL [clients](https://developers.cloudflare.com/analytics/graphql-api/getting-started/compose-graphql-query/).

GraphQL API expects JSON with two essentials fields: "query" and "variables".

A query should be stripped from newline symbols and sent as a single-line string when the variables is an object full of values for all placeholders used in the query:

*A payload structure for GraphQL APIjson*

```json
{
  "query": "{viewer { ... }}",
  "variables": {}
}
```

It is still possible to use a human-friendly query though. In the example below you can see how `echo` piped together with `tr` to provide a proper payload with `curl`:

*Example bash script that uses curl to query Analytics APIbash*

```bash
echo '{ "query":
  "{
    viewer {
      zones(filter: { zoneTag: $zoneTag }) {
        firewallEventsAdaptive(
          filter: $filter
          limit: 10
          orderBy: [datetime_DESC]
        ) {
          action
          clientAsn
          clientCountryName
          clientIP
          clientRequestPath
          clientRequestQuery
          datetime
          source
          userAgent
        }
      }
    }
  }",
  "variables": {
    "zoneTag": "<zone-tag>",
    "filter": {
      "datetime_geq": "2022-07-24T11:00:00Z",
      "datetime_leq": "2022-07-24T12:00:00Z"
    }
  }
}' | tr -d '\n' | curl --silent \
https://api.cloudflare.com/client/v4/graphql \
--header "Authorization: Bearer <API_TOKEN>" \
--header "Content-Type: application/json" \
--data @-
```

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/graphql-api/getting-started/execute-graphql-query/#page","headline":"Execute a GraphQL query with curl","description":"Learn about execute a graphql query with curl in Cloudflare analytics.","url":"https://developers.cloudflare.com/analytics/graphql-api/getting-started/execute-graphql-query/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/graphql-api/getting-started/execute-graphql-query/og.png?v=fc778c5f38caf70e","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Browse available datasets and fields via introspection.
title: Explore the GraphQL schema
image: https://developers.cloudflare.com/analytics/graphql-api/getting-started/explore-graphql-schema/og.png?v=5909fc7b082a45cb
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Explore the GraphQL schema

Last updated Aug 25, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/graphql-api/getting-started/explore-graphql-schema/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

Many GraphQL clients support browsing the GraphQL schema by taking care of [introspection](https://developers.cloudflare.com/analytics/graphql-api/features/discovery/introspection/). In this page, we will cover GraphiQL and Altair clients.

[GraphiQL ↗︎](https://github.com/graphql/graphiql/tree/main/packages/graphiql#readme) and [Altair ↗︎](https://altairgraphql.dev/#download) are open-source GraphQL clients that provide a tool to compose a query, execute it, and inspect the results. And as a bonus, they also allow you to browse GraphQL schema.

## Prerequisites

Before you begin, do not forget to [configure](https://developers.cloudflare.com/analytics/graphql-api/getting-started/authentication/graphql-client-headers/) the API endpoint and HTTP headers.

The screenshots below are done from GraphiQL. However, Altair provides the same functionality and you will not find any difficulties following the same instructions to explore the schema.

## Open the Documentation Explorer

To open the GraphiQL Documentation Explorer, select the **Docs** link in the header of the response pane:

![Clicking GraphiQL Docs link to open Documentation Explorer](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=870,height=622,format=webp/_astro/graphiql-docs-link.EkyLJzjS.png)

The **Documentation Explorer** opens and displays a list of available objects:

![GraphiQL Doc Explorer pane](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=1026,height=586,format=webp/_astro/graphiql-doc-explorer.Bd9kpJrN.png)

Objects in the **Documentation Explorer** use this syntax:

```txt
  object-name: object-type-definition
```

## Find the type definition of an object

When you first open the **Documentation Explorer** pane, the `mutation` and `query` root types display:

![Documentation Explorer displaying mutation and query nodes](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=383,height=270,format=webp/_astro/graphiql-doc-explorer-query-mutations.BbRcxejs.png)

In this example, `query` is the name of a root, and `Query` is the type definition.

## Find the fields available for a type definition

Click on the **type definition** of a node to view the fields that it provides. The **Documentation Explorer** also displays descriptions of the nodes.

For example, select the **Query** type definition. The **Documentation Explorer** displays the fields that `Query` provides. In this example, the fields are `cost` and `viewer`:

![Documentation Explorer displaying cost and viewer fields](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=388,height=237,format=webp/_astro/graphiql-doc-explorer-view-cost.CT9nC44o.png)

To explore the schema, select the names of objects and definitions. You can also use the search input (magnifying glass icon) and breadcrumb links in the header.

## Find the arguments associated with a field

Click the type definition of the `viewer` field (gold text) to list its sub-fields. The `viewer` field provides sub-fields that allow you to query `accounts` or `zones` data:

![Displaying viewer fields](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=392,height=274,format=webp/_astro/graphiql-doc-explorer-viewer-fields.BKFriIIB.png)

The `accounts` and `zones` nodes take arguments to specify which dataset to query.

For example, `zones` can take a filter of `ZoneFilter_InputObject` type as an argument. To view the fields available to filter, select **ZoneFilter\_InputObject**.

## Find the datasets available for a zone

To view a list of the datasets available to query, select the **zone** type definition (gold text):

![Clicking zone type definition](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=389,height=136,format=webp/_astro/graphiql-doc-explorer-zones.DMRVzjxA.png)

A list of datasets displays in the **Fields** section, each with list of valid arguments and a brief description. Arguments that end with an exclamation mark (`!`) are required.

![Fields section displaying datasets available](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=464,height=535,format=webp/_astro/graphiql-doc-explorer-zone-fields.OMeSzfCd.png)

Use the search input (magnifying glass icon) to find specific datasets:

![Searching a dataset in the Documentation Explorer](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=460,height=566,format=webp/_astro/graphiql-doc-explorer-find-firewall.CkSNHI_E.png)

To select a dataset, select its name.

The definition for the dataset displays. This example shows the `firewallEventsAdaptive` dataset:

![Example of a dataset definition](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=463,height=334,format=webp/_astro/graphiql-doc-explorer-firewallevents-definition.CsFujHwT.png)

## Find the fields available for a dataset

To view the fields available for a particular dataset, select on its type definition (gold text).

For example, select the **ZoneFirewallEventsAdaptive** type definition to view the fields available for the `firewallEventsAdaptive` dataset:

![Clicking type definition to visualize fields available for a dataset](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=460,height=185,format=webp/_astro/graphiql-doc-explorer-firewall-type-definition.CKad-SDm.png)

The list of fields displays:

![Displaying available fields for a dataset](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=461,height=579,format=webp/_astro/graphiql-doc-explorer-firewall-fields.K45OyD1Z.png)

For more information on using GraphiQL, please visit this [guide](https://developers.cloudflare.com/analytics/graphql-api/getting-started/compose-graphql-query/).

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/graphql-api/getting-started/explore-graphql-schema/#page","headline":"Explore the GraphQL schema","description":"Browse available datasets and fields via introspection.","url":"https://developers.cloudflare.com/analytics/graphql-api/getting-started/explore-graphql-schema/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/graphql-api/getting-started/explore-graphql-schema/og.png?v=5909fc7b082a45cb","dateModified":"2026-08-25","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Learn the basics of querying with Cloudflare's GraphQL API. Understand query structure, schema, and how to fetch data using GraphQL queries.
title: Querying basics
image: https://developers.cloudflare.com/analytics/graphql-api/getting-started/querying-basics/og.png?v=5398e23385a68c54
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Querying basics

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/graphql-api/getting-started/querying-basics/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

## Structure of a GraphQL query

GraphQL structures data as a graph. GraphQL uses a schema to define the objects and their hierarchy in your data graph. You can explore the edges of the graph by using queries to get the needed data. These queries must respect the structure of the schema.

A **node**, followed by its **fields**, is at the core of a GraphQL query. A node is an object of a specific **type**; the type specifies the fields that make up the object.

A field can be another node where the appropriate query would contain nested elements. Some nodes look like functions that can take on arguments to limit the scope of what they can act on. You can apply filters at each node.

## Cloudflare GraphQL schema

A typical query against the Cloudflare GraphQL schema is made up of four main components:

- `viewer` - is the root node,
- `zones` or `accounts` - indicate the scope of the query, that is the domain area or account you want to query. The `viewer` can access one `zones` or `accounts`, or both,
- **data node** or **dataset** - represent the data you want to query. `zones` or `accounts` may contain one or more datasets. To find out more about discovering nodes, please refer to [introspection](https://developers.cloudflare.com/analytics/graphql-api/features/discovery/introspection/),
- **fieldset** - a set of fields or nested fields of the **dataset**.

The query to Cloudflare GraphQL API must be sent over HTTP POST request with payload in JSON format that consists of these fields:

```json
{
	"query": "",
	"variables": {}
}
```

From the above structure, the `query` field must contain a GraphQL query formatted as a **single line** string (meaning all newline symbols should be stripped / escaped), when `variables` is an object that contains all values of used placeholders in the query itself.

## A single dataset example

In the following example, the GraphQL query fetches a `datetime`, `action`, and client request HTTP host as `host` field of 2 WAF events from zone-scoped `firewallEventsAdaptive` dataset.

*A GraphQL querygraphql*

```graphql
query ASingleDatasetExample($zoneTag: string, $start: Time, $end: Time) {
	viewer {
		zones(filter: { zoneTag: $zoneTag }) {
			firewallEventsAdaptive(
				filter: { datetime_gt: $start, datetime_lt: $end }
				limit: 2
				orderBy: [datetime_DESC]
			) {
				action
				datetime
				host: clientRequestHTTPHost
			}
		}
	}
}
```

In the query above, we have variable placeholders: $zoneTag, $start, and $end. We provide values for those placeholders alongside the query by placing them into `variables` field of the payload. Note that the examples below use the UTC timezone, indicated by the letter "Z".

*A set of variablesjson*

```json
{
	"zoneTag": "<zone-tag>",
	"start": "2020-08-03T02:07:05Z",
	"end": "2020-08-03T17:07:05Z"
}
```

There are multiple ways to send your query to Cloudflare GraphQL API. You can use you favourite GraphQL client or CLI to send a request via curl. We have a [how-to guide](https://developers.cloudflare.com/analytics/graphql-api/getting-started/compose-graphql-query/) about using GraphiQL client, also check a guide on how to execute a query with a curl [here](https://developers.cloudflare.com/analytics/graphql-api/getting-started/execute-graphql-query/).

*A sample of a response for a query abovejson*

```json
{
	"data": {
		"viewer": {
			"zones": [
				{
					"firewallEventsAdaptive": [
						{
							"action": "log",
							"host": "cloudflare.guru",
							"datetime": "2020-08-03T17:07:03Z"
						},
						{
							"action": "log",
							"host": "cloudflare.guru",
							"datetime": "2020-08-03T17:07:01Z"
						}
					]
				}
			]
		}
	},
	"errors": null
}
```

## Query multiple datasets in a single GraphQL API request

As previously mentioned, a query might contain one or multiple nodes (datasets). At the API level, the data extraction would be done simultaneously, but the response would be delayed until all dataset queries got their results. If any fails during the execution, the entire query will be terminated, and the error will be returned.

*A sample query for two datasets in a one gographql*

```graphql
query MultipleDatasetsExample(
	$zoneTag: string
	$start: Time
	$end: Time
	$ts: Date
) {
	viewer {
		zones(filter: { zoneTag: $zoneTag }) {
			last10Events: firewallEventsAdaptive(
				filter: { datetime_gt: $start, datetime_lt: $end }
				limit: 10
				orderBy: [datetime_DESC]
			) {
				action
				datetime
				host: clientRequestHTTPHost
			}
			top3DeviceTypes: httpRequestsAdaptiveGroups(
				filter: { date: $ts }
				limit: 10
				orderBy: [count_DESC]
			) {
				count
				dimensions {
					device: clientDeviceType
				}
			}
		}
	}
}
```

*A set of variables for the query abovejson*

```json
{
	"zoneTag": "<zone-tag>",
	"start": "2022-10-02T00:26:49Z",
	"end": "2022-10-04T14:26:49Z",
	"ts": "2022-10-04"
}
```

*A sample response for the query with variables abovejson*

```json
{
	"data": {
		"viewer": {
			"zones": [
				{
					"last10Events": [
						{
							"action": "block",
							"country": "TR",
							"datetime": "2022-10-04T08:41:09Z"
						},
						{
							"action": "block",
							"country": "TR",
							"datetime": "2022-10-04T08:41:09Z"
						},
						{
							"action": "block",
							"country": "RU",
							"datetime": "2022-10-04T01:09:36Z"
						},
						{
							"action": "block",
							"country": "US",
							"datetime": "2022-10-03T14:26:49Z"
						},
						{
							"action": "block",
							"country": "US",
							"datetime": "2022-10-03T14:26:46Z"
						},
						{
							"action": "block",
							"country": "CN",
							"datetime": "2022-10-02T23:51:26Z"
						},
						{
							"action": "block",
							"country": "TR",
							"datetime": "2022-10-02T23:39:41Z"
						},
						{
							"action": "block",
							"country": "TR",
							"datetime": "2022-10-02T23:39:41Z"
						}
					],
					"top3DeviceTypes": [
						{
							"count": 4580,
							"dimensions": {
								"device": "desktop"
							}
						}
					]
				}
			]
		}
	},
	"errors": null
}
```

## Helpful Resources

Here are some helpful articles about working with the Cloudflare Analytics API and GraphQL.

### Cloudflare specific

- [How to find your zoneTag using the API](https://developers.cloudflare.com/fundamentals/account/find-account-and-zone-ids/)

### General info on the GraphQL framework

- [How to use GraphQL (tutorials) ↗︎](https://www.howtographql.com/)
- [Thinking in Graphs ↗︎](https://graphql.org/learn/thinking-in-graphs/)
- [What data can you can query in the GraphQL type system (schemas) ↗︎](https://graphql.org/learn/schema/)
- [How to pass variables in GraphiQL (Medium article with quick tips) ↗︎](https://medium.com/graphql-mastery/graphql-quick-tip-how-to-pass-variables-into-a-mutation-in-graphiql-23ecff4add57)

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/graphql-api/getting-started/querying-basics/#page","headline":"Querying basics","description":"Learn the basics of querying with Cloudflare's GraphQL API. Understand query structure, schema, and how to fetch data using GraphQL queries.","url":"https://developers.cloudflare.com/analytics/graphql-api/getting-started/querying-basics/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/graphql-api/getting-started/querying-basics/og.png?v=5398e23385a68c54","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Review GraphQL Analytics API query limits.
title: Limits
image: https://developers.cloudflare.com/analytics/graphql-api/limits/og.png?v=decb1da875bf878f
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Limits

Last updated Oct 2, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/graphql-api/limits/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

Cloudflare GraphQL API exposes more than 70 datasets representing products with different configurations and data availability for different zones and accounts plans.

To support this variety of products, Cloudflare GraphQL API has three layers of limits:

- global limits
- user limits
- node (dataset) limits

## Global limits

These limits are applied to every query for every plan:

- A zone-scoped query can include up to **10 zones**
- An account-scoped query can include only **1 account**

Additionally, there is a limited number of queries you can make per request. The total number of queries in a request is equal to the number of zone/account scopes, multiplied by the number of nodes to which they are applied.

## User limits

Cloudflare GraphQL API limits the number of GraphQL requests each user can send. The default quota is **300 GraphQL queries over 5-minute window**. It allows a user to run at least **1 query every second** or do a burst of 300 queries and then wait 5 minutes before issuing another query.

That rate limit is applied in addition to the [general rate limits enforced by the Cloudflare API](https://developers.cloudflare.com/fundamentals/api/reference/limits/).

### Account-based rate limiting

If you query analytics across many zones or accounts, you can opt into **account-based rate limiting**, where limits apply per account and per zone instead of per user or API token. Because each account and zone has its own budget, a single user or token can make far more requests overall, and limit increases can be applied per resource and take effect quickly.

To learn how to enable it and the query requirements, refer to [Account-based rate limiting](https://developers.cloudflare.com/analytics/graphql-api/account-based-rate-limiting/).

## Node limits and availability

Each data node has its limits, such as:

- how far back in time can data be requested,
- the maximum time period (in seconds) that can be requested in one query,
- the maximum number of fields that can be requested in one query,
- the maximum number of records that can be returned in one query.

Node limits are tied to requested `zoneTag` or `accountTag`. Higher plans have access to a greater selection of datasets or fields, and can query over broader historical intervals.

Adaptive datasets, such as `httpRequestsAdaptiveGroups` and `firewallEventsAdaptive`, retain at least 31 days of data on every plan. Aggregated datasets, such as `httpRequests1hGroups`, keep their own per-plan limits.

To get exact boundaries and availability for your zone(s) or account, please refer to [settings](https://developers.cloudflare.com/analytics/graphql-api/features/discovery/settings/).

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/graphql-api/limits/#page","headline":"Limits","description":"Review GraphQL Analytics API query limits.","url":"https://developers.cloudflare.com/analytics/graphql-api/limits/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/graphql-api/limits/og.png?v=decb1da875bf878f","dateModified":"2026-10-02","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Migrate from deprecated analytics APIs to GraphQL.
title: Migration guides
image: https://developers.cloudflare.com/analytics/graphql-api/migration-guides/og.png?v=95846548d5a0034e
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Migration guides

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/graphql-api/migration-guides/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

## GraphQL migrations

If you are currently using the deprecated `httpRequests1mByColoGroups` or `httpRequests1dByColoGroups` GraphQL API nodes, the [HTTP Requests by Colo Groups to HTTP Requests by Adaptive Groups](https://developers.cloudflare.com/analytics/graphql-api/migration-guides/graphql-api-analytics/) guide will help you migrate your queries to use the `httpRequestsAdaptiveGroups` node.

## Zone Analytics migrations

If you are currently using the Zone Analytics API, the following guide will help you migrate your queries to the new GraphQL Analytics API:

- [Zone Analytics to GraphQL Analytics](https://developers.cloudflare.com/analytics/graphql-api/migration-guides/zone-analytics/)
- [Zone Analytics Colos Endpoint to GraphQL Analytics](https://developers.cloudflare.com/analytics/graphql-api/migration-guides/zone-analytics-colos/)

## Network Analytics migrations

If you are currently using the Network Analytics v1 (NAv1) GraphQL nodes, the [Network Analytics v1 to Network Analytics v2](https://developers.cloudflare.com/analytics/graphql-api/migration-guides/network-analytics-v2/) guide will help you migrate your queries to the new Network Analytics v2.

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"WebPage","@id":"https://developers.cloudflare.com/analytics/graphql-api/migration-guides/#page","headline":"Migration guides","description":"Migrate from deprecated analytics APIs to GraphQL.","url":"https://developers.cloudflare.com/analytics/graphql-api/migration-guides/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/graphql-api/migration-guides/og.png?v=95846548d5a0034e","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Migrate colo groups queries to adaptive groups.
title: HTTP Requests by Colo Groups to HTTP Requests by Adaptive Groups
image: https://developers.cloudflare.com/analytics/graphql-api/migration-guides/graphql-api-analytics/og.png?v=9a7bc6b91c4688b7
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# HTTP Requests by Colo Groups to HTTP Requests by Adaptive Groups

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/graphql-api/migration-guides/graphql-api-analytics/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

This guide shares considerations when migrating from the deprecated `httpRequests1mByColoGroups` and `httpRequests1dByColoGroups` GraphQL API nodes to the `httpRequestsAdaptiveGroups` GraphQL API node.

For example, if you wanted to see which five data centers had the most number of requests, the total number of those requests, and the total amount of data transfer, in the past you used the `httpRequests1mByColoGroups` GraphQL API node as in the following example:

```graphql
{
	viewer {
		zones(filter: { zoneTag: $zoneTag }) {
			series: httpRequests1mByColoGroups(
				limit: 5
				orderBy: [sum_requests_DESC]
				filter: { datetime_geq: $start, datetime_lt: $end }
			) {
				sum {
					requests
					bytes
				}
				dimensions {
					coloCode
				}
			}
		}
	}
}
```

<details>

<summary>

Response

</summary>

```json
{
	"data": {
		"viewer": {
			"zones": [
				{
					"series": [
						{
							"dimensions": {
								"coloCode": "LHR"
							},
							"sum": {
								"bytes": 18260055,
								"requests": 4404
							}
						},
						{
							"dimensions": {
								"coloCode": "AMS"
							},
							"sum": {
								"bytes": 17563009,
								"requests": 4302
							}
						},
						{
							"dimensions": {
								"coloCode": "CDG"
							},
							"sum": {
								"bytes": 17200434,
								"requests": 4032
							}
						},
						{
							"dimensions": {
								"coloCode": "PTY"
							},
							"sum": {
								"bytes": 10400209,
								"requests": 2707
							}
						},
						{
							"dimensions": {
								"coloCode": "JIB"
							},
							"sum": {
								"bytes": 9040105,
								"requests": 2601
							}
						}
					]
				}
			]
		}
	},
	"errors": null
}
```

</details>

## `httpRequestsAdaptiveGroups` GraphQL API node

With the deprecation of the `httpRequests1mByColoGroups` and `httpRequests1dByColoGroups` GraphQL API nodes, use the `httpRequestsAdaptiveGroups` GraphQL API node to access the same data (`count`, `sum(edgeResponseBytes)`, and `visits`).

**Request**

```graphql
query MigrationSample($zoneTag: string, $start: Time, $end: Time) {
	viewer {
		zones(filter: { zoneTag: $zoneTag }) {
			series: httpRequestsAdaptiveGroups(
				limit: 5
				orderBy: [count_DESC]
				filter: {
					datetime_geq: $start
					datetime_lt: $end
					requestSource: "eyeball"
				}
			) {
				count
				avg {
					sampleInterval
				}
				sum {
					visits
					edgeResponseBytes
				}
				dimensions {
					coloCode
				}
			}
		}
	}
}
```

<details>

<summary>

Response

</summary>

```json
{
	"data": {
		"viewer": {
			"zones": [
				{
					"series": [
						{
							"avg": {
								"sampleInterval": 10
							},
							"count": 4350,
							"dimensions": {
								"coloCode": "LHR"
							},
							"sum": {
								"edgeResponseBytes": 17860000,
								"visits": 4120
							}
						},
						{
							"avg": {
								"sampleInterval": 10
							},
							"count": 4210,
							"dimensions": {
								"coloCode": "AMS"
							},
							"sum": {
								"edgeResponseBytes": 17110000,
								"visits": 3910
							}
						},
						{
							"avg": {
								"sampleInterval": 10
							},
							"count": 3890,
							"dimensions": {
								"coloCode": "CDG"
							},
							"sum": {
								"edgeResponseBytes": 17050000,
								"visits": 3700
							}
						},
						{
							"avg": {
								"sampleInterval": 10
							},
							"count": 2550,
							"dimensions": {
								"coloCode": "PTY"
							},
							"sum": {
								"edgeResponseBytes": 10286000,
								"visits": 2130
							}
						},
						{
							"avg": {
								"sampleInterval": 10
							},
							"count": 2410,
							"dimensions": {
								"coloCode": "JIB"
							},
							"sum": {
								"edgeResponseBytes": 9029000,
								"visits": 2080
							}
						}
					]
				}
			]
		}
	},
	"errors": null
}
```

</details>

This query says:

- Given the indicated `zones`, `limit`, and `time range`.
- Fetch the total number of requests (as `count`), the total amount of data transfer (as `edgeResponseBytes` of `sum` object), and the total number of `visits` per data center.

A few points to note:

- Adding the `requestSource` filter for `eyeball` returns request, data transfer, and visit data about only the end users of your website.
- Instead of `requests`, the `httpRequestsAdaptiveGroups` node reports `count`, which indicates the number of requests per data center.
- To measure data transfer, use `sum(edgeResponseBytes)`. Note that in the old API this was called `bandwidth` even though it actually measured data transfer.
- `unique visitors per colocation` is not supported in `httpRequestsAdaptiveGroups`, but the `httpRequestsAdaptiveGroups` API does support `visits`. A visit is defined as a page view that originated from a different website or direct link. Cloudflare checks where the HTTP referer does not match the hostname. One visit can consist of multiple page views.

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/graphql-api/migration-guides/graphql-api-analytics/#page","headline":"HTTP Requests by Colo Groups to HTTP Requests by Adaptive Groups","description":"Migrate colo groups queries to adaptive groups.","url":"https://developers.cloudflare.com/analytics/graphql-api/migration-guides/graphql-api-analytics/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/graphql-api/migration-guides/graphql-api-analytics/og.png?v=9a7bc6b91c4688b7","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Migrate from Network Analytics v1 to v2 nodes.
title: Network Analytics v1 to Network Analytics v2
image: https://developers.cloudflare.com/analytics/graphql-api/migration-guides/network-analytics-v2/og.png?v=ed980654303053bd
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Network Analytics v1 to Network Analytics v2

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/graphql-api/migration-guides/network-analytics-v2/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

In early 2020, Cloudflare released the first version of the Network Analytics dashboard and its corresponding API. The second version (Network Analytics v2) was made available on 2021-09-13.

Caution

**Network Analytics v1 (NAv1) is now deprecated.** For more information on Network Analytics v2 (NAv2), refer to [Cloudflare Network Analytics](https://developers.cloudflare.com/analytics/network-analytics/).

## Before you start

Learn more about the [concepts introduced in Network Analytics v2](https://developers.cloudflare.com/analytics/network-analytics/understand/concepts/).

## Feature comparison

The following table compares the features of NAv1 and NAv2:

| Feature | NAv1 | NAv2 |
| --- | --- | --- |
| Sampling rate | 1/8,192 packets | Varies between 1/100 and 1/1,000,000 packets,<br> depending on the mitigation service. |
| Sampling method | Core Sample Enrichment | Edge Sample Enrichment |
| Historical data retention method | Aggregated roll-ups | Adaptive Bit Rate |
| Retention period | 1-min roll-ups: 30 days<br>1-hour roll-ups: 6 months<br>1-day roll-ups: 1 year<br>Attack roll-ups: 1 year | All nodes: 16 weeks |
| Attack mitigation systems | `dosd` | `dosd`, `flowtrackd`\*, and Cloudflare Network Firewall\* |
| Examples of new fields | n/a | Rule ID<br>GRE tunnel ID<br>Packet size |

\* *Applicable only for Magic Transit customers.*

For more information on the differences in terms of sampling method and historical data retention, refer to [Main differences between Network Analytics v1 and v2](https://developers.cloudflare.com/analytics/graphql-api/migration-guides/network-analytics-v2/differences/).

Note

The `attackId` field value may be different between NAv1 and NAv2 for the same attack.

## Node comparison

NAv2 uses the same API endpoint but makes use of new nodes. While NAv1 has three nodes for aggregated roll-ups for all traffic and attacks, and one node for attacks, NAv2 has one node for all traffic and attacks, and four separate nodes for attacks that vary based on the mitigation system.

| Node type | NAv1 | NAv2 for Magic Transit | NAv2 for Spectrum |
| --- | --- | --- | --- |
| Main node(s) | `ipFlows1mGroups`<br>`ipFlows1hGroups`<br>`ipFlows1dGroups` | `magicTransitNetworkAnalyticsAdaptiveGroups` | `spectrumNetworkAnalyticsAdaptiveGroups` |
| Attack node(s) | `ipFlows1mAttacksGroups` | `dosdNetworkAnalyticsAdaptiveGroups`<br> `dosdAttackAnalyticsGroups`<br> `flowtrackdNetworkAnalyticsAdaptiveGroups`<br> `magicFirewallNetworkAnalyticsAdaptiveGroups` | `dosdNetworkAnalyticsAdaptiveGroups`<br> `dosdAttackAnalyticsGroups` |

Each row represents one packet sample. The data is sampled at Cloudflare’s edge at [various rates](https://developers.cloudflare.com/analytics/graphql-api/migration-guides/network-analytics-v2/node-reference/). You can also query the sample rate from the nodes using the `sample_interval` field.

For reference information on NAv2 nodes, refer to the [NAv2 node reference](https://developers.cloudflare.com/analytics/graphql-api/migration-guides/network-analytics-v2/node-reference/).

Obtaining data for ingress traffic only

All the NAv2 `*AnalyticsAdaptiveGroups` nodes include data for ingress and egress traffic. To obtain data about ingress traffic only, include `direction: "ingress"` in your [GraphQL query filter](https://developers.cloudflare.com/analytics/graphql-api/features/filtering/).

## Schema comparison

Refer to [NAv1 to NAv2 schema map](https://developers.cloudflare.com/analytics/graphql-api/migration-guides/network-analytics-v2/schema-map/) for a mapping of schema fields from NAv1 nodes to NAv2 nodes. Follow this recommended mapping when migrating to NAv2.

## Example

The following example queries the top 20 logs of traffic dropped by mitigation systems different from Cloudflare Network Firewall within a given time range, ordered by destination IP address.

```graphql
{
	viewer {
		accounts(filter: { accountTag: "<REDACTED>" }) {
			magicTransitNetworkAnalyticsAdaptiveGroups(
				filter: {
					datetime_gt: "2021-10-01T00:00:00Z"
					datetime_lt: "2021-10-05T00:00:00Z"
					outcome_like: "drop"
					mitigationSystem_neq: "magic-firewall"
				}
				limit: 20
				orderBy: [ipDestinationAddress_ASC]
			) {
				dimensions {
					outcome
					mitigationSystem
					ipSourceAddress
					ipDestinationAddress
					ipProtocol
					destinationPort
				}
			}
		}
	}
}
```

## Final remarks

The `mitigationSystem` field can take one the following values:

- `dosd` for [DDoS managed rulesets](https://developers.cloudflare.com/ddos-protection/managed-rulesets/) (Network-layer DDoS Attack Protection or HTTP DDoS Attack Protection).
- `flowtrackd` for [Advanced TCP Protection](https://developers.cloudflare.com/ddos-protection/advanced-ddos-systems/overview/advanced-tcp-protection/).
- `magic-firewall` for [Cloudflare Network Firewall](https://developers.cloudflare.com/cloudflare-network-firewall/).
- Empty string for unmitigated traffic.

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/graphql-api/migration-guides/network-analytics-v2/#page","headline":"Network Analytics v1 to Network Analytics v2","description":"Migrate from Network Analytics v1 to v2 nodes.","url":"https://developers.cloudflare.com/analytics/graphql-api/migration-guides/network-analytics-v2/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/graphql-api/migration-guides/network-analytics-v2/og.png?v=ed980654303053bd","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Compare Network Analytics v1 and v2 sampling and retention.
title: Main differences
image: https://developers.cloudflare.com/analytics/graphql-api/migration-guides/network-analytics-v2/differences/og.png?v=909053f26bec7911
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Main differences

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/graphql-api/migration-guides/network-analytics-v2/differences/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

## Aggregated roll-ups versus Adaptive Bit Rate

In Network Analytics v1 (NAv1), the data is rolled up into one minute roll-up tables, then one hour roll-ups, and finally one day roll-ups. Users can then query either the `ipFlows1mGroups` node for high-resolution data on traffic and attacks in the past 30 days, or query the `ipFlows1hGroups` or `ipFlows1dGroups` nodes for historical data. However, the data available through these nodes is aggregate data, and that means that the accuracy and cardinality of the results are limited. For example, short traffic spikes will not be visible in the data obtained from these nodes due to the aggregation of samples in the roll-ups.

On the other hand, Network Analytics v2 (NAv2) uses [Adaptive Bit Rate (ABR)](https://developers.cloudflare.com/analytics/network-analytics/understand/concepts/#adaptive-bit-rate-sampling) sampling. This means that users do not need to choose a node based on their query timeframe. Furthermore, the cardinality and accuracy is preserved even for historical data. Depending on the size of the query, the ABR mechanism will choose the best sampling rate and fetch a response from one of the sample tables encapsulated behind each node.

## Sampling improvements

Network Analytics v2 provides more accurate data due to the better sample rate and [Edge Sample Enrichment](https://developers.cloudflare.com/analytics/network-analytics/understand/concepts/#edge-sample-enrichment). NAv1 samples 1/8,192 packets (that is, one in every 8,192 packets), while NAv2 sample rates vary depending on the mitigation service. For example:

- The sample rate for `dosd` changes dynamically from 1/100 to 1/10,000 packets based on the volume of packets.
- The sample rate for Cloudflare Network Firewall events changes dynamically from 1/100 to 1/1,000,000 packets based on the number of packets.
- The sample rate for `flowtrackd` is 1/10,000 packets.

The NAv2 data pipeline is also more resilient compared to NAv1. NAv1 uses Core Sample Enrichment, where raw packet samples are sent from all of Cloudflare's edge data centers to the Core data centers. In the Core data centers, the packet samples are cross-referenced with additional databases and infused with the associated customer account ID, attack ID, attack type, and other metadata. Then, the packet samples are inserted into storage. One of the main shortcomings of this method is the potential congestion of samples when cross-referencing information, which could, in rare cases, cause temporary data lag.

To eliminate this potential data lag, NAv2 uses a new data logging pipeline which relies on Edge Sample Enrichment. By delegating the packet sample enrichment and cross-referencing to the edge data centers, we improve the data pipeline's resilience and tolerance against congestion. Using this method, enriched packet samples are immediately stored in Cloudflare's core data centers as soon as they arrive.

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/graphql-api/migration-guides/network-analytics-v2/differences/#page","headline":"Main differences","description":"Compare Network Analytics v1 and v2 sampling and retention.","url":"https://developers.cloudflare.com/analytics/graphql-api/migration-guides/network-analytics-v2/differences/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/graphql-api/migration-guides/network-analytics-v2/differences/og.png?v=909053f26bec7911","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Reference for Network Analytics v2 GraphQL nodes.
title: NAv2 node reference
image: https://developers.cloudflare.com/analytics/graphql-api/migration-guides/network-analytics-v2/node-reference/og.png?v=c13ddcd3ba0c47c5
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# NAv2 node reference

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/graphql-api/migration-guides/network-analytics-v2/node-reference/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

## Main nodes

Main nodes provide deep packet-level information about traffic and attacks for Spectrum customers and Magic Transit customers.

Use the main node to query traffic and attacks at a high level, as seen at the Cloudflare edge:

| Product | Main node |
| --- | --- |
| Spectrum | `spectrumNetworkAnalyticsAdaptiveGroups` |
| Magic Transit | `magicTransitNetworkAnalyticsAdaptiveGroups` |

To query more specific details about attacks, use the [attack nodes](#attack-nodes).

Each row represents a packet sample. The sample rate of main nodes is 1/10,000 packets.

If you are using both Magic Transit and Spectrum for IP addresses that overlap, you can use only the Magic Transit node.

## Attack nodes

### `dosdAttackAnalyticsGroups`

This node provides information about DDoS attacks detected and mitigated by Cloudflare's main DDoS protection system, the denial of service daemon (`dosd`). This node includes attack metadata such as:

- `startDatetime`
- `endDatetime`
- `attackType`
- `sourceIp`

Each row represents an attack event. Each attack has a unique ID.

The sample rate is dynamic and based on the volume of packets, ranging from 1/100 to 1/10,000 packets.

Adjusting attack mitigation

To adjust mitigation sensitivities and actions, or to define expression filters that exclude or include traffic from mitigation actions, customize the [Network-layer DDoS Attack Protection managed ruleset](https://developers.cloudflare.com/ddos-protection/managed-rulesets/network/).

### `dosdNetworkAnalyticsAdaptiveGroups`

This node complements the information in the `dosdAttackAnalyticsGroups` node. Provides deep packet-level information about DDoS attack packets mitigated by `dosd`, including fields such as:

- `ipProtocol`
- `ipv4Checksum`
- `ipv4Options`
- `tcpSequenceNumber`
- `tcpChecksum`
- `icmpCode`
- `ruleId`
- `ruleName`
- `attackVector`

Each row represents a packet sample. The sample rate is 1/10,000 packets.

### `advancedTcpProtectionNetworkAnalyticsAdaptiveGroups`

This node is only available to Magic Transit customers. Provides metadata about out-of-state TCP DDoS attacks mitigated by Cloudflare's [Advanced TCP Protection](https://developers.cloudflare.com/ddos-protection/advanced-ddos-systems/overview/advanced-tcp-protection/) system.

Advanced TCP Protection does not use the following ID fields: attack ID, rule ID, and ruleset ID.

The sample rate is 1/1,000 packets.

### `advancedDnsProtectionNetworkAnalyticsAdaptiveGroups`

This node is only available to Magic Transit customers. Provides metadata about DNS-based DDoS attacks mitigated by Cloudflare's [Advanced DNS Protection](https://developers.cloudflare.com/ddos-protection/advanced-ddos-systems/overview/advanced-dns-protection/) system.

Samples include information about the following DNS header fields:

- `dnsQueryName`
- `dnsQueryType`

Advanced DNS Protection does not use the following ID fields: attack ID, rule ID, and ruleset ID.

The sample rate is 1/1,000 packets.

### `magicFirewallNetworkAnalyticsAdaptiveGroups`

This node is only available to Magic Transit customers. Provides information about packets that were matched against customer-configured [Cloudflare Network Firewall](https://developers.cloudflare.com/cloudflare-network-firewall/) rules.

Each row represents a packet sample that matches a Cloudflare Network Firewall rule.

Cloudflare Network Firewall does not use attack IDs, only rule IDs and ruleset IDs.

The sample rate is dynamic and based on the volume of packets, ranging from 1/100 to 1/1,000,000 packets.

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/graphql-api/migration-guides/network-analytics-v2/node-reference/#page","headline":"NAv2 node reference","description":"Reference for Network Analytics v2 GraphQL nodes.","url":"https://developers.cloudflare.com/analytics/graphql-api/migration-guides/network-analytics-v2/node-reference/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/graphql-api/migration-guides/network-analytics-v2/node-reference/og.png?v=c13ddcd3ba0c47c5","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Map Network Analytics v1 fields to v2 fields.
title: NAv1 to NAv2 schema map
image: https://developers.cloudflare.com/analytics/graphql-api/migration-guides/network-analytics-v2/schema-map/og.png?v=4f217879f7043594
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# NAv1 to NAv2 schema map

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/graphql-api/migration-guides/network-analytics-v2/schema-map/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

The following table lists direct mappings between NAv1 and NAv2 fields, when available, and provides related fields when there is no direct mapping available.

| ipFlows1mGroups | magicTransitNetworkAnalytics-AdaptiveGroups /<br> spectrumNetworkAnalytics-AdaptiveGroups | dosdNetworkAnalytics-AdaptiveGroups | dosdAttackAnalytics-Groups | flowtrackdNetworkAnalytics-AdaptiveGroups | magicFirewallNetworkAnalytics-AdaptiveGroups |
| --- | --- | --- | --- | --- | --- |
| `date` | *Related fields:*<br>`datetime`<br>`datetimeTenSeconds` | *Related fields:*<br>`datetime`<br>`datetimeTenSeconds` |  | *Related fields:*<br>`datetime`<br>`datetimeTenSeconds` | *Related fields:*<br>`datetime`<br>`datetimeTenSeconds` |
| `datetimeMinute` | `datetimeMinute` | `datetimeMinute` |  | `datetimeMinute` | `datetimeMinute` |
| `datetimeFiveMinutes` | `datetimeFiveMinutes` | `datetimeFiveMinutes` |  | `datetimeFiveMinutes` | `datetimeFiveMinutes` |
| `datetimeFifteenMinutes` | `datetimeFifteenMinutes` | `datetimeFifteenMinutes` |  | `datetimeFifteenMinutes` | `datetimeFifteenMinutes` |
| `datetimeHour` | `datetimeHour` | `datetimeHour` |  | `datetimeHour` | `datetimeHour` |
| `attackId`\* |  | `attackId`\* | `attackId`\* |  | |
| `attackType` |  |  | `attackType` |  | |
| `attackMitigationType` |  |  | `mitigationType` |  | |
| `sourceIPCountry` | `sourceCountry` | `sourceCountry` |  | `sourceCountry` | `sourceCountry` |
| `sourceIPAsn` | `sourceAsn` | `sourceAsn` |  | `sourceAsn` | `sourceAsn` |
| `sourceIPASNDescription` | *Related field:*<br>`sourceGeohash` | *Related field:*<br>`sourceGeohash` |  | *Related field:*<br>`sourceGeohash` | *Related field:*<br>`sourceGeohash` |
| `coloCode` | `coloCode` | `coloCode` |  | `coloCode` | `coloCode` |
| `coloCity` | `coloCity` | `coloCity` |  | `coloCity` | `coloCity` |
| `coloCountry` | `coloCountry` | `coloCountry` |  | `coloCountry` | `coloCountry` |
| `coloRegion` | *Related field:*<br>`coloGeohash` | *Related field:*<br>`coloGeohash` |  | *Related field:*<br>`coloGeohash` | *Related field:*<br>`coloGeohash` |
| ipFlows1mGroups | magicTransitNetworkAnalytics-AdaptiveGroups /<br> spectrumNetworkAnalytics-AdaptiveGroups | dosdNetworkAnalytics-AdaptiveGroups | dosdAttackAnalytics-Groups | flowtrackdNetworkAnalytics-AdaptiveGroups | magicFirewallNetworkAnalytics-AdaptiveGroups |
| `ipVersion` | `ethertype` | `ethertype` |  | `ethertype` | `ethertype` |
| `bits` | `ipTotalLength` <br>(`bits` divided by 8) | `ipTotalLength` <br>(`bits` divided by 8) | `bits` | `ipTotalLength` <br>(`bits` divided by 8) | `ipTotalLength` <br>(`bits` divided by 8) |
| `packets` | *n/a* | *n/a* | `packets` | *n/a* | *n/a* |
| `ipProtocol` | `ipProtocol` | `ipProtocol` | `ipProtocol` | `ipProtocol` | `ipProtocol` |
| `sourceIP` | `ipSourceAddress` | `ipSourceAddress` | `sourceIp` | `ipSourceAddress` | `ipSourceAddress` |
| `destinationIP` | `ipDestinationAddress` | `ipDestinationAddress` | `destinationIp` | `ipDestinationAddress` | `ipDestinationAddress` |
| `destinationIPv4Range24` | `ipDestinationSubnet` | `ipDestinationSubnet` |  | `ipDestinationSubnet` | `ipDestinationSubnet` |
| `destinationIPv4Range23` | *n/a* | *n/a* |  | *n/a* | *n/a* |
| `sourcePort` | `sourcePort` | `sourcePort` | `sourcePort` | `sourcePort` | `sourcePort` |
| `destinationPort` | `destinationPort` | `destinationPort` | `destinationPort` | `destinationPort` | `destinationPort` |
| `tcpFlags` | `tcpFlags` | `tcpFlags` | `tcpFlags` | `tcpFlags` | `tcpFlags` |

\* The `attackId` field value may be different between NAv1 and NAv2 for the same attack.

Was this helpful?

YesNo

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/graphql-api/migration-guides/network-analytics-v2/schema-map/#page","headline":"NAv1 to NAv2 schema map","description":"Map Network Analytics v1 fields to v2 fields.","url":"https://developers.cloudflare.com/analytics/graphql-api/migration-guides/network-analytics-v2/schema-map/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/graphql-api/migration-guides/network-analytics-v2/schema-map/og.png?v=4f217879f7043594","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Migrate from Zone Analytics API to GraphQL.
title: Zone Analytics to GraphQL Analytics
image: https://developers.cloudflare.com/analytics/graphql-api/migration-guides/zone-analytics/og.png?v=68590a93f73f9130
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Zone Analytics to GraphQL Analytics

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/graphql-api/migration-guides/zone-analytics/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

The Zone Analytics API allows you to get request data by zone. It offers optional `since` and `until` parameters to specify the request time period and a `continuous` parameter to indicate whether the time period should be moved backward to find a period with completely aggregated data.

For example, here is a sample curl call to get data for a two minute period:

```bash
curl "https://api.cloudflare.com/client/v4/zones/<ZONE_ID>/analytics/dashboard?since=2019-09-08T20:00:00Z&until=2019-09-08T20:02:00Z&continuous=false" \
--header "Authorization: Bearer <API_TOKEN>" --silent | jq .
```

<details>

<summary>

Response

</summary>

```json
{
	"success": true,
	"query": {
		"since": "2019-09-08T20:00:00Z",
		"until": "2019-09-08T20:02:00Z",
		"time_delta": 1
	},
	"errors": [],
	"messages": [],
	"result": {
		"timeseries": [
			{
				"since": "2019-09-08T20:00:00Z",
				"until": "2019-09-08T20:01:00Z",
				"requests": {
					"all": 15,
					"cached": 12,
					"uncached": 3,
					"ssl": {
						"encrypted": 13,
						"unencrypted": 2
					},
					"http_status": {
						"200": 4,
						"403": 11
					},
					"content_type": {
						"html": 12,
						"png": 3
					},
					"country": {
						"CN": 6,
						"IE": 1,
						"US": 3,
						"VN": 5
					},
					"ip_class": {
						"monitoringService": 4,
						"noRecord": 11
					},
					"ssl_protocol": {
						"TLSv1.2": 13,
						"none": 2
					}
				},
				"bandwidth": {
					"all": 312740,
					"cached": 309930,
					"uncached": 2810,
					"ssl": {
						"encrypted": 309276,
						"unencrypted": 3464
					},
					"ssl_protocol": {
						"TLSv1.2": 13,
						"none": 2
					},
					"content_type": {
						"html": 32150,
						"png": 280590
					},
					"country": {
						"CN": 10797,
						"IE": 98224,
						"US": 185176,
						"VN": 18543
					}
				},
				"threats": {
					"all": 6,
					"type": {
						"user.ban.ctry": 6
					},
					"country": {
						"CN": 6
					}
				},
				"pageviews": {
					"all": 1,
					"search_engine": {
						"pingdom": 1
					}
				},
				"uniques": {
					"all": 11
				}
			},
			{
				"since": "2019-09-08T20:01:00Z",
				"until": "2019-09-08T20:02:00Z",
				"requests": {
					"all": 4,
					"cached": 1,
					"uncached": 3,
					"ssl": {
						"encrypted": 4,
						"unencrypted": 0
					},
					"http_status": {
						"200": 4
					},
					"content_type": {
						"html": 1,
						"png": 3
					},
					"country": {
						"CA": 2,
						"US": 2
					},
					"ip_class": {
						"monitoringService": 4
					},
					"ssl_protocol": {
						"TLSv1.2": 4
					}
				},
				"bandwidth": {
					"all": 283399,
					"cached": 280590,
					"uncached": 2809,
					"ssl": {
						"encrypted": 283399,
						"unencrypted": 0
					},
					"ssl_protocol": {
						"TLSv1.2": 4
					},
					"content_type": {
						"html": 2809,
						"png": 280590
					},
					"country": {
						"CA": 101033,
						"US": 182366
					}
				},
				"threats": {
					"all": 0,
					"type": {},
					"country": {}
				},
				"pageviews": {
					"all": 1,
					"search_engine": {
						"pingdom": 1
					}
				},
				"uniques": {
					"all": 4
				}
			}
		],
		"totals": {
			"since": "2019-09-08T20:00:00Z",
			"until": "2019-09-08T20:02:00Z",
			"requests": {
				"all": 19,
				"cached": 13,
				"uncached": 6,
				"ssl": {
					"encrypted": 17,
					"unencrypted": 2
				},
				"http_status": {
					"200": 8,
					"403": 11
				},
				"content_type": {
					"html": 13,
					"png": 6
				},
				"country": {
					"CA": 2,
					"CN": 6,
					"IE": 1,
					"US": 5,
					"VN": 5
				},
				"ip_class": {
					"monitoringService": 8,
					"noRecord": 11
				},
				"ssl_protocol": {
					"TLSv1.2": 17,
					"none": 2
				}
			},
			"bandwidth": {
				"all": 596139,
				"cached": 590520,
				"uncached": 5619,
				"ssl": {
					"encrypted": 592675,
					"unencrypted": 3464
				},
				"ssl_protocol": {
					"TLSv1.2": 17,
					"none": 2
				},
				"content_type": {
					"html": 34959,
					"png": 561180
				},
				"country": {
					"CA": 101033,
					"CN": 10797,
					"IE": 98224,
					"US": 367542,
					"VN": 18543
				}
			},
			"threats": {
				"all": 6,
				"type": {
					"user.ban.ctry": 6
				},
				"country": {
					"CN": 6
				}
			},
			"pageviews": {
				"all": 2,
				"search_engine": {
					"pingdom": 2
				}
			},
			"uniques": {
				"all": 15
			}
		}
	}
}
```

</details>

As you can see from the response, Zone Analytics returns metrics along many dimensions and does not give you the option to control what you receive. With GraphQL Analytics, you can ask for only the data that you need. However, if you wanted to get exactly the same metrics and dimensions as you would from Zone Analytics, here is the query you would make:

```graphql
query ZoneAnalyticsMigrationSample($zoneTag: string, $start: Time, $end: Time) {
	viewer {
		zones(filter: { zoneTag: $zoneTag }) {
			httpRequests1mGroups(
				orderBy: [datetimeFiveMinutes_ASC]
				limit: 100
				filter: { datetime_geq: $start, datetime_lt: $end }
			) {
				dimensions {
					datetimeFiveMinutes
				}
				sum {
					browserMap {
						pageViews
						uaBrowserFamily
					}
					bytes
					cachedBytes
					cachedRequests
					contentTypeMap {
						bytes
						requests
						edgeResponseContentTypeName
					}
					clientSSLMap {
						requests
						clientSSLProtocol
					}
					countryMap {
						bytes
						requests
						threats
						clientCountryName
					}
					encryptedBytes
					encryptedRequests
					ipClassMap {
						requests
						ipType
					}
					pageViews
					requests
					responseStatusMap {
						requests
						edgeResponseStatus
					}
					threats
					threatPathingMap {
						requests
						threatPathingName
					}
				}
				uniq {
					uniques
				}
			}
		}
	}
}
```

<details>

<summary>

Response

</summary>

```json
{
	"data": {
		"viewer": {
			"zones": [
				{
					"httpRequests1mGroups": [
						{
							"dimensions": {
								"datetimeFiveMinutes": "2019-09-08T20:00:00Z"
							},
							"sum": {
								"browserMap": [
									{
										"pageViews": 1,
										"uaBrowserFamily": "PingdomBot"
									}
								],
								"bytes": 312740,
								"cachedBytes": 309930,
								"cachedRequests": 12,
								"clientSSLMap": [
									{
										"clientSSLProtocol": "none",
										"requests": 2
									},
									{
										"clientSSLProtocol": "TLSv1.2",
										"requests": 13
									}
								],
								"contentTypeMap": [
									{
										"bytes": 280590,
										"edgeResponseContentTypeName": "png",
										"requests": 3
									},
									{
										"bytes": 32150,
										"edgeResponseContentTypeName": "html",
										"requests": 12
									}
								],
								"countryMap": [
									{
										"bytes": 10797,
										"clientCountryName": "CN",
										"requests": 6,
										"threats": 6
									},
									{
										"bytes": 98224,
										"clientCountryName": "IE",
										"requests": 1,
										"threats": 0
									},
									{
										"bytes": 185176,
										"clientCountryName": "US",
										"requests": 3,
										"threats": 0
									},
									{
										"bytes": 18543,
										"clientCountryName": "VN",
										"requests": 5,
										"threats": 0
									}
								],
								"encryptedBytes": 309276,
								"encryptedRequests": 13,
								"ipClassMap": [
									{
										"ipType": "monitoringService",
										"requests": 4
									},
									{
										"ipType": "noRecord",
										"requests": 11
									}
								],
								"pageViews": 1,
								"requests": 15,
								"responseStatusMap": [
									{
										"edgeResponseStatus": 200,
										"requests": 4
									},
									{
										"edgeResponseStatus": 403,
										"requests": 11
									}
								],
								"threatPathingMap": [
									{
										"requests": 6,
										"threatPathingName": "user.ban.ctry"
									}
								],
								"threats": 6
							},
							"uniq": {
								"uniques": 11
							}
						},
						{
							"dimensions": {
								"datetimeFiveMinutes": "2019-09-08T20:01:00Z"
							},
							"sum": {
								"browserMap": [
									{
										"pageViews": 1,
										"uaBrowserFamily": "PingdomBot"
									}
								],
								"bytes": 283399,
								"cachedBytes": 280590,
								"cachedRequests": 1,
								"clientSSLMap": [
									{
										"clientSSLProtocol": "TLSv1.2",
										"requests": 4
									}
								],
								"contentTypeMap": [
									{
										"bytes": 280590,
										"edgeResponseContentTypeName": "png",
										"requests": 3
									},
									{
										"bytes": 2809,
										"edgeResponseContentTypeName": "html",
										"requests": 1
									}
								],
								"countryMap": [
									{
										"bytes": 101033,
										"clientCountryName": "CA",
										"requests": 2,
										"threats": 0
									},
									{
										"bytes": 182366,
										"clientCountryName": "US",
										"requests": 2,
										"threats": 0
									}
								],
								"encryptedBytes": 283399,
								"encryptedRequests": 4,
								"ipClassMap": [
									{
										"ipType": "monitoringService",
										"requests": 4
									}
								],
								"pageViews": 1,
								"requests": 4,
								"responseStatusMap": [
									{
										"edgeResponseStatus": 200,
										"requests": 4
									}
								],
								"threatPathingMap": [],
								"threats": 0
							},
							"uniq": {
								"uniques": 4
							}
						}
					]
				}
			]
		}
	},
	"errors": null
}
```

</details>

Notice that you can specify the request time period using a dataset filter (refer to [Filtering](https://developers.cloudflare.com/analytics/graphql-api/features/filtering/)). The `continuous` parameter is no longer needed because GraphQL Analytics is designed to provide data as soon as it is available.

Also, if you want to get the totals for a particular period, rather than a breakdown by time period, simply remove the `datetimeFiveMinutes` field under `dimensions`.

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/graphql-api/migration-guides/zone-analytics/#page","headline":"Zone Analytics to GraphQL Analytics","description":"Migrate from Zone Analytics API to GraphQL.","url":"https://developers.cloudflare.com/analytics/graphql-api/migration-guides/zone-analytics/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/graphql-api/migration-guides/zone-analytics/og.png?v=68590a93f73f9130","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Migrate colos endpoint queries to GraphQL.
title: Zone Analytics Colos Endpoint to GraphQL Analytics
image: https://developers.cloudflare.com/analytics/graphql-api/migration-guides/zone-analytics-colos/og.png?v=6a5a26c593f1d877
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Zone Analytics Colos Endpoint to GraphQL Analytics

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/graphql-api/migration-guides/zone-analytics-colos/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

This guide shows how you might migrate from the deprecated (and soon to be sunset) zone analytics API to the GraphQL API. It provides an example for a plausible use-case of the colos endpoint, then shows how that use-case is translated to the GraphQL API. It also explores features of the GraphQL API that make it more powerful than the API it replaces.

In this example, we want to calculate the number of requests for a particular colo, broken down by the hour in which the requests occurred. Referring to the zone analytics colos endpoint, we can construct a curl which retrieves the data from the API.

```bash
curl -H "Authorization: Bearer $API_TOKEN" "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/analytics/colos?since=2020-12-10T00:00:00Z"  > colos_endpoint_output.json
```

This query says:

- Given an `API_TOKEN` which has Analytics Read access to `ZONE_ID`.
- Fetch colos analytics for `ZONE_ID` with a time range that starts on `2020-12-10T00:00:00Z` ( `since` parameter) to now.

The question that we want to answer is: "What is the number of requests for ZHR per hour?" Using the colos endpoint response data and some wrangling by jq we can answer that question with this command:

```bash
cat colos_endpoint_output.json | jq  -c '.result[] | {colo_id: .colo_id, timeseries: .timeseries[]} | {colo_id: .colo_id, timeslot: .timeseries.since, requests: .timeseries.requests.all, bandwidth: .timeseries.bandwidth.all} | select(.requests > 0) | select(.colo_id == "ZRH") '
```

This jq command is complex, so we can break it down:

```bash
.result[]
```

This means that the result array is split into individual json lines.

```bash
{colo_id: .colo_id, timeseries: .timeseries[]}
```

This breaks each json line into multiple json lines. Each resulting line contains a `colo_id` and one element of the `timeseries` array.

```bash
{colo_id: .colo_id, timeslot: .timeseries.since, requests: .timeseries.requests.all, bandwidth: .timeseries.bandwidth.all}
```

This flattens out the data we are interested in that is inside the timeseries object of each line.

```bash
select(.requests > 0) | select(.colo_id == "ZRH")
```

This selects only lines that contain more than 0 requests and the `colo_id` is ZRH.

The final data we get looks like the following response:

<details>

<summary>

Response

</summary>

```json
{"colo_id":"ZRH","timeslot":"2020-12-10T00:00:00Z","requests":601,"bandwidth":683581}
{"colo_id":"ZRH","timeslot":"2020-12-10T01:00:00Z","requests":484,"bandwidth":550936}
{"colo_id":"ZRH","timeslot":"2020-12-10T02:00:00Z","requests":326,"bandwidth":370627}
{"colo_id":"ZRH","timeslot":"2020-12-10T03:00:00Z","requests":354,"bandwidth":402527}
{"colo_id":"ZRH","timeslot":"2020-12-10T04:00:00Z","requests":446,"bandwidth":507234}
{"colo_id":"ZRH","timeslot":"2020-12-10T05:00:00Z","requests":692,"bandwidth":787688}
{"colo_id":"ZRH","timeslot":"2020-12-10T06:00:00Z","requests":1474,"bandwidth":1676166}
{"colo_id":"ZRH","timeslot":"2020-12-10T07:00:00Z","requests":2839,"bandwidth":3226871}
{"colo_id":"ZRH","timeslot":"2020-12-10T08:00:00Z","requests":2953,"bandwidth":3358487}
{"colo_id":"ZRH","timeslot":"2020-12-10T09:00:00Z","requests":2550,"bandwidth":2901823}
{"colo_id":"ZRH","timeslot":"2020-12-10T10:00:00Z","requests":2203,"bandwidth":2504615}
...
```

</details>

How do we get the same result using the GraphQL API?

The GraphQL API allows us to be much more specific about the data that we want to retrieve. While the colos endpoint forces us to retrieve all the information about the breakdown of requests and bandwidth per colo, using the GraphQL API allows us to fetch only the information we are interested in.

The data we want is about HTTP requests. Hence, we use the canonical source for HTTP request data, also known as `httpRequestsAdaptiveGroups`. This node in GraphQL API allows you to filter and group by almost any dimension of an HTTP request imaginable. It is [Adaptive](https://developers.cloudflare.com/analytics/network-analytics/understand/concepts/#adaptive-bit-rate-sampling) so responses will be fast since it is driven by our [ABR technology ↗︎](https://blog.cloudflare.com/explaining-cloudflares-abr-analytics/).

The following is a GraphQL API query to retrieve the data we need to answer the question: "What is the number of requests for ZHR per hour?"

```txt
{
  viewer {
    zones(filter: {zoneTag:"$ZONE_TAG"}) {
      httpRequestsAdaptiveGroups(filter: {datetime_gt: "2020-12-10T00:00:00Z", coloCode:"ZRH"}, limit:10000, orderBy: [datetimeHour_ASC]) {
        count
        sum {
          edgeResponseBytes
        }
        avg {
          sampleInterval
        }
        count
        dimensions {
          datetimeHour
          coloCode
        }
      }
    }
  }
}
```

Then we can run it with curl:

```bash
curl -X POST -H "Authorization: Bearer $API_TOKEN"  https://api.cloudflare.com/client/v4/graphql -d "@./coloGroups.json" > graphqlColoGroupsResponse.json
```

We can answer our question in the same way as before using jq:

```bash
cat graphqlColoGroupsResponse.json| jq -c '.data.viewer.zones[] | .httpRequestsAdaptiveGroups[] | {colo_id: .dimensions.coloCode, timeslot: .dimensions.datetimeHour, requests: .count, bandwidth: .sum.edgeResponseBytes}'
```

This command is much simpler than what we had before, because the data returned by the GraphQL API is more specific than what is returned by the colos endpoint.

Still, it is worth explaining the command since it will help to understand some of the concepts underlying the GraphQL API.

```bash
.data.viewer.zones[]
```

The format of a GraphQL response is very similar to the query. A successful response always contains a `data` object which wraps the data in the response. A query will always have a `viewer` object which represents your user. Then, we unwrap the zones objects, one per line. Our query only has one zone (since this is how we chose to do it). But a query could have multiple zones as well.

```bash
.httpRequestsAdaptiveGroups[]
```

The `httpRequestsAdaptiveGroups` field is a list, where each datapoint in the list represents a combination of the dimensions that were selected, along with the aggregation that was selected for that combination of the dimensions. Here, we unwrap each of the datapoints, one per row.

```bash
{colo_id: .dimensions.coloCode, timeslot: .dimensions.datetimeHour, requests: .count, bandwidth: .sum.edgeResponseBytes}
```

This is straightforward: it just selects the attributes of each datapoint that we are interested in, in the format which we used previously in the colos endpoint.

The GraphQL API is a very powerful tool, as you can filter and group the data by many dimensions. This feature is totally absent from the colos endpoint in the Zone Analytics API.

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/graphql-api/migration-guides/zone-analytics-colos/#page","headline":"Zone Analytics Colos Endpoint to GraphQL Analytics","description":"Migrate colos endpoint queries to GraphQL.","url":"https://developers.cloudflare.com/analytics/graphql-api/migration-guides/zone-analytics-colos/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/graphql-api/migration-guides/zone-analytics-colos/og.png?v=6a5a26c593f1d877","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Understand sampling in GraphQL Analytics API datasets.
title: Sampling
image: https://developers.cloudflare.com/analytics/graphql-api/sampling/og.png?v=71bf3e3733e5b607
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Sampling

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/graphql-api/sampling/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

For a deep-dive on how sampling at Cloudflare works, see [Understanding sampling in Cloudflare Analytics](https://developers.cloudflare.com/analytics/sampling/).

## Overview

In a small number of cases, the analytics provided on the Cloudflare dashboard and GraphQL Analytics API are based on a **sample** — a subset of the dataset. In these cases, Cloudflare Analytics returns an estimate derived from the sampled value. For example, suppose that during an attack the sampling rate is 10% and 5,000 events are sampled. Cloudflare will estimate 50,000 total events (5,000 × 10) and report this value in Analytics.

## Sampled datasets

Cloudflare GraphQL API exposes datasets that powered by adaptive sampling. These nodes have **Adaptive** in the name and can be discovered through [introspection](https://developers.cloudflare.com/analytics/graphql-api/features/discovery/introspection/).

The presence of sampled data is also called out in the Cloudflare dashboard and in the description of the dataset in the API.

## Why sampling is applied

Analytics is designed to provide requested data, at the appropriate level of detail, as quickly as possible. Sampling allows Cloudflare to deliver analytics within seconds, even when datasets scale quickly and unpredictably, such as a burst of Firewall events generated during an attack. And because the volume of underlying data is large, the value estimated from the sample should still be statistically significant – meaning you can rely on sampled data with a high degree of confidence. Without sampling, it might take several minutes or longer to answer a query — a long time to wait when validating mitigation efforts.

## Types of sampling

### Adaptive sampling

Cloudflare almost always uses **adaptive sampling**, which means the sample rate fluctuates depending on the volume of data ingested or queried. If the number of records is relatively small, sampling is not used. However, as the volume of records grows larger, progressively lower sample rates are applied. Security Events (also known as Firewall Events) and the Security Event Log follow this model. Data nodes that use adaptive sampling are easy to identify by the `Adaptive` suffix in the node name, as in `firewallEventsAdaptive`.

### Fixed sampling

The following data nodes are based on fixed sampling, where the sample rate does not vary:

| Data set | Rate | Notes |
| --- | --- | --- |
| Firewall Rules Preview<br>**Nodes:**<br>`firewallRulePreviewGroups` | 1% | Use with caution. A 1% sample rate does not provide accurate estimates for datasets smaller than a certain threshold, a scenario the Cloudflare dashboard calls out explicitly but the API does not. |
| Network Analytics<br>**Nodes:**<br>`ipFlows1mGroups`<br>`ipFlows1hGroups`<br>`ipFlows1dGroups`<br>`ipFlows1mAttacksGroups` | 0.012% | Sampling rate is in terms of packet count (1 of every 8,192 packets). |

## Access to raw data

Because sampling is primarily adaptive and automatically adjusts to provide an accurate estimate, the sampling rate cannot be directly controlled. Enterprise customers have access to raw data via Cloudflare Logs.

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/graphql-api/sampling/#page","headline":"Sampling","description":"Understand sampling in GraphQL Analytics API datasets.","url":"https://developers.cloudflare.com/analytics/graphql-api/sampling/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/graphql-api/sampling/og.png?v=71bf3e3733e5b607","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Capture dashboard GraphQL queries using Chrome DevTools.
title: Capture GraphQL queries with Chrome DevTools
image: https://developers.cloudflare.com/analytics/graphql-api/tutorials/capture-graphql-queries-from-dashboard/og.png?v=bdd823697067fe4c
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Capture GraphQL queries with Chrome DevTools

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/graphql-api/tutorials/capture-graphql-queries-from-dashboard/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

Using [Chrome DevTools ↗︎](https://developer.chrome.com/docs/devtools), you can capture the queries running behind the Cloudflare Dashboard analytics. In this example, we will focus on the Network Analytics dataset, but the same process can be applied to any other analytics available in your dashboard.

1. In the Cloudflare dashboard, go to the **Network Analytics** page or any other analytics dashboard you are interested in seeing the GraphQL queries in. [Go to **Network analytics** ↗](https://dash.cloudflare.com/?to=/:account/networking-insights/analytics/network-analytics/transport-analytics)

![Analytics tab](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=2322,height=1090,format=webp/_astro/analytics-tab.sJIMwybT.png)

2. Open the [Chrome Developer Tools ↗︎](https://developer.chrome.com/docs/devtools) and select **Inspect**.

![Chrome developer tools](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=1470,height=960,format=webp/_astro/chrome-developer-tools.D4a36rnA.png)

3. Select the **Network** tab in the Developer Tools panel.
4. In the filter bar, type `graphql` to filter out the GraphQL requests. If no requests appear, try reloading the page. As the page reloads, several network requests will populate the **Network** tab. Look for requests that contain `graphql` in the name.

![Type graphql in the search field](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=1258,height=1032,format=webp/_astro/search-field.BxHnt1F0.png)

5. Select one of the GraphQL requests to open its details and go to the **Payload** tab. There you will find the GraphQL query. Select the query line and then **Copy value** to capture the query.

![Copy query value](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=1110,height=740,format=webp/_astro/copy-value.BZMZMU5_.png)

6. If you want to capture a new query, adjust the filters in the **Network analytics** dashboard and a new query will appear in the GraphQL requests.

![Create a new query](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=1538,height=866,format=webp/_astro/new-query.TN7tG2lX.png)

You can now use this query as the basis for your API call. Refer to the [Get started](https://developers.cloudflare.com/analytics/graphql-api/getting-started/) section for more information.

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/graphql-api/tutorials/capture-graphql-queries-from-dashboard/#page","headline":"Capture GraphQL queries with Chrome DevTools","description":"Capture dashboard GraphQL queries using Chrome DevTools.","url":"https://developers.cloudflare.com/analytics/graphql-api/tutorials/capture-graphql-queries-from-dashboard/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/graphql-api/tutorials/capture-graphql-queries-from-dashboard/og.png?v=bdd823697067fe4c","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Query HTTP request metrics by hostname.
title: Querying HTTP events by hostname with GraphQL
image: https://developers.cloudflare.com/analytics/graphql-api/tutorials/end-customer-analytics/og.png?v=dddbad7b66e15bad
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Querying HTTP events by hostname with GraphQL

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/graphql-api/tutorials/end-customer-analytics/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

## Aggregated HTTP metrics by hostname over time

In this example, we are going to use the GraphQL Analytics API to query aggregated metrics about HTTP events by hostname over a specific period of time.

The following API call will request the number of visits and edge response bytes for the custom hostname `hostname.example.com` over a four day period. Be sure to replace `CLOUDFLARE_ZONE_TAG` and `API_TOKEN`<sup>[1](#user-content-fn-1)</sup> with your zone ID and API credentials, and adjust the `datetime_geq` and `datetime_leq` values as needed.

### API Call

```bash
echo '{ "query":
  "query RequestsAndDataTransferByHostname($zoneTag: string, $filter:filter) {
    viewer {
      zones(filter: {zoneTag: $zoneTag}) {
        httpRequestsAdaptiveGroups(limit: 10, filter: $filter) {
          sum {
            visits
            edgeResponseBytes
          }
          dimensions {
            datetimeHour
          }
        }
      }
    }
  }",
  "variables": {
    "zoneTag": "<CLOUDFLARE_ZONE_TAG>",
    "filter": {
      "datetime_geq": "2022-07-20T11:00:00Z",
      "datetime_lt": "2022-07-24T12:00:00Z",
      "clientRequestHTTPHost": "hostname.example.com",
      "requestSource": "eyeball"
    }
  }
}' | tr -d '\n' | curl --silent \
https://api.cloudflare.com/client/v4/graphql \
--header "Authorization: Bearer <API_TOKEN>" \
--header "Accept: application/json" \
--header "Content-Type: application/json" \
--data @- | jq .
```

The returned results will be in JSON format (as requested), so piping the output to `jq` will make them easier to read, like in the following example:

```json
{
  "data": {
    "viewer": {
      "zones": [
        {
          "httpRequestsAdaptiveGroups": [
            {
              "dimensions": {
                "datetimeHour": "2022-07-21T10:00:00Z"
              },
              "sum": {
                "edgeResponseBytes": 19849385,
                "visits": 4383
              }
            },
            {
              "dimensions": {
                "datetimeHour": "2022-07-21T06:00:00Z"
              },
              "sum": {
                "edgeResponseBytes": 20607204,
                "visits": 4375
              }
            },
            {
              "dimensions": {
                "datetimeHour": "2022-07-26T05:00:00Z"
              },
              "sum": {
                "edgeResponseBytes": 20170839,
                "visits": 4519
              }
            },
            {
              "dimensions": {
                "datetimeHour": "2022-07-23T08:00:00Z"
              },
              "sum": {
                "edgeResponseBytes": 20141860,
                "visits": 4448
              }
            },
            {
              "dimensions": {
                "datetimeHour": "2022-07-25T15:00:00Z"
              },
              "sum": {
                "edgeResponseBytes": 21070367,
                "visits": 4469
              }
            },
            {
              "dimensions": {
                "datetimeHour": "2022-07-28T08:00:00Z"
              },
              "sum": {
                "edgeResponseBytes": 19200774,
                "visits": 4345
              }
            },
            {
              "dimensions": {
                "datetimeHour": "2022-07-26T02:00:00Z"
              },
              "sum": {
                "edgeResponseBytes": 20758067,
                "visits": 4502
              }
            },
            {
              "dimensions": {
                "datetimeHour": "2022-07-20T19:00:00Z"
              },
              "sum": {
                "edgeResponseBytes": 22127811,
                "visits": 4443
              }
            },
            {
              "dimensions": {
                "datetimeHour": "2022-07-27T15:00:00Z"
              },
              "sum": {
                "edgeResponseBytes": 20480644,
                "visits": 4268
              }
            },
            {
              "dimensions": {
                "datetimeHour": "2022-07-27T17:00:00Z"
              },
              "sum": {
                "edgeResponseBytes": 19885704,
                "visits": 4287
              }
            }
          ]
        }
      ]
    }
  },
  "errors": null
}
```

## Top 10 consuming URLs in a zone

We are going to use the GraphQL Analytics API to query the top 10 consuming URLs from a zone, helping you identify the URLs with the highest resource usage. Here are some configuration instructions:

- To filter on a specific hostname, add the line `"clientRequestHTTPHost": "'$2'"` below `"requestSource"`."
- Replace `API_TOKEN` with your generated API token using the `Read all resources` permissions. The script will only access zones available to the token's creator.
- Pass the zone ID ( `zoneTag`) as a parameter `ARG=$1`.
- To calculate the current date and the date from 30 days ago, use `gdate` on Mac:
  - `CURRENTDATE=$(gdate -u +'%FT%TZ')`
  - `OLDDATE=$(gdate -d '-30 days' -u +'%FT%TZ')`.
- For specific dates within the last 30 days, set `CURRENTDATE` and `OLDDATE` variables in the format `"YYYY-MM-DDTHH:MM:SSZ"`.

### API call

```bash
curl --silent \
https://api.cloudflare.com/client/v4/graphql \
--header "Authorization: Bearer <API_TOKEN>" \
--header "Content-Type: application/json" \
--data '{
  "query": "{viewer {zones(filter: {zoneTag: $zoneTag}) {topPaths: httpRequestsAdaptiveGroups(filter: $filter, limit: 10, orderBy: [sum_edgeResponseBytes_DESC]) {count sum {edgeResponseBytes} dimensions {metric: clientRequestPath}}}}}",
  "variables": {
    "zoneTag": "'$ARG'",
    "filter": {
      "AND": [
        {
          "datetime_geq": "'$OLDDATE'",
          "datetime_leq": "'$CURRENTDATE'"
        },
        {
          "requestSource": "eyeball"
        }
      ]
    }
  }
}' | jq -r 'try .data.viewer.zones[].topPaths[] | "\"\(.dimensions.metric)\": \(.sum.edgeResponseBytes)"' | sort
```

## Footnotes

1. Refer to [Configure an Analytics API token](https://developers.cloudflare.com/analytics/graphql-api/getting-started/authentication/api-token-auth/) for more information on configuration and permissions. [↩](#user-content-fnref-1)

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/graphql-api/tutorials/end-customer-analytics/#page","headline":"Querying HTTP events by hostname with GraphQL","description":"Query HTTP request metrics by hostname.","url":"https://developers.cloudflare.com/analytics/graphql-api/tutorials/end-customer-analytics/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/graphql-api/tutorials/end-customer-analytics/og.png?v=dddbad7b66e15bad","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Retrieve Access login event logs via GraphQL.
title: Querying Access login events with GraphQL
image: https://developers.cloudflare.com/analytics/graphql-api/tutorials/querying-access-login-events/og.png?v=28289548c674fb2d
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Querying Access login events with GraphQL

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/graphql-api/tutorials/querying-access-login-events/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

In this example, we are going to use the GraphQL Analytics API to retrieve logs for an Access login event. These logs are particularly useful for determining why a user received a `403` Forbidden error, since they surface additional data beyond what is shown in the dashboard Access logs.

The following API call will request logs for a single Access login event and output the requested fields. The authentication request is identified by its **Ray ID**, which you can obtain from the `403` Forbidden page shown to the user.

You will need to insert your `<CLOUDFLARE_ACCOUNT_TAG>`, your API credentials in `<API_TOKEN>`<sup>[1](#user-content-fn-1)</sup>, and substitute your own values for the following variables:

- `rayID`: A unique identifier assigned to the authentication request.
- `datetimeStart`: The earliest event time to query (no earlier than September 16, 2022).
- `datetimeEnd`: The latest event time to query. Be sure to specify a time range that includes the login event you are querying.

## API Call

```bash
echo '{ "query":
  "query accessLoginRequestsAdaptiveGroups($accountTag: string, $rayId: string, $datetimeStart: string, $datetimeEnd: string) {
    viewer {
      accounts(filter: {accountTag: $accountTag}) {
        accessLoginRequestsAdaptiveGroups(limit: 100, filter: {datetime_geq: $datetimeStart, datetime_leq: $datetimeEnd, cfRayId: $rayId}, orderBy: [datetime_ASC]) {
          dimensions {
            datetime
            isSuccessfulLogin
            hasWarpEnabled
            hasGatewayEnabled
            hasExistingJWT
            approvingPolicyId
            cfRayId
            ipAddress
            userUuid
            identityProvider
            country
            deviceId
            mtlsStatus
            mtlsCertSerialId
            mtlsCommonName
            serviceTokenId
          }
        }
      }
    }
  }",
  "variables": {
    "accountTag": "<CLOUDFLARE_ACCOUNT_TAG>",
    "rayId": "74e4ac510dfdc44f",
    "datetimeStart": "2022-09-20T14:36:38Z",
    "datetimeEnd": "2022-09-22T14:36:38Z"
}
}' | tr -d '\n' | curl --silent \
https://api.cloudflare.com/client/v4/graphql \
--header "Authorization: Bearer <API_TOKEN>" \
--header "Accept: application/json" \
--header "Content-Type: application/json" \
--data @- | jq .
```

Note

Rather than filter by `cfRayId`, you may also [filter](https://developers.cloudflare.com/analytics/graphql-api/features/filtering/) by any other field in the query such as `userUuid` or `deviceId`.

## Response

```json
{
  "data": {
    "viewer": {
      "accounts": [
        {
          "accessLoginRequestsAdaptiveGroups": [
            {
              "dimensions": {
                "approvingPolicyId": "",
                "cfRayId": "744927037ce06d68",
                "country": "US",
                "datetime": "2022-09-02T20:56:27Z",
                "deviceId": "",
                "hasExistingJWT": 0,
                "hasGatewayEnabled": 0,
                "hasWarpEnabled": 0,
                "identityProvider": "nonidentity",
                "ipAddress": "2a09:bac0:15::814:7b37",
                "isSuccessfulLogin": 0,
                "mtlsCertSerialId": "",
                "mtlsCommonName": "",
                "mtlsStatus": "NONE",
                "serviceTokenId": "",
                "userUuid": ""
              }
            }
          ]
        }
      ]
    }
  },
  "errors": null
}
```

You can compare the query results to your Access policies to understand why a user was blocked. For example, if your application requires a valid mTLS certificate, Access blocked the request shown above because `mtlsStatus`, `mtlsCommonName`, and `mtlsCertSerialId` are empty.

## Footnotes

1. Refer to [Configure an Analytics API token](https://developers.cloudflare.com/analytics/graphql-api/getting-started/authentication/api-token-auth/) for more information on configuration and permissions. [↩](#user-content-fnref-1)

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/graphql-api/tutorials/querying-access-login-events/#page","headline":"Querying Access login events with GraphQL","description":"Retrieve Access login event logs via GraphQL.","url":"https://developers.cloudflare.com/analytics/graphql-api/tutorials/querying-access-login-events/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/graphql-api/tutorials/querying-access-login-events/og.png?v=28289548c674fb2d","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Query Cloudflare Containers metrics with the GraphQL Analytics API.
title: Querying Containers metrics with GraphQL
image: https://developers.cloudflare.com/analytics/graphql-api/tutorials/querying-container-metrics/og.png?v=6a2e0f0adf373928
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Querying Containers metrics with GraphQL

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/graphql-api/tutorials/querying-container-metrics/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

This example uses the GraphQL Analytics API to query metrics for your [Containers](https://developers.cloudflare.com/containers/). Two endpoints are available:

- `containersMetricsAdaptiveGroups` returns metrics for the code running inside your container, including every process inside it. Use this endpoint to inspect CPU, memory, disk, network, and uptime behavior for your own workload.
- `containersUsageAdaptiveGroups` returns the resources consumed by your container together with the micro VM sandbox required to run it. These are the values that populate the usage estimates in the Cloudflare dashboard, and are the ones to use when estimating your billing costs.

Both endpoints share the same underlying dataset, but expose different slices of it.

Replace `<CLOUDFLARE_ACCOUNT_TAG>` and `<API_TOKEN>`<sup>[1](#user-content-fn-1)</sup> with your Account ID and API token, and adjust the `datetimeStart` and `datetimeEnd` values for the time range you want to query.

## Query container workload metrics

Use `containersMetricsAdaptiveGroups` to understand how your container and its subprocesses are behaving. The numbers returned reflect resource usage of your own code and do not include any platform overhead.

<details>

<summary>

Dimensions

</summary>

You can group results by any of the following dimensions:

| Dimension | Description |
| --- | --- |
| <code>instanceId</code> | The container instance ID. This is the same ID shown in the Cloudflare dashboard and by <a href="https://developers.cloudflare.com/workers/wrangler/">Wrangler</a>. |
| <code>placementId</code> | A single container instance can be placed in different locations over its lifetime (for example, when moved between data centers). Group by <code>placementId</code> to separate metrics across each placement. |
| <code>applicationId</code> | The Containers application the instance belongs to. |
| <code>location</code> | The Cloudflare data center where the container is running. |
| <code>region</code> | The region the container is running in. |
| <code>label(name: "...")</code> | The value of a specific container label. See <a href="#filter-and-group-by-labels">Filter and group by labels</a>. |
| <code>date</code>, <code>datetime</code>, <code>datetimeMinute</code>, <code>datetimeFiveMinutes</code>, <code>datetimeFifteenMinutes</code>, <code>datetimeHour</code>, <code>datetimeSixHours</code> | Time buckets of varying granularity. |

</details>

<details>

<summary>

Metrics

</summary>

The following metric groups are available. Each group exposes multiple fields — use GraphQL introspection or the <a href="https://developers.cloudflare.com/analytics/graphql-api/getting-started/explore-graphql-schema/">GraphQL API Explorer</a> to discover the full list.

| Group | Examples | Description |
| --- | --- | --- |
| <code>count</code> | — | Number of metric samples received. |
| <code>avg</code> | <code>memory</code>, <code>cpuUtilization</code>, <code>rxBandwidthBps</code>, <code>txBandwidthBps</code>, <code>gpuMemory</code>, <code>containerUptime</code> | Average of the metric over the selected time range. |
| <code>sum</code> | <code>cpuTimeSec</code>, <code>allocatedMemory</code>, <code>allocatedDisk</code>, <code>allocatedCpu</code>, <code>rxBytes</code>, <code>txBytes</code>, <code>containerUptime</code> | Total value of the metric over the selected time range. |
| <code>max</code> | <code>memory</code>, <code>cpuUtilization</code>, <code>diskUsage</code>, <code>diskUsagePercentage</code>, <code>rxBandwidthBps</code>, <code>txBandwidthBps</code>, <code>containerUptime</code> | Maximum observed value of the metric. |
| <code>quantiles</code> | <code>memory</code>, <code>cpuUtilization</code>, <code>rxBandwidthBps</code>, <code>txBandwidthBps</code>, <code>diskUsage</code>, <code>diskUsagePercentage</code>, <code>gpuMemory</code>, <code>containerUptime</code> | Weighted quantiles. Each metric is available with a <code>P50</code>, <code>P95</code>, or <code>P99</code> suffix (for example, <code>memoryP95</code>). |

</details>

### API call

The following query returns CPU time and peak memory usage for a single container instance, bucketed by hour:

```bash
echo '{ "query":
  "query ContainersMetrics($accountTag: String, $datetimeStart: Time, $datetimeEnd: Time, $instanceId: String) {
    viewer {
      accounts(filter: {accountTag: $accountTag}) {
        containersMetricsAdaptiveGroups(
          limit: 100
          filter: {
            datetime_geq: $datetimeStart,
            datetime_leq: $datetimeEnd,
            instanceId: $instanceId
          }
          orderBy: [datetimeHour_ASC]
        ) {
          dimensions {
            datetimeHour
            instanceId
          }
          sum {
            cpuTimeSec
          }
          max {
            memory
          }
          quantiles {
            cpuUtilizationP95
            memoryP95
          }
        }
      }
    }
  }",
  "variables": {
    "accountTag": "<CLOUDFLARE_ACCOUNT_TAG>",
    "datetimeStart": "2026-04-15T00:00:00Z",
    "datetimeEnd": "2026-04-16T00:00:00Z",
    "instanceId": "4c9b1b3c-8e8d-4a2d-9a3f-7f2b1c0a0e55"
  }
}' | tr -d '\n' | curl --silent \
https://api.cloudflare.com/client/v4/graphql \
--header "Authorization: Bearer <API_TOKEN>" \
--header "Accept: application/json" \
--header "Content-Type: application/json" \
--data @- | jq .
```

### Response

```json
{
	"data": {
		"viewer": {
			"accounts": [
				{
					"containersMetricsAdaptiveGroups": [
						{
							"dimensions": {
								"datetimeHour": "2026-04-15T00:00:00Z",
								"instanceId": "4c9b1b3c-8e8d-4a2d-9a3f-7f2b1c0a0e55"
							},
							"max": {
								"memory": 312475648
							},
							"quantiles": {
								"cpuUtilizationP95": 0.4821,
								"memoryP95": 298123264
							},
							"sum": {
								"cpuTimeSec": 128.47
							}
						},
						{
							"dimensions": {
								"datetimeHour": "2026-04-15T01:00:00Z",
								"instanceId": "4c9b1b3c-8e8d-4a2d-9a3f-7f2b1c0a0e55"
							},
							"max": {
								"memory": 305135616
							},
							"quantiles": {
								"cpuUtilizationP95": 0.3914,
								"memoryP95": 291454976
							},
							"sum": {
								"cpuTimeSec": 104.91
							}
						}
					]
				}
			]
		}
	},
	"errors": null
}
```

## Query container billing usage

Use `containersUsageAdaptiveGroups` to estimate your billing costs. Results include both your container's resource usage and the micro VM sandbox required to run it, and match the usage values shown in the Cloudflare dashboard.

<details>

<summary>

Dimensions

</summary>

You can group results by any of the following dimensions:

| Dimension | Description |
| --- | --- |
| <code>instanceId</code> | The container instance ID. This is the same ID shown in the Cloudflare dashboard and by <a href="https://developers.cloudflare.com/workers/wrangler/">Wrangler</a>. |
| <code>placementId</code> | A single container instance can be placed in different locations over its lifetime (for example, when moved between data centers). Group by <code>placementId</code> to separate metrics across each placement. |
| <code>applicationId</code> | The Containers application the instance belongs to. |
| <code>location</code> | The Cloudflare data center where the container is running. |
| <code>region</code> | The region the container is running in. |
| <code>label(name: "...")</code> | The value of a specific container label. See <a href="#filter-and-group-by-labels">Filter and group by labels</a>. |
| <code>date</code>, <code>datetime</code>, <code>datetimeMinute</code>, <code>datetimeFiveMinutes</code>, <code>datetimeFifteenMinutes</code>, <code>datetimeHour</code>, <code>datetimeSixHours</code> | Time buckets of varying granularity. |

</details>

<details>

<summary>

Metrics

</summary>

Only <code>sum</code> metrics are available:

| Field | Description |
| --- | --- |
| <code>cpuTimeSec</code> | Total CPU time, in seconds. |
| <code>allocatedMemory</code> | Total allocated memory, in byte-seconds. |
| <code>allocatedDisk</code> | Total allocated disk, in byte-seconds. |
| <code>txBytes</code> | Total bytes transmitted. |

</details>

### API call

The following query returns daily CPU and memory usage for the last 30 days:

```bash
echo '{ "query":
  "query ContainersUsage($accountTag: String, $datetimeStart: Time, $datetimeEnd: Time) {
    viewer {
      accounts(filter: {accountTag: $accountTag}) {
        containersUsageAdaptiveGroups(
          limit: 100
          filter: {
            date_geq: $datetimeStart,
            date_leq: $datetimeEnd
          }
          orderBy: [date_ASC]
        ) {
          dimensions {
            date
          }
          sum {
            cpuTimeSec
            allocatedMemory
            allocatedDisk
            txBytes
          }
        }
      }
    }
  }",
  "variables": {
    "accountTag": "<CLOUDFLARE_ACCOUNT_TAG>",
    "datetimeStart": "2026-03-23",
    "datetimeEnd": "2026-04-22"
  }
}' | tr -d '\n' | curl --silent \
https://api.cloudflare.com/client/v4/graphql \
--header "Authorization: Bearer <API_TOKEN>" \
--header "Accept: application/json" \
--header "Content-Type: application/json" \
--data @- | jq .
```

### Response

```json
{
	"data": {
		"viewer": {
			"accounts": [
				{
					"containersUsageAdaptiveGroups": [
						{
							"dimensions": {
								"date": "2026-04-20"
							},
							"sum": {
								"allocatedDisk": 172800000000000,
								"allocatedMemory": 22118400000000,
								"cpuTimeSec": 3742.18,
								"txBytes": 8471239
							}
						},
						{
							"dimensions": {
								"date": "2026-04-21"
							},
							"sum": {
								"allocatedDisk": 172800000000000,
								"allocatedMemory": 22118400000000,
								"cpuTimeSec": 3955.02,
								"txBytes": 9023841
							}
						}
					]
				}
			]
		}
	},
	"errors": null
}
```

## Filter and group by labels

Both endpoints expose container labels through two fields:

- `labels` is an array of `key=value` strings, and is designed for filtering. Use the [`_has` operator](https://developers.cloudflare.com/analytics/graphql-api/features/filtering/) to match a specific label.
- `label(name: "...")` is a grouping dimension that returns the value of a named label. Alias it to a convenient field name in your response.

For example, the following query returns CPU time and memory usage for production containers, grouped by environment:

```graphql
query ContainersByLabel(
	$accountTag: String
	$datetimeStart: Time
	$datetimeEnd: Time
) {
	viewer {
		accounts(filter: { accountTag: $accountTag }) {
			containersMetricsAdaptiveGroups(
				limit: 100
				filter: {
					datetime_geq: $datetimeStart
					datetime_leq: $datetimeEnd
					labels_has: "env=production"
				}
			) {
				dimensions {
					env: label(name: "env")
					region: label(name: "region")
				}
				sum {
					cpuTimeSec
				}
				max {
					memory
				}
			}
		}
	}
}
```

The aliased dimensions appear directly on each result:

```json
{
	"data": {
		"viewer": {
			"accounts": [
				{
					"containersMetricsAdaptiveGroups": [
						{
							"dimensions": {
								"env": "production",
								"region": "enam"
							},
							"max": { "memory": 412316672 },
							"sum": { "cpuTimeSec": 9812.41 }
						},
						{
							"dimensions": {
								"env": "production",
								"region": "weur"
							},
							"max": { "memory": 398458880 },
							"sum": { "cpuTimeSec": 7421.08 }
						}
					]
				}
			]
		}
	},
	"errors": null
}
```

## Footnotes

1. Refer to [Configure an Analytics API token](https://developers.cloudflare.com/analytics/graphql-api/getting-started/authentication/api-token-auth/) for more information on configuration and permissions. [↩](#user-content-fnref-1)

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/graphql-api/tutorials/querying-container-metrics/#page","headline":"Querying Containers metrics with GraphQL","description":"Query Cloudflare Containers metrics with the GraphQL Analytics API.","url":"https://developers.cloudflare.com/analytics/graphql-api/tutorials/querying-container-metrics/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/graphql-api/tutorials/querying-container-metrics/og.png?v=6a2e0f0adf373928","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Query Email Routing activity logs via GraphQL.
title: Querying Email Routing events with GraphQL
image: https://developers.cloudflare.com/analytics/graphql-api/tutorials/querying-email-routing/og.png?v=de674f74af6e3fc7
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Querying Email Routing events with GraphQL

Last updated Jun 9, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/graphql-api/tutorials/querying-email-routing/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

This example uses the GraphQL Analytics API to query for Email Routing events over a specified time period.

## Activity logs API call

The following API call will request Email Routing activity logs over a one day period, and output the requested fields. Be sure to replace `<CLOUDFLARE_ZONE_TAG>` and `<API_TOKEN>`<sup>[1](#user-content-fn-1)</sup> with your zone tag and API credentials, and adjust the `datetime_geg` and `datetime_leq` values as required.

```bash
echo '{ "query":
  "query EmailRoutingActivity($zoneTag: string, $filter: EmailRoutingAdaptiveFilter_InputObject) {
    viewer {
      zones(filter: { zoneTag: $zoneTag }) {
        emailRoutingAdaptive(
          filter: $filter
          limit: 3
          orderBy: [datetime_DESC]
        ) {
          datetime
          id: sessionId
          messageId
          from
          to
          subject
          status
          action
          spf
          dkim
          dmarc
          arc
          errorDetail
          isNDR
          isSpam
          spamThreshold
          spamScore
        }
      }
    }
  }",
  "variables": {
    "zoneTag": "<CLOUDFLARE_ZONE_TAG>",
    "filter": {
      "datetime_geq": "2026-01-18T11:00:00Z",
      "datetime_leq": "2026-01-19T11:00:00Z"
    }
  }
}' | tr -d '\n' | curl --silent \
https://api.cloudflare.com/client/v4/graphql \
--header "Authorization: Bearer <API_TOKEN>" \
--header "Accept: application/json" \
--header "Content-Type: application/json" \
--data @- | jq .
```

The results returned will be in JSON (as requested):

```json
{
  "data": {
    "viewer": {
      "zones": [
        {
          "emailRoutingAdaptive": [
            {
              "action": "forward",
              "arc": "none",
              "datetime": "2026-01-19T10:51:25Z",
              "dkim": "pass",
              "dmarc": "pass",
              "errorDetail": "",
              "from": "John <john@email.example.com>",
              "id": "AfWyaZ7V1TAH",
              "isNDR": 0,
              "isSpam": 0,
              "messageId": "<9e6574f1-97f8-4060-ad62-c54b6408ac3f@local>",
              "spamScore": 0,
              "spamThreshold": 5,
              "spf": "pass",
              "status": "delivered",
              "subject": "How are you doing?",
              "to": "me@example.com"
            },
            {
              "action": "forward",
              "arc": "none",
              "datetime": "2026-01-19T10:30:00Z",
              "dkim": "pass",
              "dmarc": "pass",
              "errorDetail": "",
              "from": "eBay <ebay@ebay.co.uk>",
              "id": "aYPegrIfLWia",
              "isNDR": 0,
              "isSpam": 0,
              "messageId": "<1A513C40-F2CD808A928-029BBE999993-0000000000FA8855@starship>",
              "spamScore": 0,
              "spamThreshold": 5,
              "spf": "pass",
              "status": "delivered",
              "subject": "New offers",
              "to": "me@example.com"
            },
            {
              "action": "forward",
              "arc": "none",
              "datetime": "2026-01-19T10:29:59Z",
              "dkim": "pass",
              "dmarc": "pass",
              "errorDetail": "",
              "from": "Notification <notifications@example.com>",
              "id": "nWIl9gs95mY3",
              "isNDR": 0,
              "isSpam": 0,
              "messageId": "<0AB8F1C3-3015EDF2980-019BBE9B58F2-0000000000FA7C4D@local>",
              "spamScore": 0,
              "spamThreshold": 5,
              "spf": "pass",
              "status": "delivered",
              "subject": "You're over quota",
              "to": "me@example.com"
            }
          ]
        }
      ]
    }
  },
  "errors": null
}
```

## Analytics API Call

The following API call will count the number of events grouped by hour.

```bash
echo '{ "query":
  "query EmailRoutingActivity($zoneTag: string, $filter: EmailRoutingAdaptiveFilter_InputObject) {
     viewer {
       zones(filter: { zoneTag: $zoneTag }) {
         emailRoutingAdaptiveGroups(
           limit: 10000
           filter: $filter
           orderBy: [datetimeHour_ASC]
         ) { count
               dimensions {
                 datetimeHour
               }
             }
           }
     }
  }",
  "variables": {
    "zoneTag": "<CLOUDFLARE_ZONE_TAG>",
    "filter": {
      "datetimeHour_geq": "2026-01-18T11:00:00Z",
      "datetimeHour_leq": "2026-01-19T11:00:00Z"
    }
  }
}' | tr -d '\n' | curl --silent \
https://api.cloudflare.com/client/v4/graphql \
--header "Authorization: Bearer <API_TOKEN>" \
--header "Accept: application/json" \
--header "Content-Type: application/json" \
--data @- | jq .
```

The results returned will be in JSON (as requested):

```json
{
  "data": {
    "viewer": {
      "zones": [
        {
          "emailRoutingAdaptiveGroups": [
            {
              "count": 2,
              "dimensions": {
                "datetimeHour": "2026-01-18T11:00:00Z"
              }
            },
            {
              "count": 1,
              "dimensions": {
                "datetimeHour": "2026-01-18T12:00:00Z"
              }
            },
            {
              "count": 1,
              "dimensions": {
                "datetimeHour": "2026-01-18T13:00:00Z"
              }
            },
            {
              "count": 2,
              "dimensions": {
                "datetimeHour": "2026-01-18T14:00:00Z"
              }
            },
            {
              "count": 1,
              "dimensions": {
                "datetimeHour": "2026-01-18T15:00:00Z"
              }
            },
            {
              "count": 1,
              "dimensions": {
                "datetimeHour": "2026-01-18T16:00:00Z"
              }
            },
            {
              "count": 2,
              "dimensions": {
                "datetimeHour": "2026-01-18T17:00:00Z"
              }
            },
            {
              "count": 3,
              "dimensions": {
                "datetimeHour": "2026-01-18T18:00:00Z"
              }
            },
            {
              "count": 1,
              "dimensions": {
                "datetimeHour": "2026-01-18T22:00:00Z"
              }
            },
            {
              "count": 2,
              "dimensions": {
                "datetimeHour": "2026-01-19T01:00:00Z"
              }
            },
            {
              "count": 1,
              "dimensions": {
                "datetimeHour": "2026-01-19T02:00:00Z"
              }
            },
            {
              "count": 4,
              "dimensions": {
                "datetimeHour": "2026-01-19T05:00:00Z"
              }
            },
            {
              "count": 1,
              "dimensions": {
                "datetimeHour": "2026-01-19T08:00:00Z"
              }
            },
            {
              "count": 5,
              "dimensions": {
                "datetimeHour": "2026-01-19T09:00:00Z"
              }
            },
            {
              "count": 6,
              "dimensions": {
                "datetimeHour": "2026-01-19T10:00:00Z"
              }
            },
            {
              "count": 2,
              "dimensions": {
                "datetimeHour": "2026-01-19T11:00:00Z"
              }
            }
          ]
        }
      ]
    }
  },
  "errors": null
}
```

## Footnotes

1. Refer to [Configure an Analytics API token](https://developers.cloudflare.com/analytics/graphql-api/getting-started/authentication/api-token-auth/) for more information on configuration and permissions. [↩](#user-content-fnref-1)

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/graphql-api/tutorials/querying-email-routing/#page","headline":"Querying Email Routing events with GraphQL","description":"Query Email Routing activity logs via GraphQL.","url":"https://developers.cloudflare.com/analytics/graphql-api/tutorials/querying-email-routing/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/graphql-api/tutorials/querying-email-routing/og.png?v=de674f74af6e3fc7","dateModified":"2026-06-09","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Query WAF firewall events via GraphQL.
title: Querying Firewall Events with GraphQL
image: https://developers.cloudflare.com/analytics/graphql-api/tutorials/querying-firewall-events/og.png?v=20f54987574f99dc
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Querying Firewall Events with GraphQL

Last updated May 7, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/graphql-api/tutorials/querying-firewall-events/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

In this example, we are going to use the GraphQL Analytics API to query for Firewall Events over a specified time period.

The following API call will request Firewall Events over a one hour period, and output the requested fields. Be sure to replace `<CLOUDFLARE_ZONE_TAG>`, `<EMAIL>`, and `<API_TOKEN>`<sup>[1](#user-content-fn-1)</sup> with your zone tag and API credentials, and adjust the `datetime_geg` and `datetime_leq` values to your liking.

## API Call

```bash
echo '{ "query":
  "query ListFirewallEvents($zoneTag: string, $filter: FirewallEventsAdaptiveFilter_InputObject) {
    viewer {
      zones(filter: { zoneTag: $zoneTag }) {
        firewallEventsAdaptive(
          filter: $filter
          limit: 10
          orderBy: [datetime_DESC]
        ) {
          action
          clientAsn
          clientCountryName
          clientIP
          clientRequestPath
          clientRequestQuery
          datetime
          source
          userAgent
        }
      }
    }
  }",
  "variables": {
    "zoneTag": "<CLOUDFLARE_ZONE_TAG>",
    "filter": {
      "datetime_geq": "2022-07-24T11:00:00Z",
      "datetime_leq": "2022-07-24T12:00:00Z"
    }
  }
}' | tr -d '\n' | curl --silent \
https://api.cloudflare.com/client/v4/graphql \
--header "Authorization: Bearer <API_TOKEN>" \
--header "Accept: application/json" \
--header "Content-Type: application/json" \
--data @-
```

The results returned will be in JSON (as requested), so piping the output to `jq` will make them easier to read, for example:

```bash
... | curl --silent \
https://api.cloudflare.com/client/v4/graphql \
--header "Authorization: Bearer <API_TOKEN>" \
--header "Accept: application/json" \
--header "Content-Type: application/json" \
--data @- | jq .

#=> {
#=>   "data": {
#=>     "viewer": {
#=>       "zones": [
#=>         {
#=>           "firewallEventsAdaptive": [
#=>             {
#=>               "action": "log",
#=>               "clientAsn": "5089",
#=>               "clientCountryName": "GB",
#=>               "clientIP": "203.0.113.69",
#=>               "clientRequestPath": "/%3Cscript%3Ealert()%3C/script%3E",
#=>               "clientRequestQuery": "",
#=>               "datetime": "2020-04-24T10:11:24Z",
#=>               "source": "waf",
#=>               "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36"
#=>             },
#=>             {
#=>               "action": "log",
#=>               "clientAsn": "5089",
#=>               "clientCountryName": "GB",
#=>               "clientIP": "203.0.113.69",
#=>               "clientRequestPath": "/%3Cscript%3Ealert()%3C/script%3E",
#=>               "clientRequestQuery": "",
#=>               "datetime": "2020-04-24T10:11:24Z",
#=>               "source": "waf",
#=>               "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36"
#=>             },
#=>             {
#=>               "action": "log",
#=>               "clientAsn": "5089",
#=>               "clientCountryName": "GB",
#=>               "clientIP": "203.0.113.69",
#=>               "clientRequestPath": "/%3Cscript%3Ealert()%3C/script%3E",
#=>               "clientRequestQuery": "",
#=>               "datetime": "2020-04-24T10:11:24Z",
#=>               "source": "waf",
#=>               "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36"
#=>             },
#=>             {
#=>               "action": "log",
#=>               "clientAsn": "5089",
#=>               "clientCountryName": "GB",
#=>               "clientIP": "203.0.113.69",
#=>               "clientRequestPath": "/%3Cscript%3Ealert()%3C/script%3E",
#=>               "clientRequestQuery": "",
#=>               "datetime": "2020-04-24T10:11:24Z",
#=>               "source": "waf",
#=>               "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36"
#=>             },
#=>             {
#=>               "action": "log",
#=>               "clientAsn": "5089",
#=>               "clientCountryName": "GB",
#=>               "clientIP": "203.0.113.69",
#=>               "clientRequestPath": "/%3Cscript%3Ealert()%3C/script%3E",
#=>               "clientRequestQuery": "",
#=>               "datetime": "2020-04-24T10:11:24Z",
#=>               "source": "waf",
#=>               "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36"
#=>             },
#=>             {
#=>               "action": "log",
#=>               "clientAsn": "5089",
#=>               "clientCountryName": "GB",
#=>               "clientIP": "203.0.113.69",
#=>               "clientRequestPath": "/%3Cscript%3Ealert()%3C/script%3E",
#=>               "clientRequestQuery": "",
#=>               "datetime": "2020-04-24T10:11:24Z",
#=>               "source": "waf",
#=>               "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36"
#=>             },
#=>             {
#=>               "action": "log",
#=>               "clientAsn": "5089",
#=>               "clientCountryName": "GB",
#=>               "clientIP": "203.0.113.69",
#=>               "clientRequestPath": "/%3Cscript%3Ealert()%3C/script%3E",
#=>               "clientRequestQuery": "",
#=>               "datetime": "2020-04-24T10:11:24Z",
#=>               "source": "waf",
#=>               "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36"
#=>             },
#=>             {
#=>               "action": "block",
#=>               "clientAsn": "5089",
#=>               "clientCountryName": "GB",
#=>               "clientIP": "203.0.113.69",
#=>               "clientRequestPath": "/%3Cscript%3Ealert()%3C/script%3E",
#=>               "clientRequestQuery": "",
#=>               "datetime": "2020-04-24T10:11:24Z",
#=>               "source": "waf",
#=>               "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36"
#=>             },
#=>             {
#=>               "action": "log",
#=>               "clientAsn": "58224",
#=>               "clientCountryName": "IR",
#=>               "clientIP": "2.183.175.37",
#=>               "clientRequestPath": "/api/v2",
#=>               "clientRequestQuery": "",
#=>               "datetime": "2020-04-24T10:00:54Z",
#=>               "source": "waf",
#=>               "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36"
#=>             },
#=>             {
#=>               "action": "log",
#=>               "clientAsn": "58224",
#=>               "clientCountryName": "IR",
#=>               "clientIP": "2.183.175.37",
#=>               "clientRequestPath": "/api/v2",
#=>               "clientRequestQuery": "",
#=>               "datetime": "2020-04-24T10:00:54Z",
#=>               "source": "waf",
#=>               "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36"
#=>             }
#=>           ]
#=>         }
#=>       ]
#=>     }
#=>   },
#=>   "errors": null
#=> }
```

## Retention and query window

The `firewallEventsAdaptive` dataset, which powers [Security Events](https://developers.cloudflare.com/waf/analytics/security-events/), has different data retention limits from the datasets used in [Security Analytics](https://developers.cloudflare.com/waf/analytics/security-analytics/#limits). Queries that exceed the data retention window return an error similar to the following:

```txt
cannot request data older than 2678400s
```

For more information on the limits per plan for the `firewallEventsAdaptive` dataset, refer to [Security Events](https://developers.cloudflare.com/waf/analytics/security-events/#availability).

To discover the exact limits for your zone programmatically, query the `settings` node:

```graphql
{
	viewer {
		zones(filter: { zoneTag: "<CLOUDFLARE_ZONE_TAG>" }) {
			settings {
				firewallEventsAdaptive {
					maxDuration
					maxPageSize
					notOlderThan
				}
				httpRequestsAdaptive {
					maxDuration
					maxPageSize
					notOlderThan
				}
			}
		}
	}
}
```

For more on the `settings` node, refer to [Settings node](https://developers.cloudflare.com/analytics/graphql-api/features/discovery/settings/).

## Footnotes

1. Refer to [Configure an Analytics API token](https://developers.cloudflare.com/analytics/graphql-api/getting-started/authentication/api-token-auth/) for more information on configuration and permissions. [↩](#user-content-fnref-1)

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/graphql-api/tutorials/querying-firewall-events/#page","headline":"Querying Firewall Events with GraphQL","description":"Query WAF firewall events via GraphQL.","url":"https://developers.cloudflare.com/analytics/graphql-api/tutorials/querying-firewall-events/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/graphql-api/tutorials/querying-firewall-events/og.png?v=20f54987574f99dc","dateModified":"2026-05-07","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Query Magic Transit endpoint health checks.
title: Querying Magic Transit endpoint health check results with GraphQL
image: https://developers.cloudflare.com/analytics/graphql-api/tutorials/querying-magic-transit-endpoint-healthcheck-results/og.png?v=23bb76f6d9ac8f54
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Querying Magic Transit endpoint health check results with GraphQL

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/graphql-api/tutorials/querying-magic-transit-endpoint-healthcheck-results/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

Use the [GraphQL Analytics API](https://developers.cloudflare.com/analytics/graphql-api/) to query endpoint health check results for your account. The `magicEndpointHealthCheckAdaptiveGroups` dataset returns probe results aggregated by the dimensions and time interval you specify.

Send all GraphQL queries as HTTP `POST` requests to `https://api.cloudflare.com/client/v4/graphql`.

### Prerequisites

You need the following to query endpoint health check data:

- Your [account ID](https://developers.cloudflare.com/fundamentals/account/find-account-and-zone-ids/).
- An [API token](https://developers.cloudflare.com/fundamentals/api/get-started/create-token/) with `Account > Account Analytics > Read` permissions. For details, refer to [Configure an Analytics API token](https://developers.cloudflare.com/analytics/graphql-api/getting-started/authentication/api-token-auth/).

### Query parameters

The following parameters are some of the most common ones in the `filter` object:

| Parameter | Description |
| --- | --- |
| `date_geq` | Start date for the query in `YYYY-MM-DD` format (for example, `2026-01-01`). When used with a date-based truncation dimension, returns results from this date onward. You can also use a full ISO 8601 timestamp (for example, `2026-01-01T00:00:00Z`). |
| `date_leq` | *(Optional)* End date for the query. Uses the same format as `date_geq`. |
| `datetime_geq` | *(Optional)* Start timestamp in ISO 8601 format (for example, `2026-01-01T00:00:00Z`). Use instead of `date_geq` for time-based truncation dimensions. |
| `datetime_leq` | *(Optional)* End timestamp in ISO 8601 format. |
| `limit` | Maximum number of result groups to return. |

You can also filter on any dimension listed in the [Available dimensions](#available-dimensions) table. Append an operator suffix to the dimension name to create a filter — for example, `endpoint_in` to filter by a list of endpoints, or `checkType_neq` to exclude a specific check type. Using a dimension name without a suffix filters for equality. For the full list of supported operators, refer to [Filtering](https://developers.cloudflare.com/analytics/graphql-api/features/filtering/).

### Available dimensions

You can query the following dimensions in the `dimensions` field:

| Dimension | Description |
| --- | --- |
| `checkId` | The unique ID of the configured health check. |
| `checkType` | The type of health check (for example, `icmp`). |
| `endpoint` | The IP address of the endpoint being checked. |
| `name` | The name assigned to the health check when configured (may be empty if not set). |
| `date` | Event timestamp truncated to the day. |
| `datetime` | Full event timestamp. |
| `datetimeMinute` | Event timestamp truncated to the minute. |
| `datetimeFiveMinutes` | Event timestamp truncated to five-minute intervals. |
| `datetimeFifteenMinutes` | Event timestamp truncated to 15-minute intervals. |
| `datetimeHalfOfHour` | Event timestamp truncated to 30-minute intervals. |
| `datetimeHour` | Event timestamp truncated to the hour. |

### Available metrics

| Metric | Description |
| --- | --- |
| `count` | Total number of health check events in the group. |
| `sum.total` | Total number of health check probes sent. |
| `sum.failures` | Number of failed health check probes. |
| `avg.lossPercentage` | Average calculated loss percentage (0-100). |

### API call

The following example queries endpoint health check results for a specific account, returning probe counts aggregated in five-minute intervals. Replace `<ACCOUNT_ID>` with your [account ID](https://developers.cloudflare.com/fundamentals/account/find-account-and-zone-ids/) and `<API_TOKEN>` with your [API token](https://developers.cloudflare.com/analytics/graphql-api/getting-started/authentication/api-token-auth/).

```bash
echo '{ "query":
  "query GetEndpointHealthCheckResults($accountTag: string, $datetimeStart: string) {
    viewer {
      accounts(filter: {accountTag: $accountTag}) {
        magicEndpointHealthCheckAdaptiveGroups(
          filter: {
            datetime_geq: $datetimeStart
          }
          limit: 10
        ) {
          count
          dimensions {
            checkId
            checkType
            endpoint
            datetimeFiveMinutes
          }
          sum {
            failures
            total
          }
        }
      }
    }
  }",
  "variables": {
    "accountTag": "<ACCOUNT_ID>",
    "datetimeStart": "2026-01-21T00:00:00Z"
  }
}' | tr -d '\n' | curl --silent \
https://api.cloudflare.com/client/v4/graphql \
--header "Authorization: Bearer <API_TOKEN>" \
--header "Accept: application/json" \
--header "Content-Type: application/json" \
--data @-
```

Pipe the output to `jq` to format the JSON response for easier reading:

```bash
... | curl --silent \
https://api.cloudflare.com/client/v4/graphql \
--header "Authorization: Bearer <API_TOKEN>" \
--header "Accept: application/json" \
--header "Content-Type: application/json" \
--data @- | jq .
```

### Example response

```json
{
  "data": {
    "viewer": {
      "accounts": [
        {
          "magicEndpointHealthCheckAdaptiveGroups": [
            {
              "count": 288,
              "dimensions": {
                "checkId": "90b478c7-bb51-4640-b94b-2c3050e9fa00",
                "checkType": "icmp",
                "datetimeFiveMinutes": "2026-01-21T12:00:00Z",
                "endpoint": "103.21.244.100"
              },
              "sum": {
                "failures": 0,
                "total": 288
              }
            },
            {
              "count": 288,
              "dimensions": {
                "checkId": "90b478c7-bb51-4640-b94b-2c3050e9fa00",
                "checkType": "icmp",
                "datetimeFiveMinutes": "2026-01-21T12:05:00Z",
                "endpoint": "103.21.244.100"
              },
              "sum": {
                "failures": 2,
                "total": 288
              }
            }
          ]
        }
      ]
    }
  },
  "errors": null
}
```

In this response, `sum.total` is the number of probes sent during the interval and `sum.failures` is the number that did not receive a reply. A `failures` value of `0` indicates the endpoint was fully reachable during that period.

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/graphql-api/tutorials/querying-magic-transit-endpoint-healthcheck-results/#page","headline":"Querying Magic Transit endpoint health check results with GraphQL","description":"Query Magic Transit endpoint health checks.","url":"https://developers.cloudflare.com/analytics/graphql-api/tutorials/querying-magic-transit-endpoint-healthcheck-results/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/graphql-api/tutorials/querying-magic-transit-endpoint-healthcheck-results/og.png?v=23bb76f6d9ac8f54","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Query Magic Transit tunnel bandwidth analytics.
title: Querying Magic Transit and Cloudflare WAN IPsec/GRE tunnel bandwidth analytics with GraphQL
image: https://developers.cloudflare.com/analytics/graphql-api/tutorials/querying-magic-transit-tunnel-bandwidth-analytics/og.png?v=5361cd0d1a49e5d4
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Querying Magic Transit and Cloudflare WAN IPsec/GRE tunnel bandwidth analytics with GraphQL

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/graphql-api/tutorials/querying-magic-transit-tunnel-bandwidth-analytics/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

This example uses the GraphQL Analytics API to query Magic Transit or Cloudflare WAN ingress tunnel traffic over a specified time period.

The following API call requests Magic Transit or Cloudflare WAN ingress tunnel traffic over a one-hour period and outputs the requested fields. Replace `<CLOUDFLARE_ACCOUNT_TAG>` with your account ID, `<EMAIL>`, `<API_KEY>`<sup>[1](#user-content-fn-1)</sup> (legacy), or `<API_TOKEN>`<sup>[2](#user-content-fn-2)</sup> (preferred) with your API credentials, and adjust the `datetime_geq` and `datetime_leq` values as needed.

The example queries for ingress traffic. To query for egress traffic, change the value in the `direction` filter.

## API Call

```bash
PAYLOAD='{ "query":
  "query GetTunnelHealthCheckResults($accountTag: string, $datetimeStart: string, $datetimeEnd: string) {
      viewer {
        accounts(filter: {accountTag: $accountTag}) {
          magicTransitTunnelTrafficAdaptiveGroups(
            limit: 100,
            filter: {
              datetime_geq: $datetimeStart,
              datetime_lt:  $datetimeEnd,
              direction: $direction
            }
          ) {
            avg {
              bitRateFiveMinutes
            }
            dimensions {
              tunnelName
              datetimeFiveMinutes
            }
          }
        }
      }
  }",
    "variables": {
      "accountTag": "<CLOUDFLARE_ACCOUNT_TAG>",
      "direction": "ingress",
      "datetimeStart": "2022-05-04T11:00:00.000Z",
      "datetimeEnd": "2022-05-04T12:00:00.000Z"
    }
  }
}'

# curl with Legacy API Key
curl https://api.cloudflare.com/client/v4/graphql \
--header "X-Auth-Email: <EMAIL>" \
--header "X-Auth-Key: <API_KEY>" \
--header "Accept: application/json" \
--header "Content-Type: application/json" \
--data "$(echo $PAYLOAD)"

# curl with API Token
curl https://api.cloudflare.com/client/v4/graphql \
--header "Authorization: Bearer <API_TOKEN>" \
--header "Accept: application/json" \
--header "Content-Type: application/json" \
--data "$(echo $PAYLOAD)"
```

The returned values represent the total bandwidth in bits per second during the five-minute interval for a particular tunnel. To use aggregations other than five minutes, use the same time window for both your metric and datetime. For example, to analyze hourly groups, use `bitRateHour` and `datetimeHour`.

The result is in JSON (as requested), so piping the output to `jq` formats it for easier parsing, as in the following example:

```bash
curl https://api.cloudflare.com/client/v4/graphql \
--header "Authorization: Bearer <API_TOKEN>" \
--header "Accept: application/json" \
--header "Content-Type: application/json" \
--data "$(echo $PAYLOAD)" | jq .

## Example response:
#=> {
#=>   "data": {
#=>     "viewer": {
#=>       "accounts": [
#=>         {
#=>           "magicTransitTunnelTrafficAdaptiveGroups": [
#=>             {
#=>               avg: { bitRateFiveMinutes:  327680 },
#=>               dimensions: {
#=>                 datetimeFiveMinute: '2021-05-12T22:00-00:00',
#=>                 tunnelName: 'tunnel_name'
#=>               }
#=>             },
#=>             {
#=>               avg: { bitRateFiveMinutes:  627213680 },
#=>               dimensions: {
#=>                 datetimeFiveMinute: '2021-05-12T22:05-00:00',
#=>                 tunnelName: 'another_tunnel'
#=>              }
#=>             }
#=>           ]
#=>         }
#=>       ]
#=>     }
#=>   },
#=>   "errors": null
#=> }
```

## Footnotes

1. For details, refer to [Authenticate with a Cloudflare API key](https://developers.cloudflare.com/analytics/graphql-api/getting-started/authentication/api-key-auth/). [↩](#user-content-fnref-1)
2. For details, refer to [Configure an Analytics API token](https://developers.cloudflare.com/analytics/graphql-api/getting-started/authentication/api-token-auth/). [↩](#user-content-fnref-2)

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/graphql-api/tutorials/querying-magic-transit-tunnel-bandwidth-analytics/#page","headline":"Querying Magic Transit and Cloudflare WAN IPsec/GRE tunnel bandwidth analytics with GraphQL","description":"Query Magic Transit tunnel bandwidth analytics.","url":"https://developers.cloudflare.com/analytics/graphql-api/tutorials/querying-magic-transit-tunnel-bandwidth-analytics/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/graphql-api/tutorials/querying-magic-transit-tunnel-bandwidth-analytics/og.png?v=5361cd0d1a49e5d4","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Query Magic Transit tunnel health check results.
title: Querying Magic Transit and Cloudflare WAN IPsec/GRE tunnel health check results with GraphQL
image: https://developers.cloudflare.com/analytics/graphql-api/tutorials/querying-magic-transit-tunnel-healthcheck-results/og.png?v=7aa732dfe0477855
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Querying Magic Transit and Cloudflare WAN IPsec/GRE tunnel health check results with GraphQL

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/graphql-api/tutorials/querying-magic-transit-tunnel-healthcheck-results/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

This example uses the GraphQL Analytics API to query Magic Transit or Cloudflare WAN tunnel health check results. These results are aggregated from individual health checks that Cloudflare servers perform against the tunnels you configured in your account. You can query up to one week of data for dates up to three months in the past.

The following API call requests tunnel health checks for a specific account over a one-day period for a specific Cloudflare data center and outputs the requested fields. Replace `<CLOUDFLARE_ACCOUNT_TAG>` and `<API_TOKEN>`<sup>[1](#user-content-fn-1)</sup> with your API credentials, and adjust the `datetimeStart` and `datetimeEnd` variables as needed.

The API call returns tunnel health check results by Cloudflare data center. Cloudflare aggregates each data center's result from health checks conducted on individual servers. The `tunnelState` field represents the state of the tunnel. Magic Transit or Cloudflare WAN uses these states for routing. A `tunnelState` value of `0` represents a down tunnel, `0.5` represents a degraded tunnel, and `1` represents a healthy tunnel.

## API Call

```bash
echo '{ "query":
  "query GetTunnelHealthCheckResults($accountTag: string, $datetimeStart: string, $datetimeEnd: string) {
    viewer {
      accounts(filter: {accountTag: $accountTag}) {
        magicTransitTunnelHealthChecksAdaptiveGroups(
          limit: 100,
          filter: {
            datetime_geq: $datetimeStart,
            datetime_lt:  $datetimeEnd,
          }
        ) {
          avg {
            tunnelState
          }
          dimensions {
            tunnelName
            edgeColoName
          }
        }
      }
    }
  }",
  "variables": {
    "accountTag": "<CLOUDFLARE_ACCOUNT_TAG>",
    "datetimeStart": "2022-08-04T00:00:00.000Z",
    "datetimeEnd": "2022-08-04T01:00:00.000Z"
  }
}' | tr -d '\n' | curl --silent \
https://api.cloudflare.com/client/v4/graphql \
--header "Authorization: Bearer <API_TOKEN>" \
--header "Accept: application/json" \
--header "Content-Type: application/json" \
--data @-
```

The results are returned in JSON (as requested), so piping the output to `jq` formats them for easier parsing, as in the following example:

```bash
... | curl --silent \
https://api.cloudflare.com/client/v4/graphql \
--header "Authorization: Bearer <API_TOKEN>" \
--header "Accept: application/json" \
--header "Content-Type: application/json" \
--data @- | jq .

## Example response:
#=> {
#=>   "data": {
#=>     "viewer": {
#=>       "accounts": [
#=>         {
#=>           "conduitEdgeTunnelHealthChecks": [
#=>             {
#=>               {
#=>                 "avg": {
#=>                   "tunnelState": 1
#=>                 },
#=>                 "dimensions": {
#=>                   "edgeColoName": "mel01",
#=>                   "tunnelName": "tunnel_01",
#=>                   "tunnelState": 0.5
#=>                 }
#=>               },
#=>               {
#=>                 "avg": {
#=>                   "tunnelState": 0.5
#=>                 },
#=>                 "count": 310,
#=>                 "dimensions": {
#=>                   "edgeColoName": "mel01",
#=>                   "tunnelName": "tunnel_02",
#=>                   "tunnelState": 0.5
#=>                 }
#=>               }
#=>           ]
#=>         }
#=>       ]
#=>     }
#=>   },
#=>   "errors": null
#=> }
```

## Footnotes

1. For details, refer to [Configure an Analytics API token](https://developers.cloudflare.com/analytics/graphql-api/getting-started/authentication/api-token-auth/). [↩](#user-content-fnref-1)

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/graphql-api/tutorials/querying-magic-transit-tunnel-healthcheck-results/#page","headline":"Querying Magic Transit and Cloudflare WAN IPsec/GRE tunnel health check results with GraphQL","description":"Query Magic Transit tunnel health check results.","url":"https://developers.cloudflare.com/analytics/graphql-api/tutorials/querying-magic-transit-tunnel-healthcheck-results/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/graphql-api/tutorials/querying-magic-transit-tunnel-healthcheck-results/og.png?v=7aa732dfe0477855","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Query Network Firewall IDS samples via GraphQL.
title: Querying Cloudflare Network Firewall Intrusion Detection System (IDS) samples with GraphQL
image: https://developers.cloudflare.com/analytics/graphql-api/tutorials/querying-network-firewall-ids-samples/og.png?v=3db5361f7713b740
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Querying Cloudflare Network Firewall Intrusion Detection System (IDS) samples with GraphQL

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/graphql-api/tutorials/querying-network-firewall-ids-samples/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

In this example, we are going to use the GraphQL Analytics API to query for IDS samples over a specified time period.

The following API call will request IDS samples over a one hour period, and output the requested fields. Be sure to replace `<CLOUDFLARE_ACCOUNT_TAG>` and `<API_TOKEN>`<sup>[1](#user-content-fn-1)</sup> with your account tag and API credentials, and adjust the `datetime_geg` and `datetime_leq` values to your liking.

## API Call

```bash
echo '{ "query":
  "query IDSActivity {
    viewer {
      accounts(filter: { accountTag: $accountTag }) {
        magicIDPSNetworkAnalyticsAdaptiveGroups(
          filter: $filter
          limit: 10
        ) {
          sum {
            bits
            packets
          }
          dimensions {
            datetimeFiveMinutes
          }
        }
      }
    }
  }",
  "variables": {
    "accountTag": "<CLOUDFLARE_ACCOUNT_TAG>",
    "filter": {
      "datetime_geq": "2023-06-20T11:00:00.000Z",
      "datetime_leq": "2023-06-20T12:00:00.000Z",
      "verdict": "drop",
      "outcome": "pass"
    }
  }
}' | tr -d '\n' | curl --silent \
https://api.cloudflare.com/client/v4/graphql \
--header "Authorization: Bearer <API_TOKEN>" \
--header "Accept: application/json" \
--header "Content-Type: application/json" \
--data @-
```

The returned values represent the total number of packets and bits that matched IDS rules during the five minute interval. The result will be in JSON (as requested), so piping the output to `jq` will make it easier to read, like in the following example:

```bash
... | curl --silent \
https://api.cloudflare.com/client/v4/graphql \
--header "Authorization: Bearer <API_TOKEN>" \
--header "Accept: application/json" \
--header "Content-Type: application/json" \
--data @- | jq .

#=> {
#=>   "data": {
#=>     "viewer": {
#=>       "accounts": [
#=>         {
#=>           "magicIDPSNetworkAnalyticsAdaptiveGroups": [
#=>             {
#=>               sum: { bits:  327680, packets: 16384 },
#=>               dimensions: {
#=>                 datetimeFiveMinute: '2021-05-12T22:00-00:00'
#=>               }
#=>             },
#=>             {
#=>               sum: { bits:  360448, packets: 8192 },
#=>               dimensions: {
#=>                 datetimeFiveMinute: '2021-05-12T22:05-00:00'
#=>               }
#=>             },
#=>             {
#=>               sum: { bits:  327680, packets: 8192 },
#=>               dimensions: {
#=>                 datetimeFiveMinute: '2021-05-12T22:05-00:00'
#=>               }
#=>             },
#=>             {
#=>               sum: { bits:  360448, packets: 8192 },
#=>               dimensions: {
#=>                 datetimeFiveMinute: '2021-05-12T22:20-00:00'
#=>               }
#=>             },
#=>             {
#=>               sum: { bits:  327680, packets: 8192 },
#=>               dimensions: {
#=>                 datetimeFiveMinute: '2021-05-12T22:20-00:00'
#=>               }
#=>             }
#=>           ]
#=>         }
#=>       ]
#=>     }
#=>   },
#=>   "errors": null
#=> }
```

## Footnotes

1. Refer to [Configure an Analytics API token](https://developers.cloudflare.com/analytics/graphql-api/getting-started/authentication/api-token-auth/) for more information on configuration and permissions. [↩](#user-content-fnref-1)

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/graphql-api/tutorials/querying-network-firewall-ids-samples/#page","headline":"Querying Cloudflare Network Firewall Intrusion Detection System (IDS) samples with GraphQL","description":"Query Network Firewall IDS samples via GraphQL.","url":"https://developers.cloudflare.com/analytics/graphql-api/tutorials/querying-network-firewall-ids-samples/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/graphql-api/tutorials/querying-network-firewall-ids-samples/og.png?v=3db5361f7713b740","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Query Network Firewall packet samples via GraphQL.
title: Querying Cloudflare Network Firewall Samples with GraphQL
image: https://developers.cloudflare.com/analytics/graphql-api/tutorials/querying-network-firewall-samples/og.png?v=a6e67bf3ae0aaeda
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Querying Cloudflare Network Firewall Samples with GraphQL

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/graphql-api/tutorials/querying-network-firewall-samples/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

In this example, we are going to use the GraphQL Analytics API to query for Cloudflare Network Firewall Samples over a specified time period.

The following API call will request Cloudflare Network Firewall Samples over a one hour period, and output the requested fields. Be sure to replace `<CLOUDFLARE_ACCOUNT_TAG>` and `<API_TOKEN>`<sup>[1](#user-content-fn-1)</sup> with your zone tag and API credentials, and adjust the `datetime_geg` and `datetime_leq` values to your liking.

## API Call

```bash
echo '{ "query":
  "query MFWActivity {
    viewer {
      accounts(filter: { accountTag: $accountTag }) {
        magicFirewallSamplesAdaptiveGroups(
          filter: $filter
          limit: 10
          orderBy: [datetimeFiveMinute_DESC]
        ) {
          sum {
            bits
            packets
          }
          dimensions {
            datetimeFiveMinute
            ruleId
          }
        }
      }
    }
  }",
  "variables": {
    "accountTag": "<CLOUDFLARE_ACCOUNT_TAG>",
    "filter": {
      "datetime_geq": "2022-07-24T11:00:00Z",
      "datetime_leq": "2022-07-24T11:10:00Z"
    }
  }
}' | tr -d '\n' | curl --silent \
https://api.cloudflare.com/client/v4/graphql \
--header "Authorization: Bearer <API_TOKEN>" \
--header "Accept: application/json" \
--header "Content-Type: application/json" \
--data @-
```

The returned values represent the total number of packets and bits received during the five minute interval for a particular rule. The result will be in JSON (as requested), so piping the output to `jq` will make it easier to read, like in the following example:

```bash
... | curl --silent \
https://api.cloudflare.com/client/v4/graphql \
--header "Authorization: Bearer <API_TOKEN>" \
--header "Accept: application/json" \
--header "Content-Type: application/json" \
--data @- | jq .

#=> {
#=>   "data": {
#=>     "viewer": {
#=>       "accounts": [
#=>         {
#=>           "magicFirewallSamplesAdaptiveGroups": [
#=>             {
#=>               sum: { bits:  327680, packets: 16384 },
#=>               dimensions: {
#=>                 datetimeFiveMinute: '2021-05-12T22:00-00:00',
#=>                 ruleId: 'bdfa8f8f0ae142b4a70ef15f6160e532'
#=>               }
#=>             },
#=>             {
#=>               sum: { bits:  360448, packets: 8192 },
#=>               dimensions: {
#=>                 datetimeFiveMinute: '2021-05-12T22:05-00:00',
#=>                 ruleId: 'bdfa8f8f0ae142b4a70ef15f6160e532'
#=>               }
#=>             },
#=>             {
#=>               sum: { bits:  327680, packets: 8192 },
#=>               dimensions: {
#=>                 datetimeFiveMinute: '2021-05-12T22:05-00:00',
#=>                 ruleId: 'bdfa8f8f0ae142b4a70ef15f6160e532'
#=>               }
#=>             },
#=>             {
#=>               sum: { bits:  360448, packets: 8192 },
#=>               dimensions: {
#=>                 datetimeFiveMinute: '2021-05-12T22:20-00:00',
#=>                 ruleId: 'bdfa8f8f0ae142b4a70ef15f6160e532'
#=>               }
#=>             },
#=>             {
#=>               sum: { bits:  327680, packets: 8192 },
#=>               dimensions: {
#=>                 datetimeFiveMinute: '2021-05-12T22:20-00:00',
#=>                 ruleId: 'bdfa8f8f0ae142b4a70ef15f6160e532'
#=>               }
#=>             }
#=>           ]
#=>         }
#=>       ]
#=>     }
#=>   },
#=>   "errors": null
#=> }
```

## Footnotes

1. Refer to [Configure an Analytics API token](https://developers.cloudflare.com/analytics/graphql-api/getting-started/authentication/api-token-auth/) for more information on configuration and permissions. [↩](#user-content-fnref-1)

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/graphql-api/tutorials/querying-network-firewall-samples/#page","headline":"Querying Cloudflare Network Firewall Samples with GraphQL","description":"Query Network Firewall packet samples via GraphQL.","url":"https://developers.cloudflare.com/analytics/graphql-api/tutorials/querying-network-firewall-samples/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/graphql-api/tutorials/querying-network-firewall-samples/og.png?v=a6e67bf3ae0aaeda","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Query Workers invocation metrics via GraphQL.
title: Querying Workers Metrics with GraphQL
image: https://developers.cloudflare.com/analytics/graphql-api/tutorials/querying-workers-metrics/og.png?v=43480c3fa3568ce2
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Querying Workers Metrics with GraphQL

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/graphql-api/tutorials/querying-workers-metrics/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

In this example, we are going to use the GraphQL Analytics API to query for Workers Metrics over a specified time period. We can query up to one month of data for dates up to three months ago.

The following API call will request a Worker script's metrics over a one day period, and output the requested fields. Be sure to replace `<CLOUDFLARE_ACCOUNT_TAG>` and `<API_TOKEN>`<sup>[1](#user-content-fn-1)</sup> with your API credentials, and adjust the `datetimeStart`, `datetimeEnd`, and `scriptName` variables as needed.

## API Call

```bash
echo '{ "query":
  "query GetWorkersAnalytics($accountTag: string, $datetimeStart: string, $datetimeEnd: string, $scriptName: string) {
    viewer {
      accounts(filter: {accountTag: $accountTag}) {
        workersInvocationsAdaptive(limit: 100, filter: {
          scriptName: $scriptName,
          datetime_geq: $datetimeStart,
          datetime_leq: $datetimeEnd
        }) {
          sum {
            subrequests
            requests
            errors
          }
          quantiles {
            cpuTimeP50
            cpuTimeP99
          }
          dimensions{
            datetime
            scriptName
            status
          }
        }
      }
    }
  }",
  "variables": {
    "accountTag": "<CLOUDFLARE_ACCOUNT_TAG>",
    "datetimeStart": "2022-08-04T00:00:00.000Z",
    "datetimeEnd": "2022-08-04T01:00:00.000Z",
    "scriptName": "worker-subrequest-test-client"
  }
}' | tr -d '\n' | curl --silent \
https://api.cloudflare.com/client/v4/graphql \
--header "Authorization: Bearer <API_TOKEN>" \
--header "Accept: application/json" \
--header "Content-Type: application/json" \
--data @-
```

The results returned will be in JSON (as requested), so piping the output to `jq` will make them easier to read, like in the following example:

```bash
... | curl --silent \
https://api.cloudflare.com/client/v4/graphql \
--header "Authorization: Bearer <API_TOKEN>" \
--header "Accept: application/json" \
--header "Content-Type: application/json" \
--data @- | jq .

#=> {
#=>   "data": {
#=>     "viewer": {
#=>       "accounts": [
#=>         {
#=>           "workersInvocationsAdaptive": [
#=>             {
#=>               "dimensions": {
#=>                 "datetime": "2020-05-04T18:10:35Z",
#=>                 "scriptName": "worker-subrequest-test-client",
#=>                 "status": "success"
#=>               },
#=>               "quantiles": {
#=>                 "cpuTimeP50": 206,
#=>                 "cpuTimeP99": 206
#=>               },
#=>               "sum": {
#=>                 "errors": 0,
#=>                 "requests": 1,
#=>                 "subrequests": 0
#=>               }
#=>             },
#=>             {
#=>               "dimensions": {
#=>                 "datetime": "2020-05-04T18:10:34Z",
#=>                 "scriptName": "worker-subrequest-test-client",
#=>                 "status": "success"
#=>               },
#=>               "quantiles": {
#=>                 "cpuTimeP50": 291,
#=>                 "cpuTimeP99": 291
#=>               },
#=>               "sum": {
#=>                 "errors": 0,
#=>                 "requests": 1,
#=>                 "subrequests": 0
#=>               }
#=>             },
#=>             {
#=>               "dimensions": {
#=>                 "datetime": "2020-05-04T18:10:49Z",
#=>                 "scriptName": "worker-subrequest-test-client",
#=>                 "status": "success"
#=>               },
#=>               "quantiles": {
#=>                 "cpuTimeP50": 212.5,
#=>                 "cpuTimeP99": 261.19
#=>               },
#=>               "sum": {
#=>                 "errors": 0,
#=>                 "requests": 4,
#=>                 "subrequests": 0
#=>               }
#=>             }
#=>           ]
#=>         }
#=>       ]
#=>     }
#=>   },
#=>   "errors": null
#=> }
```

## Footnotes

1. Refer to [Configure an Analytics API token](https://developers.cloudflare.com/analytics/graphql-api/getting-started/authentication/api-token-auth/) for more information on configuration and permissions. [↩](#user-content-fnref-1)

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/graphql-api/tutorials/querying-workers-metrics/#page","headline":"Querying Workers Metrics with GraphQL","description":"Query Workers invocation metrics via GraphQL.","url":"https://developers.cloudflare.com/analytics/graphql-api/tutorials/querying-workers-metrics/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/graphql-api/tutorials/querying-workers-metrics/og.png?v=43480c3fa3568ce2","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Build dashboard widgets with GraphQL Analytics queries.
title: Use GraphQL to create widgets
image: https://developers.cloudflare.com/analytics/graphql-api/tutorials/use-graphql-create-widgets/og.png?v=a101899464ea62e8
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Use GraphQL to create widgets

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/graphql-api/tutorials/use-graphql-create-widgets/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

This article presents examples of queries you can use to populate your own dashboard.

- [Parameters and filters](#parameters-and-filters)
- [Timeseries graph](#timeseries-graph)
- [Activity log](#activity-log)
- [Top N cards - source](#top-n-cards---source)
- [Top N cards - destination](#top-n-cards---destination)
- [TCP Flags](#tcp-flags)
- [Executive summary](#executive-summary)

Use this workflow to build and test queries:

- Install and configure the [GraphiQL ↗︎](https://www.gatsbyjs.com/docs/how-to/querying-data/running-queries-with-graphiql/) app to authenticate to the Cloudflare Analytics GraphQL API. Cloudflare recommends token authentication. Refer to [Configure an Analytics API token](https://developers.cloudflare.com/analytics/graphql-api/getting-started/authentication/api-token-auth/), for more information.
- Construct the queries in the GraphiQL. You can use the introspective documentation in the GraphQL client to explore the nodes available. For further information about queries, refer to [Querying basics](https://developers.cloudflare.com/analytics/graphql-api/getting-started/querying-basics/).
- Test your queries by running them from GraphiQL or by passing them as the payload in a cURL request to the GraphQL API endpoint.
- Use the queries in your application to provide data for your dashboard widgets.

## Parameters and filters

These examples use the account ID for the Cloudflare account that you are querying. You can define this as a variable (`accountTag`) and reference it in your queries.

The queries also use a filter to specify the time interval that you want to query. The filter uses a start time and end time to define the time interval. You use different attributes to specify the start and end times, depending on the time period that you want to query. Refer to [Filtering](https://developers.cloudflare.com/analytics/graphql-api/features/filtering/) for further information about filters.

The following example queries for data with dates greater than or equal to `date_geq` and less than or equal to `date_leq`:

*Account and query time interval settingsjson*

```json
{
	"accountTag": "{account-id}",
	"filter": {
		"AND": [{ "date_geq": "2020-01-19" }, { "date_leq": "2020-01-20" }]
	}
}
```

This table lists Network Analytics datasets (nodes) and the `datetimeDimension` that you should use when querying data for a given time selection.

When you want an aggregated view of data, use the `Groups` query nodes. For example, the `ipFlows1mAttacksGroups` dataset represents minute-wise rollup reports of attack activity. For more detail, refer to [Datasets](https://developers.cloudflare.com/analytics/graphql-api/features/data-sets/).

| **Time Selection** | **Query node** | **datetimeDimension** |
| --- | --- | --- |
| Last week | ipFlows1dGroups | date |
| Last month | ipFlows1dGroups | date |
| 24 hours | ipFlows1mGroups | datetimeFifteenMinutes |
| 12 hours | ipFlows1mGroups | datetimeFifteenMinutes |
| 6 hours | ipFlows1mGroups | datetimeFiveMinutes |
| 30 mins | ipFlows1mGroups | datetimeMinute |
| Custom range | Dependent on range selected | Dependent on range selected |

The table below lists the start and end time attributes that are valid for query nodes representing different time ranges.

| **Query node** | **Start day / time filter** | **End day / time filter** |
| --- | --- | --- |
| ipFlows1mGroups | datetimeMinute\_geq | datetimeMinute\_leq |
| ipFlows1mAttacksGroups | date\_geq | date\_leq |
| ipFlows1hGroups | datetimeHour\_geq | datetimeHour\_leq |
| ipFlows1dGroups | date\_geq | date\_leq |

## Timeseries graph

Use the following query to build the timeseries graph in network analytics:

*Timeseries graphgraphql*

```graphql
query ipFlowTimeseries(
	$accountTag: string
	$filter: AccountIpFlows1mGroupsFilter_InputObject
) {
	viewer {
		accounts(filter: { accountTag: $accountTag }) {
			ipFlows1mGroups(
				limit: 1000
				filter: $filter
				orderBy: datetimeMinute_ASC
			) {
				dimensions {
					timestamp: datetimeMinute
					attackMitigationType
					attackId
				}
				sum {
					bits
					packets
				}
			}
		}
	}
}
```

## Activity log

This query returns an activity log summarizing minute-wise rollups of attack traffic in IP flows. The query groups the data by the fields listed in the `dimensions` object.

*Activity log querygraphql*

```graphql
query ipFlowEventLog(
	$accountTag: string
	$filter: AccountIpFlows1mAttacksGroupsFilter_InputObject
) {
	viewer {
		accounts(filter: { accountTag: $accountTag }) {
			ipFlows1mAttacksGroups(
				limit: 10
				filter: $filter
				orderBy: [min_datetimeMinute_ASC]
			) {
				dimensions {
					attackId
					attackDestinationIP
					attackDestinationPort
					attackMitigationType
					attackSourcePort
					attackType
				}
				avg {
					bitsPerSecond
					packetsPerSecond
				}
				min {
					datetimeMinute
					bitsPerSecond
					packetsPerSecond
				}
				max {
					datetimeMinute
					bitsPerSecond
					packetsPerSecond
				}
				sum {
					bits
					packets
				}
			}
		}
	}
}
```

## Top N cards - source

This query returns data about the top source IPs. The `limit` parameter controls the amount of records returned for each node. In the following code, the highlighted lines indicate where you configure `limit`.

*Top N Cards querygraphql*

```graphql
query GetTopNBySource(
    $accountTag: string
    $filter: AccountIpFlows1mGroupsFilter_InputObject
    $portFilter: AccountIpFlows1mGroupsFilter_InputObject
  ) {
    viewer {
      accounts(filter: { accountTag: $accountTag }) {
        topNPorts: ipFlows1mGroups(
        limit: 5
        filter: $portFilter
        orderBy: [sum_(bits/packets)_DESC]
      ) {
        sum {
          count: (bits/packets)
        }
        dimensions {
          metric: sourcePort
          ipProtocol
        }
      }
      topNASN: ipFlows1mGroups(
        limit: 5
        filter: $filter
        orderBy: [sum_(bits/packets)_DESC]
      ) {
        sum {
          count: (bits/packets)
        }
        dimensions {
          metric: sourceIPAsn
          description: sourceIPASNDescription
        }
      }
        topNIPs: ipFlows1mGroups(
        limit: 5
        filter: $filter
        orderBy: [sum_(bits/packets)_DESC]
      ) {
        sum {
          count: (bits/packets)
        }
        dimensions {
          metric: sourceIP
        }
      }
        topNColos: ipFlows1mGroups(
          limit: 10
          filter: $filter
          orderBy: [sum_(bits/packets)_DESC]
        ) {
          sum {
            count: (bits/packets)
          }
          dimensions {
            metric: coloCity
            coloCode
          }
        }
        topNCountries: ipFlows1mGroups(
          limit: 10
          filter: $filter
          orderBy: [sum_(bits/packets)_DESC]
        ) {
          sum {
            count: (bits/packets)
          }
          dimensions {
            metric: coloCountry
          }
        }
        topNIPVersions: ipFlows1mGroups(
          limit: 2
          filter: $filter
          orderBy: [sum_(bits/packets)_DESC]
        ) {
          sum {
            count: (bits/packets)
          }
          dimensions {
            metric: ipVersion
          }
        }
      }
    }
  }
```

## Top N cards - destination

This query returns data about the top destination IPs. The `limit` parameter controls the amount of records returned. In the following code, the highlighted lines indicate that the query returns the five highest results.

*Top N Cards - Destinationgraphql*

```graphql
query GetTopNByDestination(
    $accountTag: string
    $filter: AccountIpFlows1mGroupsFilter_InputObject
    $portFilter: AccountIpFlows1mGroupsFilter_InputObject
  ) {
    viewer {
      accounts(filter: { accountTag: $accountTag }) {
        topNIPs: ipFlows1mGroups(
          filter: $filter
          limit: 5
          orderBy: [sum_(bits/packets)_DESC]
        ) {
          sum {
            count: (bits/packets)
          }
          dimensions {
            metric: destinationIP
          }
        }
        topNPorts: ipFlows1mGroups(
          filter: $portFilter
          limit: 5
          orderBy: [sum_(bits/packets)_DESC]
        ) {
          sum {
            count: (bits/packets)
          }
          dimensions {
            metric: destinationPort
            ipProtocol
          }
        }
      }
    }
  }
```

## TCP Flags

This query extracts the number of TCP packets from the minute-wise rollups of IP flows, and groups the results by TCP flag value. It uses `limit: 8` to display the top eight results, and presents them in descending order.

Add the following line to the filter to indicate that you want to view TCP data:

```json
{ "ipProtocol": "TCP" }
```

*TCP Flags querygraphql*

```graphql
query GetTCPFlags(
    $accountTag: string
    $filter: AccountIpFlows1mGroupsFilter_InputObject
  ) {
    viewer {
      accounts(filter: { accountTag: $accountTag }) {
        tcpFlags: ipFlows1mGroups(
          filter: $filter
          limit: 8
          orderBy: [sum_(bits/packets)_DESC]
        ) {
          sum {
            count: (bits/packets)
          }
          dimensions {
            tcpFlags
          }
        }
      }
    }
  }
```

## Executive summary

The executive summary query summarizes overall activity, therefore it only filters by the selected time interval, and ignores all filters applied to the analytics. Use different queries, depending on the time interval you want to examine and what kind of traffic the account is seeing.

If the time interval is absolute, for example March 25th 09:00 to March 25th 17:00, then execute a query for attacks within those times. [Use the appropriate query node](#parameters-and-filters), for example `ipFlows1dGroups`, for the time interval.

*GetPreviousAttacks query - fetch previous attacksgraphql*

```graphql
query GetPreviousAttacks($accountTag: string, $filter: filter) {
  viewer {
    accounts(filter: {accountTag: $accountTag}) {
      ${queryNode}(limit: 1000, filter: $filter) {
        dimensions {
          attackId
        }
        sum {
          packets
          bits
        }
      }
    }
  }
}
```

If the time interval is relative to the current time, for example the last 24 hours or the last 30 minutes, then make a query to the `ipFlows1mGroup` node to check whether there were attacks in the past five minutes. Attacks within the past five minutes are classed as ongoing: the Activity Log displays `Present`. The query response lists the `attackID` values of ongoing attacks.

*GetOngoingAttackIds query - check for ongoing attacksgraphql*

```graphql
query GetOngoingAttackIds($accountTag: string, $filter: filter) {
	viewer {
		accounts(filter: { accountTag: $accountTag }) {
			ipFlows1mGroups(limit: 1000, filter: $filter) {
				dimensions {
					attackId
				}
			}
		}
	}
}
```

If there are ongoing attacks, query the `ipFlows1mAttacksGroups` node, filtering with the `attackID` values from the previous query. The query below returns the maximum bit and packet rates.

*GetOngoingAttacks query - fetch data for ongoing attacksgraphql*

```graphql
query GetOngoingAttacks($accountTag: string, $filter: filter) {
	viewer {
		accounts(filter: { accountTag: $accountTag }) {
			ipFlows1mAttacksGroups(limit: 1000, filter: $filter) {
				dimensions {
					attackId
				}
				max {
					bitsPerSecond
					packetsPerSecond
				}
			}
		}
	}
}
```

If there are no ongoing attacks, use the `GetPreviousAttacks` query to display data for attacks within an absolute time interval.

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/graphql-api/tutorials/use-graphql-create-widgets/#page","headline":"Use GraphQL to create widgets","description":"Build dashboard widgets with GraphQL Analytics queries.","url":"https://developers.cloudflare.com/analytics/graphql-api/tutorials/use-graphql-create-widgets/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/graphql-api/tutorials/use-graphql-create-widgets/og.png?v=a101899464ea62e8","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Send and query unlimited-cardinality analytics from Workers.
title: Workers Analytics Engine
image: https://developers.cloudflare.com/analytics/analytics-engine/og.png?v=dfb72c4220270535
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Workers Analytics Engine

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/analytics-engine/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

Workers Analytics Engine provides unlimited-cardinality analytics at scale, via [a built-in API](https://developers.cloudflare.com/analytics/analytics-engine/get-started/) to write data points from Workers, and a [SQL API](https://developers.cloudflare.com/analytics/analytics-engine/sql-api/) to query that data.

You can use Workers Analytics Engine to:

- Expose custom analytics to your own customers
- Build usage-based billing systems
- Understand the health of your service on a per-customer or per-user basis
- Add instrumentation to frequently called code paths, without impacting performance or overwhelming external analytics systems with events

[Get started](https://developers.cloudflare.com/analytics/analytics-engine/get-started/)

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"WebPage","@id":"https://developers.cloudflare.com/analytics/analytics-engine/#page","headline":"Workers Analytics Engine","description":"Send and query unlimited-cardinality analytics from Workers.","url":"https://developers.cloudflare.com/analytics/analytics-engine/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/analytics-engine/og.png?v=dfb72c4220270535","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Set up and access Network Analytics.
title: Get started
image: https://developers.cloudflare.com/analytics/analytics-engine/get-started/og.png?v=bc12057ae3200e6d
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Get started

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/analytics-engine/get-started/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

## 1. Name your dataset and add it to your Worker

Add the following to your [Wrangler configuration file](https://developers.cloudflare.com/workers/wrangler/configuration/) to create a [binding](https://developers.cloudflare.com/workers/runtime-apis/bindings/) to a Workers Analytics Engine dataset. A dataset is like a table in SQL: the rows and columns should have consistent meaning.

Note

You do not need to manually create a dataset in the Cloudflare dashboard. Workers Analytics Engine datasets are created automatically the first time you write to them after defining the binding in your Wrangler configuration.

```jsonc
{
	"analytics_engine_datasets": [
		{
			"binding": "<BINDING_NAME>",
			"dataset": "<DATASET_NAME>"
		}
	]
}
```

```toml
[[analytics_engine_datasets]]
binding = "<BINDING_NAME>"
dataset = "<DATASET_NAME>"
```

## 2. Write data points from your Worker

You can write data points to your Worker by calling the `writeDataPoint()` method that is exposed on the binding that you just created.

```js
async fetch(request, env) {
  env.WEATHER.writeDataPoint({
    'blobs': ["Seattle", "USA", "pro_sensor_9000"], // City, State
    'doubles': [25, 0.5],
    'indexes': ["a3cd45"]
  });
  return new Response("OK!");
}
```

Note

You do not need to await `writeDataPoint()` — it will return immediately, and the Workers runtime handles writing your data in the background.

A data point is a structured event that consists of:

- **Blobs** (strings) — The dimensions used for grouping and filtering. Sometimes called labels in other metrics systems.
- **Doubles** (numbers) — The numeric values that you want to record in your data point.
- **Indexes** — (strings) — Used as a [sampling](https://developers.cloudflare.com/analytics/analytics-engine/sql-api/#sampling) key.

In the example above, suppose you are collecting air quality samples. Each data point written represents a reading from your weather sensor. The blobs define city, state, and sensor model — the dimensions you want to be able to filter queries on later. The doubles define the numeric temperature and air pressure readings. And the index is the ID of your customer. You may want to include [context about the incoming request](https://developers.cloudflare.com/workers/runtime-apis/request/), such as geolocation, to add additional data to your datapoint.

Currently, the `writeDataPoint()` API accepts ordered arrays of values. This means that you must provide fields in a consistent order. While the `indexes` field accepts an array, you currently must only provide a single index. If you attempt to provide multiple indexes, your data point will not be recorded.

## 3. Query data using the SQL API

You can query the data you have written in two ways:

- [**SQL API**](https://developers.cloudflare.com/analytics/analytics-engine/sql-api) — Best for writing your own queries and integrating with external tools like Grafana.
- [**GraphQL API**](https://developers.cloudflare.com/analytics/graphql-api/) — This is the same API that powers the Cloudflare dashboard.

For the purpose of this example, we will use the SQL API.

### Create an API token

Create an [API Token ↗︎](https://dash.cloudflare.com/profile/api-tokens) that has the `Account Analytics Read` permission.

### Write your first query

The following query returns the top 10 cities that had the highest average humidity readings when the temperature was above zero:

```sql
SELECT
  blob1 AS city,
  SUM(_sample_interval * double2) / SUM(_sample_interval) AS avg_humidity
FROM WEATHER
WHERE double1 > 0
GROUP BY city
ORDER BY avg_humidity DESC
LIMIT 10
```

Note

We are using a custom averaging function to take [sampling](https://developers.cloudflare.com/analytics/analytics-engine/sql-api/#sampling) into account.

You can run this query by making an HTTP request to the SQL API:

```bash
curl "https://api.cloudflare.com/client/v4/accounts/{account_id}/analytics_engine/sql" \
--header "Authorization: Bearer <API_TOKEN>" \
--data "SELECT blob1 AS city, SUM(_sample_interval * double2) / SUM(_sample_interval) AS avg_humidity FROM WEATHER WHERE double1 > 0 GROUP BY city ORDER BY avg_humidity DESC LIMIT 10"
```

Refer to the [Workers Analytics Engine SQL Reference](https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/) for a full list of supported SQL functionality.

### Working with time series data

Workers Analytics Engine is optimized for powering time series analytics that can be visualized using tools like Grafana. Every event written from the runtime is automatically populated with a `timestamp` field. It is expected that most time series will round, and then `GROUP BY` the `timestamp`. For example:

```sql
SELECT
  intDiv(toUInt32(timestamp), 300) * 300 AS t,
  blob1 AS city,
  SUM(_sample_interval * double2) / SUM(_sample_interval) AS avg_humidity
FROM WEATHER
WHERE
  timestamp >= NOW() - INTERVAL '1' DAY
  AND double1 > 0
GROUP BY t, city
ORDER BY t, avg_humidity DESC
```

This query first rounds the `timestamp` field to the nearest five minutes. Then, it groups by that field and city and calculates the average humidity in each city for a five minute period.

Refer to [Querying Workers Analytics Engine from Grafana](https://developers.cloudflare.com/analytics/analytics-engine/grafana/) for more details on how to create efficient Grafana queries against Workers Analytics Engine.

## Further reading

- [Get started](https://developers.cloudflare.com/analytics/analytics-engine/get-started/)
- [Examples](https://developers.cloudflare.com/analytics/analytics-engine/recipes/)
- [SQL API](https://developers.cloudflare.com/analytics/analytics-engine/sql-api/)
- [SQL Reference](https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/)
- [Querying from Grafana](https://developers.cloudflare.com/analytics/analytics-engine/grafana/)
- [Querying from a Worker](https://developers.cloudflare.com/analytics/analytics-engine/worker-querying/)
- [Sampling with WAE](https://developers.cloudflare.com/analytics/analytics-engine/sampling/)
- [Pricing](https://developers.cloudflare.com/analytics/analytics-engine/pricing/)
- [Limits](https://developers.cloudflare.com/analytics/analytics-engine/limits/)

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/analytics-engine/get-started/#page","headline":"Get started","description":"Set up and access Network Analytics.","url":"https://developers.cloudflare.com/analytics/analytics-engine/get-started/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/analytics-engine/get-started/og.png?v=bc12057ae3200e6d","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Visualize Workers Analytics Engine data in Grafana.
title: Querying from Grafana
image: https://developers.cloudflare.com/analytics/analytics-engine/grafana/og.png?v=b6e63e39e7079f3c
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Querying from Grafana

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/analytics-engine/grafana/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

Workers Analytics Engine is optimized for powering time series analytics that can be visualized using tools like Grafana. Every event written from the runtime is automatically populated with a `timestamp` field.

## Grafana plugin setup

We recommend the use of the [Altinity plugin for Clickhouse ↗︎](https://grafana.com/grafana/plugins/vertamedia-clickhouse-datasource/) for querying Workers Analytics Engine from Grafana.

Configure the plugin as follows:

- URL: `https://api.cloudflare.com/client/v4/accounts/<account_id>/analytics_engine/sql`. Replace `<account_id>` with your 32 character account ID (available in the Cloudflare dashboard).
- Leave all auth settings off.
- Add a custom header with a name of `Authorization` and value set to `Bearer <token>`. Replace `<token>` with suitable API token string (refer to the [SQL API docs](https://developers.cloudflare.com/analytics/analytics-engine/sql-api/#authentication) for more information on this).
- No other options need to be set.

## Querying timeseries data

For use in a dashboard, you usually want to aggregate some metric per time interval. This can be achieved by rounding and then grouping by the `timestamp` field. The following query rounds and groups in this way, and then computes an average across each time interval whilst taking into account [sampling](https://developers.cloudflare.com/analytics/analytics-engine/sql-api/#sampling).

```sql
SELECT
    intDiv(toUInt32(timestamp), 60) * 60 AS t,
    blob1 AS label,
    SUM(_sample_interval * double1) / SUM(_sample_interval) AS average_metric
FROM dataset_name
WHERE 
    timestamp <= NOW() 
    AND timestamp > NOW() - INTERVAL '1' DAY
GROUP BY blob1, t
ORDER BY t
```

The Altinity plugin provides some useful macros that can simplify writing queries of this type. The macros require setting `Column:DateTime` to `timestamp` in the query builder, then they can be used like this:

```sql
SELECT
    $timeSeries AS t,
    blob1 AS label,
    SUM(_sample_interval * double1) / SUM(_sample_interval) AS average_metric
FROM dataset_name
WHERE $timeFilter
GROUP BY blob1, t
ORDER BY t
```

This query will automatically adjust the rounding time depending on the zoom level and filter to the correct time range that is currently being displayed.

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/analytics-engine/grafana/#page","headline":"Querying from Grafana","description":"Visualize Workers Analytics Engine data in Grafana.","url":"https://developers.cloudflare.com/analytics/analytics-engine/grafana/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/analytics-engine/grafana/og.png?v=b6e63e39e7079f3c","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Review GraphQL Analytics API query limits.
title: Limits
image: https://developers.cloudflare.com/analytics/analytics-engine/limits/og.png?v=decb1da875bf878f
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Limits

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/analytics-engine/limits/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

The following limits apply to Workers Analytics Engine:

- Analytics Engine will accept up to twenty blobs, twenty doubles, and one index per call to `writeDataPoint`.
- The total size of all blobs in a request must not exceed **16 KB**. The 16 KB size limit for the blobs field applies to **each individual data point**, regardless of how many are included in a single request using writeDataPoints().
- Each index must not be more than 96 bytes.
- You can write a maximum of 250 data points per Worker invocation (client HTTP request). Each call to `writeDataPoint` counts towards this limit.

## Data retention

Data written to Workers Analytics Engine is stored for three months.

Interested in longer retention periods? Join the `#analytics-engine` channel in the [Cloudflare Developers Discord ↗︎](https://discord.cloudflare.com/) and tell us more about what you are building.

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/analytics-engine/limits/#page","headline":"Limits","description":"Review GraphQL Analytics API query limits.","url":"https://developers.cloudflare.com/analytics/analytics-engine/limits/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/analytics-engine/limits/og.png?v=decb1da875bf878f","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Workers Analytics Engine is priced based on two metrics — data points written, and read queries.
title: Pricing
image: https://developers.cloudflare.com/analytics/analytics-engine/pricing/og.png?v=b3a0e93ba3352b69
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Pricing

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/analytics-engine/pricing/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

Workers Analytics Engine is priced based on two metrics — data points written, and read queries.

| Plan | Data points written | Read queries |
| --- | --- | --- |
| **Workers Paid** | 10 million included per month <br> (+$0.25 per additional million) | 1 million included per month (+$1.00 per additional million) |
| **Workers Free** | 100,000 included per day | 10,000 included per day |

Pricing availability

Currently, you will not be billed for your use of Workers Analytics Engine. Pricing information here is shared in advance, so that you can estimate what your costs will be once Cloudflare starts billing for usage in the coming months.

If you are an Enterprise customer, contact your account team for information about Workers Analytics Engine pricing and billing.

### Data points written

Every time you call [`writeDataPoint()`](https://developers.cloudflare.com/analytics/analytics-engine/get-started/#2-write-data-points-from-your-worker) in a Worker, this counts as one data point written.

Each data point written costs the same amount. There is no extra cost to add dimensions or cardinality, and no additional cost for writing more data in a single data point.

### Read queries

Every time you post to Workers Analytics Engine's [SQL API](https://developers.cloudflare.com/analytics/analytics-engine/sql-api/), this counts as one read query.

Each read query costs the same amount. There is no extra cost for more or less complex queries, and no extra cost for reading only a few rows of data versus many rows of data.

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/analytics-engine/pricing/#page","headline":"Pricing","description":"Workers Analytics Engine is priced based on two metrics — data points written, and read queries.","url":"https://developers.cloudflare.com/analytics/analytics-engine/pricing/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/analytics-engine/pricing/og.png?v=b3a0e93ba3352b69","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: How to use Workers Analytics Engine to build usage-based billing into your SaaS product
title: Usage-based billing
image: https://developers.cloudflare.com/analytics/analytics-engine/recipes/usage-based-billing-for-your-saas-product/og.png?v=9b80803f9b1684ac
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Usage-based billing

Last updated Sep 4, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/analytics-engine/recipes/usage-based-billing-for-your-saas-product/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

Many Cloudflare customers run software-as-a-service products with multiple customers. A big concern for such companies is understanding the cost of each customer, and understanding customer behaviour more widely.

Keeping data on every web request used by a customer can be expensive, as can attributing page views to customers. At Cloudflare we have solved this problem with the same in-house technologies now available to you through Analytics Engine.

## Recording data on usage

Analytics Engine is designed for use with Cloudflare Workers. If you already use Cloudflare Workers to serve requests, you can start sending data into Analytics Engine in just a few lines of code:

```javascript
  [...]

  // This examples assumes you give a unique ID to each of your SaaS customers, and the Worker has
  // assigned it to the variable named `customer_id`
  const { pathname } = new URL(request.url);
  env.USAGE_INDEXED_BY_CUSTOMER_ID.writeDataPoint({
    "indexes": [customer_id],
    "blobs": [pathname]
  });
```

SaaS customer activity often follows an exponential pattern: one customer may do 100 million requests per second, while another does 100 requests a day. If all data is sampled together, the usage of bigger customers can cause smaller customers data to be sampled to zero. Analytics Engine allows you to prevent that: in the example code above we supply the customer's unique ID as the index, causing Analytics Engine to sample your customers' individual activity.

## Viewing usage

You can start viewing customer data either using Grafana (for visualisations) or as JSON (for your own tools). Other areas of the Analytics Engine documentation explain this in-depth.

Look at customer usage over all endpoints:

```sql
SELECT
  index1 AS customer_id,
  sum(_sample_interval) AS count
FROM
  usage_indexed_by_customer_id
GROUP BY customer_id
```

If run in Grafana, this query returns a graph summarising the usage of each customer. The `sum(_sample_interval)` accounts for the sampling - refer to other Analytics Engine documentation. This query gives you an answer to "which customers are most active?"

The example `writeDataPoint` call above writes an endpoint name. If you do that, you can break down customer activity by endpoint:

```sql
SELECT
  index1 AS customer_id,
  blob1 AS request_endpoint,
  sum(_sample_interval) AS count
FROM
  usage_indexed_by_customer_id
GROUP BY customer_id, request_endpoint
```

This can give you insights into what endpoints different customers are using. This can be useful for business purposes (for example, understanding customer needs) as well as for your engineers to see activity and behaviour (observability).

## Billing customers

Analytics Engine can be used to bill customers based on a reliable approximation of usage. In order to get the best approximation, when generating bills we suggest executing one query per customer. This can result in less sampling than querying multiple customers at once.

```sql
SELECT
  index1 AS customer_id,
  blob1 AS request_endpoint,
  sum(_sample_interval) AS usage_count
FROM
  usage_indexed_by_customer_id
WHERE
  customer_id = 'substitute_customer_id_here'
  AND timestamp >= toDateTime('2023-03-01 00:00:00')
  AND timestamp < toDateTime('2023-04-01 00:00:00')
GROUP BY customer_id, request_endpoint
```

Running this query once for each customer at the end of each month could give you the data to produce a bill. This is just an example: most likely you'll want to adjust this example to how you want to bill.

When producing a bill, most likely you will also want to provide the daily costs. The following query breaks down usage by day:

```sql
SELECT
  index1 AS customer_id,
  toStartOfInterval(timestamp, INTERVAL '1' DAY) AS date,
  blob1 AS request_endpoint,
  sum(_sample_interval) AS request_count
FROM
  usage_indexed_by_customer_id
WHERE
  customer_id = 'x'
  AND timestamp >= toDateTime('2023-03-01 00:00:00')
  AND timestamp < toDateTime('2023-04-01 00:00:00')
GROUP BY customer_id, date, request_endpoint
```

You will want to take the usage queries above, adapt them for how you charge customers, and make a backend system run those queries and calculate the customer charges based on the data returned.

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/analytics-engine/recipes/usage-based-billing-for-your-saas-product/#page","headline":"Usage-based billing","description":"How to use Workers Analytics Engine to build usage-based billing into your SaaS product","url":"https://developers.cloudflare.com/analytics/analytics-engine/recipes/usage-based-billing-for-your-saas-product/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/analytics-engine/recipes/usage-based-billing-for-your-saas-product/og.png?v=9b80803f9b1684ac","dateModified":"2026-09-04","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: How data written to Workers Analytics Engine is automatically sampled at scale
title: Sampling with WAE
image: https://developers.cloudflare.com/analytics/analytics-engine/sampling/og.png?v=79f7addcd6bae94b
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Sampling with WAE

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/analytics-engine/sampling/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

Workers Analytics Engine offers the ability to write an extensive amount of data and retrieve it quickly, at minimal or no cost. To facilitate writing large amounts of data at a reasonable cost, Workers Analytics Engine employs weighted adaptive [sampling ↗︎](<https://en.wikipedia.org/wiki/Sampling_(statistics)>).

When utilizing sampling, you do not need every single data point to answer questions about a dataset. For a sufficiently large dataset, the [necessary sample size ↗︎](https://select-statistics.co.uk/blog/importance-effect-sample-size/) does not depend on the size of the original population. Necessary sample size depends on the variance of your measure, the size of the subgroups you analyze, and how accurate your estimate must be.

The implication for Analytics Engine is that we can compress very large datasets into many fewer observations, yet still answer most queries with very high accuracy. This enables us to offer an analytics service that can measure very high rates of usage, with unbounded cardinality, at a low and predictable price.

At a high level, the way sampling works is:

1. At write time, we sample if data points are written too quickly into one index.
2. We sample again at query time if the query is too complex.

In the following sections, you will learn:

- [How sampling works](https://developers.cloudflare.com/analytics/analytics-engine/sampling/#how-sampling-works).
- [How to read sampled data](https://developers.cloudflare.com/analytics/analytics-engine/sampling/#how-to-read-sampled-data).
- [How is data sampled](https://developers.cloudflare.com/analytics/analytics-engine/sampling/#how-is-data-sampled).
- [How Adaptive Bit Rate Sampling works](https://developers.cloudflare.com/analytics/analytics-engine/sampling/#adaptive-bit-rate-sampling-at-read-time).
- [How to pick your index such that your data is sampled in a usable way](https://developers.cloudflare.com/analytics/analytics-engine/sampling/#how-to-select-an-index).

## How sampling works

Cloudflare's data sampling is similar to how online mapping services like Google Maps render maps at different zoom levels. When viewing satellite imagery of a whole continent, the mapping service provides appropriately sized images based on the user's screen and Internet speed.

![The image on the left shows a satellite view from OpenStreetMap. On the right, the same image is zoomed in. In these two images, each pixel represents the same area; however the image on the right has many fewer pixels.](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=1180,height=420,format=webp/_astro/zoom-less-pixels.CTBizcEW.png)

Each pixel on the map represents a large area, such as several square kilometers. If a user tries to zoom in using a screenshot, the resulting image would be blurry. Instead, the mapping service selects higher-resolution images when a user zooms in on a specific city. The total number of pixels remains relatively constant, but each pixel now represents a smaller area, like a few square meters.

![Now the image on the right is of a much higher resolution. Each pixel represents a much smaller area; however, the total number of pixels in both images is roughly the same.](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=1184,height=414,format=webp/_astro/zoom-more-pixels.CFR4ChGF.png)

The key point is that the map's quality does not solely depend on the resolution or the area represented by each pixel. It is determined by the total number of pixels used to render the final view.

There are similarities between the how a mapping services handles resolution and Cloudflare Analytics delivers analytics using adaptive samples:

- **How data is stored**:
  - **Mapping service**: Imagery stored at different resolutions.
  - **Cloudflare Analytics**: Events stored at different sample rates.
- **How data is displayed to user**:
  - **Mapping service**: The total number of pixels is \~constant for a given screen size, regardless of the area selected.
  - **Cloudflare Analytics**: A similar number of events are read for each query, regardless of the size of the dataset or length of time selected.
- **How a resolution is selected**:
  - **Mapping service**: The area represented by each pixel will depend on the size of the map being rendered. In a more zoomed out map, each pixel will represent a larger area.
  - **Cloudflare Analytics**: The sample interval of each event in the result depends on the size of the underlying dataset and length of time selected. For a query over a large dataset or long length of time, each sampled event may stand in for many similar events.

## How to read sampled data

To effectively write queries and analyze the data, it is helpful to first learn how sampled data is read in Workers Analytics Engine.

In Workers Analytics Engine, every event is recorded with the `_sample_interval` field. The sample interval is the inverse of the sample rate. For example, if a one percent (1%) sample rate is applied, the `sample_interval` will be set to `100`.

Using the mapping example in simple terms, the sample interval represents the "number of unsampled data points" (kilometers or meters) that a given sampled data point (pixel) represents.

The sample interval is a property associated with each individual row stored in Workers Analytics Engine. Due to the implementation of equitable sampling, the sample interval can vary for each row. As a result, when querying the data, you need to consider the sample interval field. Simply multiplying the query result by a constant sampling factor is not sufficient.

Here are some examples of how to express some common queries over sampled data.

| Use case | Example without sampling | Example with sampling |
| --- | --- | --- |
| Count events in a dataset | `count()` | `sum(_sample_interval)` |
| Sum a quantity, for example, bytes | `sum(bytes)` | `sum(bytes * _sample_interval)` |
| Average a quantity | `avg(bytes)` | `sum(bytes * _sample_interval) / sum(_sample_interval)` |
| Compute quantiles | `quantile(0.50)(bytes)` | `quantileExactWeighted(0.50)(bytes, _sample_interval)` |

Note that the accuracy of results is not determined by the sample interval, similar to the mapping analogy mentioned earlier. A high sample interval can still provide precise results. Instead, accuracy depends on the total number of data points queried and their distribution.

## How is data sampled

To determine the sample interval for each event, note that most analytics have some important type of subgroup that must be analyzed with accurate results. For example, you may want to analyze user usage or traffic to specific hostnames. Analytics Engine users can define these groups by populating the `index` field when writing an event. This allows for more targeted and precise analysis within the specified groups.

The next observation is that these index values likely have a very different number of events written to them. In fact, the usage of most web services follows a [Pareto distribution ↗︎](https://en.wikipedia.org/wiki/Pareto_distribution), meaning that the top few users will account for the vast majority of the usage. Pareto distributions are common and look like this:

![In this graphic, each bar represents a user; the height of the bar is their total usage.](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=1798,height=1092,format=webp/_astro/total-usage.DT9rN3Uq.png)

If we took a [simple random sample ↗︎](https://en.wikipedia.org/wiki/Simple_random_sample) of one percent (1%) of this data, and we applied that to the whole population, you may be able to track your largest customers accurately — but you would lose visibility into what your smaller customers are doing:

![The same graphic as above, but now based on a 1% sample of the data.](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=1904,height=1136,format=webp/_astro/sample-data.Db8bZbVI.png)

Notice that the larger bars look more or less unchanged, and yet they are still quite accurate. But as you analyze smaller customers, results get [quantized ↗︎](<https://en.wikipedia.org/wiki/Quantization_(signal_processing)>) and may even be rounded to 0 entirely.

This shows that while a one percent (1%) or even smaller sample of a large population may be sufficient, we may need to store a larger proportion of events for a small population to get accurate results.

We do this through a technique called equitable sampling. This means that we will equalize the number of events we store for each unique index value. For relatively uncommon index values, we may write all of the data points that we get via `writeDataPoint()`. But if you write lots of data points to a single index value, we will start to sample.

Here is the same distribution, but now with (a simulation of) equitable sampling applied:

![This graphic shows the same population, but with equitable sampling.](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=1902,height=1146,format=webp/_astro/equitable-sampling.CzViMd9X.png)

You may notice that this graphic is very similar to the first graph. However, it only requires `<10%` of the data to be stored overall. The sample rate is actually much lower than `10%` for the larger series (that is, we store larger sample intervals), but the sample rate is higher for the smaller series.

Refer back to the mapping analogy above. Regardless of the map area shown, the total number of pixels in the map stays constant. Similarly, we always want to store a similar number of data points for each index value. However, the resolution of the map — how much area is represented by each pixel — will change based on the area being shown. Similarly here, the amount of data represented by each stored data point will vary, based on the total number of data points in the index.

## Adaptive Bit Rate Sampling at Read Time

Equitable sampling ensures that an equal amount of data is maintained for each index within a specific time frame. However, queries can vary significantly in the duration of time they target. Some queries may only require a 10-minute data snapshot, while others might need to analyze data spanning 10 weeks — a period which is 10,000 times longer.

To address this issue, we employ a method called [adaptive bit rate ↗︎](https://blog.cloudflare.com/explaining-cloudflares-abr-analytics/) (ABR). With ABR, queries that cover longer time ranges will retrieve data from a higher sample interval, allowing them to be completed within a fixed time limit. In simpler terms, just as screen size or bandwidth is a fixed resource in our mapping analogy, the time required to complete a query is also fixed. Therefore, irrespective of the volume of data involved, we need to limit the total number of rows scanned to provide an answer to the query. This helps to ensure fairness: regardless of the size of the underlying dataset being queried, we ensure that all queries receive an equivalent share of the available computing time.

To achieve this, we store the data in multiple resolutions (that is, with different levels of detail, for instance, 100%, 10%, 1%) derived from the equitably sampled data. At query time, we select the most suitable data resolution to read based on the query's complexity. The query's complexity is determined by the number of rows to be retrieved and the probability of the query completing within a specified time limit of N seconds. By dynamically selecting the appropriate resolution, we optimize the query performance and ensure it stays within the allotted time budget.

ABR offers a significant advantage by enabling us to consistently provide query results within a fixed query budget, regardless of the data size or time span involved. This sets it apart from systems that struggle with timeouts, errors, or high costs when dealing with extensive datasets.

## How to select an index

In order to get accurate results with sampled data, select an appropriate value to use as your index. The index should match how users will query and view data. For example, if users frequently view data based on a specific device or hostname, it is recommended to incorporate those attributes into your index.

The index has the following properties, which are important to consider when choosing an index:

- Get accurate summary statistics about your entire dataset, across all index values.
- Get an accurate count of the number of unique values of your index.
- Get accurate summary statistics (for example, count, sum) within a particular index value.
- See the `Top N` values of specific fields that are not in your index.
- Filter on most fields.
- Run other aggregations like quantiles.

Some limitations and trade-offs to consider are:

- You may not be able to get accurate unique counts of fields that are not in your index.
  - For example, if you index on `hostname`, you may not be able to count the number of unique URLs.
- You may not be able to observe very rare values of fields not in the index.
  - For example, a particular URL for a hostname, if you index on host and have millions of unique URLs.
- You may not be able to run accurate queries across multiple indices at once.
  - For example, you may only be able to query for one host at a time (or all of them) and expect accurate results.
- There is no guarantee you can retrieve any one individual record.
- You cannot necessarily reconstruct exact sequences of events.

It is not recommended to write a unique index value on every row (like a UUID) for most use cases. While this will make it possible to retrieve individual data points very quickly, it will slow down most queries for aggregations and time series.

Refer to the Workers Analytics Engine FAQs, for common question about [Sampling](https://developers.cloudflare.com/analytics/faq/wae-faqs/#sampling).

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/analytics-engine/sampling/#page","headline":"Sampling with WAE","description":"How data written to Workers Analytics Engine is automatically sampled at scale","url":"https://developers.cloudflare.com/analytics/analytics-engine/sampling/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/analytics-engine/sampling/og.png?v=79f7addcd6bae94b","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: The SQL API for Workers Analytics Engine
title: SQL API
image: https://developers.cloudflare.com/analytics/analytics-engine/sql-api/og.png?v=eae470f8bdad1c3a
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# SQL API

Last updated Oct 2, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/analytics-engine/sql-api/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

The Workers Analytics Engine SQL API is an HTTP API that allows executing SQL queries against your Workers Analytics Engine datasets.

The API is hosted at `https://api.cloudflare.com/client/v4/accounts/<account_id>/analytics_engine/sql`.

This endpoint and its SQL dialect are separate from the [Analytics SQL API](https://developers.cloudflare.com/analytics/sql-api/). To query Analytics Engine data through that API, use `events.analyticsEngine.<DATASET_NAME>`. Double-quote dataset names that are not ordinary SQL identifiers, for example `events.analyticsEngine."example-dataset"`.

## Authentication

Authentication is done via bearer token. An `Authorization: Bearer <token>` header must be supplied with every request to the API.

Use the dashboard to create a token with permission to read analytics data on your account:

1. Visit the [API tokens ↗︎](https://dash.cloudflare.com/profile/api-tokens) page in the Cloudflare dashboard.
2. Select **Create Token**.
3. Select **Create Custom Token**.
4. Complete the **Create Custom Token** form as follows:
   - Give your token a descriptive name.
   - For **Permissions** select *Account* | *Account Analytics* | *Read*
   - Optionally configure account and IP restrictions and TTL.
   - Submit and confirm the form to create the token.
5. Make a note of the token string.

## Querying the API

Submit the query text in the body of a `POST` request to the API address. The format of the data returned can be selected using the [`FORMAT`](https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/statements/#format-clause) option in your query.

You can use cURL to test the API as follows, replacing the `<account_id>` with your 32 character account ID (available in the dashboard) and the `<token>` with the token string you generated above.

```bash
curl "https://api.cloudflare.com/client/v4/accounts/{account_id}/analytics_engine/sql" \
--header "Authorization: Bearer <API_TOKEN>" \
--data "SELECT 'Hello Workers Analytics Engine' AS message"
```

If you have already published some data, you might try executing the following to confirm that the dataset has been created in the DB.

```bash
curl "https://api.cloudflare.com/client/v4/accounts/{account_id}/analytics_engine/sql" \
--header "Authorization: Bearer <API_TOKEN>" \
--data "SHOW TABLES"
```

Refer to the Workers Analytics Engine [SQL reference](https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/), for the full supported query syntax.

## Table structure

A new table will automatically be created for each dataset once you start writing events to it from your worker.

The table will have the following columns:

| Name | Type | Description |
| --- | --- | --- |
| dataset | string | This column will contain the dataset name in every row. |
| timestamp | DateTime | The timestamp at which the event was logged in your worker. |
| \_sample\_interval | integer | In case that the data has been sampled, this column indicates what the sample rate is for this row (that is, how many rows of the original data are represented by this row). Refer to the [sampling](#sampling) section below for more information. |
| index1 | string | The index value that was logged with the event. The value in this column is used as the key for sampling. |
| blob1<br>...<br>blob20 | string | The blob values that were logged with the event. |
| double1<br>...<br>double20 | double | The double values that were logged with the event. |

## Sampling

At very high volumes of data, Analytics Engine will downsample data in order to be able to maintain performance. Sampling can occur on write and on read. Sampling is based on the index of your dataset so that only indexes that receive large numbers of events will be sampled. For example, if your worker serves multiple customers, you might consider making customer ID the index field. This would mean that if one customer starts making a high rate of requests then events from that customer could be sampled while other customers data remains unsampled.

We have tested this system of sampling over a number of years at Cloudflare and it has enabled us to scale our web analytics systems to very high throughput, while still providing statistically meaningful results irrespective of the amount of traffic a website receives.

The rate at which the data is sampled is exposed via the `_sample_interval` column. This means that if you are doing statistical analysis of your data, you may need to take this column into account. For example:

| Original query | Query taking into account sampling |
| --- | --- |
| `SELECT COUNT() FROM ...` | `SELECT SUM(_sample_interval) FROM ...` |
| `SELECT SUM(double1) FROM ...` | `SELECT SUM(_sample_interval * double1) FROM ...` |
| `SELECT AVG(double1) FROM ...` | `SELECT SUM(_sample_interval * double1) / SUM(_sample_interval) FROM ...` |

Additionally, the [QUANTILEEXACTWEIGHTED](https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/aggregate-functions/#quantileexactweighted) function is designed to be used with sample interval as the third argument.

## Example queries

### Select data with column aliases

Column aliases can be used in queries to give names to the blobs and doubles in your dataset:

```sql
SELECT
    timestamp,
    blob1 AS location_id,
    double1 AS inside_temp,
    double2 AS outside_temp
FROM temperatures
WHERE timestamp > NOW() - INTERVAL '1' DAY
```

### Aggregation taking into account sample interval

Calculate number of readings taken at each location in the last 7 days. In this case, we are grouping by the index field so an exact count can be calculated even in the case that the data has been sampled:

```sql
SELECT
    index1 AS location_id,
    SUM(_sample_interval) AS n_readings
FROM temperatures
WHERE timestamp > NOW() - INTERVAL '7' DAY
GROUP BY index1
```

Calculate the average temperature over the last 7 days at each location. Sample interval is taken into account:

```sql
SELECT
    index1 AS location_id,
    SUM(_sample_interval * double1) / SUM(_sample_interval) AS average_temp
FROM temperatures
WHERE timestamp > NOW() - INTERVAL '7' DAY
GROUP BY index1
```

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/analytics-engine/sql-api/#page","headline":"SQL API","description":"The SQL API for Workers Analytics Engine","url":"https://developers.cloudflare.com/analytics/analytics-engine/sql-api/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/analytics-engine/sql-api/og.png?v=eae470f8bdad1c3a","dateModified":"2026-10-02","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: SQL aggregate functions for Analytics Engine queries.
title: Aggregate functions
image: https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/aggregate-functions/og.png?v=1ed00cf69a75fc3e
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Aggregate functions

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/aggregate-functions/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

## count

Usage:

```sql
count()
count(DISTINCT column_name)
```

`count` is an aggregation function that returns the number of rows in each group or results set.

`count` can also be used to count the number of distinct (unique) values in each column:

Example:

```sql
-- return the total number of rows
count()
-- return the number of different values in the column
count(DISTINCT column_name)
```

## sum

Usage:

```sql
sum([DISTINCT] column_name)
```

`sum` is an aggregation function that returns the sum of column values across all rows in each group or results set. Sum also supports `DISTINCT`, but in this case it will only sum the unique values in the column.

Example:

```sql
-- return the total cost of all items
sum(item_cost)
-- return the total of all unique item costs
sum(DISTINCT item_cost)
```

## avg

Usage:

```sql
avg([DISTINCT] column_name)
```

`avg` is an aggregation function that returns the mean of column values across all rows in each group or results set. Avg also supports `DISTINCT`, but in this case it will only average the unique values in the column.

Example:

```sql
-- return the mean item cost
avg(item_cost)
-- return the mean of unique item costs
avg(DISTINCT item_cost)
```

## min

Usage:

```sql
min(column_name)
```

`min` is an aggregation function that returns the minimum value of a column across all rows.

Example:

```sql
-- return the minimum item cost
min(item_cost)
```

## max

Usage:

```sql
max(column_name)
```

`max` is an aggregation function that returns the maximum value of a column across all rows.

Example:

```sql
-- return the maximum item cost
max(item_cost)
```

## quantileExactWeighted

Usage:

```sql
quantileExactWeighted(q)(column_name, weight_column_name)
```

`quantileExactWeighted` is an aggregation function that returns the value at the q<sup>th</sup> quantile in the named column across all rows in each group or results set. Each row will be weighted by the value in `weight_column_name`. Typically this would be `_sample_interval` (refer to [Sampling](https://developers.cloudflare.com/analytics/analytics-engine/sql-api/#sampling) for more information).

Example:

```sql
-- estimate the median value of <double1>
quantileExactWeighted(0.5)(double1, _sample_interval)

-- in a table of query times, estimate the 95th centile query time
quantileExactWeighted(0.95)(query_time, _sample_interval)
```

For backwards compatibility, this is also available as `quantileWeighted(q, column_name, weight_column_name)`.

## argMax New

Usage:

```sql
argMax(arg, val)
```

`argMax` is an aggregation function that returns the `arg` value that corresponds to the maximum value of `val`.

If multiple `arg` values have the maximum value of `val`, any one will be returned.

Example:

```sql
-- find the <blob1> value for the row with the highest <double1>
argMax(blob1, double1)

-- find the <blob1> value from the most heavily sampled row
argMax(blob1, _sample_interval)
```

## argMin New

Usage:

```sql
argMin(arg, val)
```

`argMin` is an aggregation function that returns the `arg` value that corresponds to the minimum value of `val`.

If multiple `arg` values have the minimum value of `val`, any one will be returned.

Example:

```sql
-- find the <blob1> value for the row with the lowest <double1>
argMin(blob1, double1)

-- find the <blob1> value from the least heavily sampled row
argMin(blob1, _sample_interval)
```

## first\_value New

Usage:

```sql
first_value(column_name)
```

`first_value` is an aggregation function which returns the first value of the provided column.

Example:

```sql
-- find the oldest value of <blob1>
SELECT first_value(blob1) FROM my_dataset ORDER BY timestamp ASC
```

## last\_value New

Usage:

```sql
last_value(column_name)
```

`last_value` is an aggregation function which returns the last value of the provided column.

Example:

```sql
-- find the oldest value of <blob1>
SELECT last_value(blob1) FROM my_dataset ORDER BY timestamp DESC
```

## topK New

Usage:

```sql
topK(N)(column)
```

`topK` is an aggregation function which returns the most common `N` values of a column.

`N` is optional and defaults to `10`.

Example:

```sql
-- find the 10 most common values of <double1>
SELECT topK(double1) FROM my_dataset

-- find the 15 most common values of <blob1>
SELECT topK(15)(blob1) FROM my_dataset
```

## topKWeighted New

Usage:

```sql
topKWeighted(N)(column, weight_column)
```

`topKWeighted` is an aggregation function which returns the most common `N` values of a column, weighted by a second column.

`N` is optional and defaults to `10`.

Example:

```sql
-- find the 10 most common values of <double1>, weighted by `_sample_interval`
SELECT topKWeighted(double1, _sample_interval) FROM my_dataset

-- find the 15 most common values of <blob1>, weighted by `_sample_interval`
SELECT topKWeighted(15)(blob1, _sample_interval) FROM my_dataset
```

## countIf New

Usage:

```sql
countIf(<expr>)
```

`countIf` is an aggregation function that returns the number of rows in the results set, but only counting rows where a provided expression evaluates to true.

Example:

```sql
-- return the number of rows where `double1` is greater than 5
countIf(double1 > 5)
```

## sumIf New

Usage:

```sql
sumIf(<expr>, <expr>)
```

`sumIf` is an aggregation function that returns the sum of a first expression across all rows in the results set, but only including rows where a second expression evaluates to true.

Example:

```sql
-- return the sum of column `item_cost` of all items where another column `in_stock` is not zero
sumIf(item_cost, in_stock > 0)
```

## avgIf New

Usage:

```sql
avgIf(<expr>, <expr>)
```

`avgIf` is an aggregation function that returns the mean of an expression across all rows in the results set, but only including rows where a second expression evaluates to true.

Example:

```sql
-- return the mean of column `item_cost` where another column `in_stock` is not zero
avgIf(item_cost, in_stock > 0)
```

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/aggregate-functions/#page","headline":"Aggregate functions","description":"SQL aggregate functions for Analytics Engine queries.","url":"https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/aggregate-functions/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/aggregate-functions/og.png?v=1ed00cf69a75fc3e","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Bitwise SQL functions for Analytics Engine.
title: Bit functions
image: https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/bit-functions/og.png?v=d3ca9f693050a388
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Bit functions

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/bit-functions/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

## bitAnd New

Usage:

```sql
bitAnd(a, b)
```

`bitAnd` returns the bitwise AND of expressions `a` and `b`.

Examples:

```sql
-- perform 0b1 & 0b11
bitAnd(1, 3)
-- extract the least significant bit of the integer value of double1
bitAnd(toUInt8(double1), 1)
```

## bitCount New

Usage:

```sql
bitCount(a)
```

`bitCount` returns the number of bits set to one in the binary representation of `a`.

Examples:

```sql
-- get the number of 1 bits in the binary representation of the float `double1`
bitCount(double1)
-- get the number of 1 bits in the binary representation of `double1` as an integer
bitCount(toUInt32(double1))
-- select rows where at least 5 bits are 1
SELECT * WHERE bitCount(double1) > 5
```

## bitHammingDistance New

Usage:

```sql
bitHammingDistance(x, y)
```

`bitHammingDistance` returns the number of bits that differ between `x` and `y`.

Examples:

```sql
-- returns zero
bitHammingDistance(1, 1)
-- returns 2
bitHammingDistance(3, 0)
```

## bitNot New

Usage:

```sql
bitNot(a)
```

`bitNot` returns `a` with all bits flipped.

Examples:

```sql
bitNot(1)
```

## bitOr New

Usage:

```sql
bitOr(a, b)
```

`bitOr` returns the inclusive bitwise or of `a` and `b`.

Examples:

```sql
-- returns 3
bitOr(1, 2)
```

## bitRotateLeft New

Usage:

```sql
bitRotateLeft(a, n)
```

`bitRotateLeft` rotates all bits in `a` left by `n` positions.

Examples:

```sql
-- returns 2
bitRotateLeft(1, 1)
-- returns 1
bitRotateLeft(128, 1)
```

## bitRotateRight New

Usage:

```sql
bitRotateRight(a, n)
```

`bitRotateRight` rotates all bits in `a` right by `n` positions.

Examples:

```sql
-- returns 128
bitRotateRight(1, 1)
-- returns 3
bitRotateRight(12, 2)
```

## bitShiftLeft New

Usage:

```sql
bitShiftLeft(a, n)
```

`bitShiftLeft` shifts all bits in `a` left by `n` positions.

Examples:

```sql
-- returns 2
bitShiftLeft(1, 1)
-- returns 0
bitShiftLeft(128, 1)
```

## bitShiftRight New

Usage:

```sql
bitShiftRight(a, n)
```

`bitShiftRight` shifts all bits in `a` right by `n` positions.

Examples:

```sql
-- returns 0
bitShiftRight(1, 1)
-- returns 3
bitShiftRight(12, 2)
```

## bitTest New

Usage:

```sql
bitTest(a, n)
```

`bitTest` returns the value of bit `n` in number `a`.

Examples:

```sql
-- returns 1
bitTest(3, 1)
-- return 0
bitTest(2, 1)
-- select rows where a particular bit is 1
SELECT * WHERE bitTest(double1, 2)
```

## bitXor New

Usage:

```sql
bitXor(a, b)
```

`bitXor` returns the bitwise exclusive-or of `a` and `b`.

Examples:

```sql
-- returns 3
bitXor(1, 2)
-- returns 0
bitXor(3, 3)
```

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/bit-functions/#page","headline":"Bit functions","description":"Bitwise SQL functions for Analytics Engine.","url":"https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/bit-functions/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/bit-functions/og.png?v=d3ca9f693050a388","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Conditional SQL functions for Analytics Engine queries.
title: Conditional functions
image: https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/conditional-functions/og.png?v=76c21573bf8cad4a
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Conditional functions

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/conditional-functions/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

## if

Usage:

```sql
if(<condition>, <true_expression>, <false_expression>)
```

Returns `<true_expression>` if `<condition>` evaluates to true, else returns `<false_expression>`.

Example:

```sql
if(temp > 20, 'It is warm', 'Bring a jumper')
```

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/conditional-functions/#page","headline":"Conditional functions","description":"Conditional SQL functions for Analytics Engine queries.","url":"https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/conditional-functions/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/conditional-functions/og.png?v=76c21573bf8cad4a","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Date and time SQL functions for Analytics Engine.
title: Date and Time functions
image: https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/date-time-functions/og.png?v=17f4625cdb31a326
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Date and Time functions

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/date-time-functions/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

## formatDateTime

Usage:

```sql
formatDateTime(<datetime expression>, <format string>[, <timezone string>])
```

`formatDateTime` prints a datetime as a string according to a provided format string. Refer to [ClickHouse's documentation ↗︎](https://clickhouse.com/docs/en/sql-reference/functions/date-time-functions/#formatdatetime) for a list of supported formatting options.

Examples:

```sql
-- prints the current YYYY-MM-DD in UTC
formatDateTime(now(), '%Y-%m-%d')

-- prints YYYY-MM-DD in the datetime's timezone
formatDateTime(<a datetime with a timezone>, '%Y-%m-%d')
formatDateTime(toDateTime('2022-12-01 16:17:00', 'America/New_York'), '%Y-%m-%d')

-- prints YYYY-MM-DD in UTC
formatDateTime(<a datetime with a timezone>, '%Y-%m-%d', 'Etc/UTC')
formatDateTime(toDateTime('2022-12-01 16:17:00', 'America/New_York'), '%Y-%m-%d', 'Etc/UTC')
```

## now

Usage:

```sql
now()
```

Returns the current time as a DateTime.

## today New

Usage:

```sql
today()
```

Returns the current date as a `Date`.

## toDateTime

Usage:

```sql
toDateTime(<expression>[, 'timezone string'])
```

`toDateTime` converts an expression to a datetime. This function does not support ISO 8601-style timezones; if your time is not in UTC then you must provide the timezone using the second optional argument.

Examples:

```sql
-- double1 contains a unix timestamp in seconds
toDateTime(double1)

-- blob1 contains an datetime in the format 'YYYY-MM-DD hh:mm:ss'
toDateTime(blob1)

-- literal values:
toDateTime(355924804) -- unix timestamp
toDateTime('355924804') -- string containing unix timestamp
toDateTime('1981-04-12 12:00:04') -- string with datetime in 'YYYY-MM-DD hh:mm:ss' format

-- interpret a date relative to New York time
toDateTime('2022-12-01 16:17:00', 'America/New_York')
```

## toYear New

Usage:

```sql
toYear(<datetime>)
```

`toYear` returns the year of a datetime.

Examples:

```sql
-- returns the number 2025
toYear(toDateTime('2025-10-27 00:00:00'))
```

## toMonth New

Usage:

```sql
toMonth(<datetime>)
```

`toMonth` returns the year of a datetime.

Examples:

```sql
-- returns the number 10
toMonth(toDateTime('2025-10-27 00:00:00'))
```

## toDayOfWeek New

Usage:

```sql
toDayOfWeek(<datetime>)
```

`toDayOfWeek` takes a datetime and returns its numerical day of the week.

Returns `1` to indicate Monday, `2` to indicate Tuesday, and so on.

Examples:

```sql
-- returns the number 1 for Monday 27th October 2025
toDayOfWeek(toDateTime('2025-10-27 00:00:00'))

-- returns the number 2 for Tuesday 28th October 2025
toDayOfWeek(toDateTime('2025-10-28 00:00:00'))

-- returns the number 7 for Sunday 2nd November 2025
toDayOfWeek(toDateTime('2025-11-02 00:00:00'))
```

## toDayOfMonth New

Usage:

```sql
toDayOfMonth(<datetime>)
```

`toDayOfMonth` returns the day of the month from a datetime.

Examples:

```sql
-- returns the number 27
toDayOfMonth(toDateTime('2025-10-27 00:00:00'))
```

## toHour New

Usage:

```sql
toHour(<datetime>)
```

`toHour` returns the hour of the day from a datetime.

Examples:

```sql
-- returns the number 9
toHour(toDateTime('2025-10-27 09:11:13'))
```

## toMinute New

Usage:

```sql
toMinute(<datetime>)
```

`toMinute` returns the minute of the hour from a datetime.

Examples:

```sql
-- returns the number 11
toMinute(toDateTime('2025-10-27 09:11:13'))
```

## toSecond New

Usage:

```sql
toSecond(<datetime>)
```

`toSecond` returns the second of the minute from a datetime.

Examples:

```sql
-- returns the number 13
toSecond(toDateTime('2025-10-27 09:11:13'))
```

## toUnixTimestamp

Usage:

```sql
toUnixTimestamp(<datetime>)
```

`toUnixTimestamp` converts a datetime into an integer unix timestamp.

Examples:

```sql
-- get the current unix timestamp
toUnixTimestamp(now())
```

## toStartOfInterval

Usage:

```sql
toStartOfInterval(<datetime>, INTERVAL '<n>' <unit>[, <timezone string>])
```

`toStartOfInterval` rounds down a datetime to the nearest offset of a provided interval. This can be useful for grouping data into equal-sized time ranges.

Examples:

```sql
-- round the current time down to the nearest 15 minutes
toStartOfInterval(now(), INTERVAL '15' MINUTE)

-- round a timestamp down to the day
toStartOfInterval(timestamp, INTERVAL '1' DAY)

-- count the number of datapoints filed in each hourly window
SELECT
  toStartOfInterval(timestamp, INTERVAL '1' HOUR) AS hour,
  sum(_sample_interval) AS count
FROM your_dataset
GROUP BY hour
ORDER BY hour ASC
```

## toStartOfYear New

Usage:

```sql
toStartOfYear(<datetime>)
```

`toStartOfYear` rounds down a datetime to the nearest start of year. This can be useful for grouping data into equal-sized time ranges.

Examples:

```sql
-- round a timestamp down to 2025-01-01 00:00:00
toStartOfYear(toDateTime('2025-10-27 00:00:00'))
```

## toStartOfMonth New

Usage:

```sql
toStartOfMonth(<datetime>)
```

`toStartOfMonth` rounds down a datetime to the nearest start of month. This can be useful for grouping data into equal-sized time ranges.

Examples:

```sql
-- round a timestamp down to 2025-10-01 00:00:00
toStartOfMonth(toDateTime('2025-10-27 00:00:00'))
```

## toStartOfWeek New

Usage:

```sql
toStartOfWeek(<datetime>)
```

`toStartOfWeek` rounds down a datetime to the start of the week. This can be useful for grouping data into equal-sized time ranges.

Treats Monday as the first day of the week.

Examples:

```sql
-- round a time on a Monday down to Monday 2025-10-27 00:00:00
toStartOfWeek(toDateTime('2025-10-27 00:00:00'))

-- round a time on a Wednesday down to Monday 2025-10-27 00:00:00
toStartOfWeek(toDateTime('2025-10-29 00:00:00'))
```

## toStartOfDay New

Usage:

```sql
toStartOfDay(<datetime>)
```

`toStartOfDay` rounds down a datetime to the nearest start of day. This can be useful for grouping data into equal-sized time ranges.

Examples:

```sql
-- round a timestamp down to 2025-10-27 00:00:00
toStartOfDay(toDateTime('2025-10-27 00:00:00'))
```

## toStartOfHour New

Usage:

```sql
toStartOfHour(<datetime>)
```

`toStartOfHour` rounds down a datetime to the nearest start of hour. This can be useful for grouping data into equal-sized time ranges.

Examples:

```sql
-- round a timestamp down to 2025-10-27 16:00:00
toStartOfHour(toDateTime('2025-10-27 16:55:25'))
```

## toStartOfFifteenMinutes New

Usage:

```sql
toStartOfFifteenMinutes(<datetime>)
```

`toStartOfFifteenMinutes` rounds down a datetime to the nearest fifteen minutes. This can be useful for grouping data into equal-sized time ranges.

Examples:

```sql
-- round a timestamp down to 2025-10-27 16:45:00
toStartOfFifteenMinutes(toDateTime('2025-10-27 16:55:25'))
```

## toStartOfTenMinutes New

Usage:

```sql
toStartOfTenMinutes(<datetime>)
```

`toStartOfTenMinutes` rounds down a datetime to the nearest ten minutes. This can be useful for grouping data into equal-sized time ranges.

Examples:

```sql
-- round a timestamp down to 2025-10-27 16:50:00
toStartOfTenMinutes(toDateTime('2025-10-27 16:55:25'))
```

## toStartOfFiveMinutes New

Usage:

```sql
toStartOfFiveMinutes(<datetime>)
```

`toStartOfFiveMinutes` rounds down a datetime to the nearest five minutes. This can be useful for grouping data into equal-sized time ranges.

Examples:

```sql
-- round a timestamp down to 2025-10-27 16:55:00
toStartOfFiveMinutes(toDateTime('2025-10-27 16:55:25'))
```

## toStartOfMinute New

Usage:

```sql
toStartOfMinute(<datetime>)
```

`toStartOfMinute` rounds down a datetime to the nearest minute. This can be useful for grouping data into equal-sized time ranges.

Examples:

```sql
-- round a timestamp down to 2025-10-27 16:55:00
toStartOfMinute(toDateTime('2025-10-27 16:55:25'))
```

## toYYYYMM New

Usage:

```sql
toYYYYMM(<datetime>)
```

`toYYYYMM` returns a number representing year and month of a datetime. For instance a datetime on `2025-05-03` would return the number `202505`.

Examples:

```sql
-- returns the number 202510
toYYYYMM(toDateTime('2025-10-27 16:55:25'))
```

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/date-time-functions/#page","headline":"Date and Time functions","description":"Date and time SQL functions for Analytics Engine.","url":"https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/date-time-functions/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/date-time-functions/og.png?v=17f4625cdb31a326","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Encoding SQL functions for Analytics Engine queries.
title: Encoding functions
image: https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/encoding-functions/og.png?v=118ae30c51b8339e
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Encoding functions

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/encoding-functions/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

## bin New

Usage:

```sql
bin(<expression>)
```

`bin` returns a string containing the binary representation of its argument.

Examples:

```sql
-- get the binary representation of 1
bin(1)
-- get the binary representation of a string`
bin('abc')
```

## hex New

Usage:

```sql
hex(<expression>)
```

`hex` returns a string containing the hexadecimal representation of its argument.

Examples:

```sql
-- get the hexadecimal representation of 1
hex(1)
-- get the hexadecimal representation of a string`
hex('abc')
```

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/encoding-functions/#page","headline":"Encoding functions","description":"Encoding SQL functions for Analytics Engine queries.","url":"https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/encoding-functions/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/encoding-functions/og.png?v=118ae30c51b8339e","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Supported literal types in Analytics Engine SQL.
title: Literals
image: https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/literals/og.png?v=369895b9c2ae900f
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Literals

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/literals/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

The following literals are supported:

| Type | Syntax |
| --- | --- |
| integer | `42`, `-42` |
| double | `4.2`, `-4.2` |
| string | `'so long and thanks for all the fish'` |
| boolean | `true` or `false` |
| time interval | `INTERVAL '42' DAY`<br>Intervals of `YEAR`, `MONTH`, `DAY`, `HOUR`, `MINUTE` and `SECOND` are supported |

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/literals/#page","headline":"Literals","description":"Supported literal types in Analytics Engine SQL.","url":"https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/literals/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/literals/og.png?v=369895b9c2ae900f","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Mathematical SQL functions for Analytics Engine.
title: Mathematical functions
image: https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/mathematical-functions/og.png?v=029d44160f4880b7
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Mathematical functions

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/mathematical-functions/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

## intDiv

Usage:

```sql
intDiv(a, b)
```

Divide `a` by `b`, rounding the answer down to the nearest whole number.

## log New

Usage:

```sql
log(<expression>)
```

`log` returns the natural logarithm of a provided number. `ln` is also available as an alias.

Examples:

```sql
-- get the natural logarithm of the double1 column
log(double1)
```

## pow New

Usage:

```sql
pow(<expression>, <expression>)
```

`pow` returns the first argument raised to the power of the second argument.

Examples:

```sql
-- get the square of the double1 column
pow(double1, 2)
```

## round New

Usage:

```sql
round(<expression>[, n])
```

`round` returns a number rounded to the nearest whole number, or to a given number of decimal points specified by the second argument.

Examples:

```sql
-- round 5.5 to 6
round(5.5)
-- round 3.14 to 3.1
round(3.14, 1)
```

## floor New

Usage:

```sql
floor(<expression>[, n])
```

`floor` returns a number rounded down to a whole number, or rounded down to a given number of decimal points specified by the second argument.

Examples:

```sql
-- round down 5.5 to 5
floor(5.5)
-- round down 3.14 to 3.1
floor(3.14, 1)
```

## ceil New

Usage:

```sql
ceil(<expression>[, n])
```

`ceil` returns a number rounded up to a whole number, or rounded up to a given number of decimal points specified by the second argument.

Examples:

```sql
-- round up 5.5 to 6
ceil(5.5)
-- round up 3.14 to 3.2
ceil(3.14, 1)
```

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/mathematical-functions/#page","headline":"Mathematical functions","description":"Mathematical SQL functions for Analytics Engine.","url":"https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/mathematical-functions/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/mathematical-functions/og.png?v=029d44160f4880b7","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Arithmetic, comparison, and logical SQL operators.
title: Operators
image: https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/operators/og.png?v=7988826db27eee17
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Operators

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/operators/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

The following operators are supported:

## Arithmetic operators

| Operator | Description |
| --- | --- |
| `+` | addition |
| `-` | subtraction |
| `*` | multiplication |
| `/` | division |
| `%` | modulus |

## Comparison operators

| Operator | Description |
| --- | --- |
| `=` | equals |
| `<` | less than |
| `>` | greater than |
| `<=` | less than or equal to |
| `>=` | greater than or equal to |
| `<>` or `!=` | not equal |
| `IN` | true if the preceding expression's value is in the list<br>`column IN ('a', 'list', 'of', 'values')` |
| `NOT IN` | true if the preceding expression's value is not in the list<br>`column NOT IN ('a', 'list', 'of', 'values')` |

We also support the `BETWEEN` operator for checking a value is in an inclusive range: `a [NOT] BETWEEN b AND c`.

### Pattern matching operators New

| Operator | Description |
| --- | --- |
| `LIKE` | true if the string matches the pattern (case-sensitive)<br>`column LIKE 'pattern%'` |
| `NOT LIKE` | true if the string does not match the pattern (case-sensitive)<br>`column NOT LIKE 'pattern%'` |
| `ILIKE` | true if the string matches the pattern (case-insensitive)<br>`column ILIKE 'pattern%'` |
| `NOT ILIKE` | true if the string does not match the pattern (case-insensitive)<br>`column NOT ILIKE 'pattern%'` |

Pattern matching supports two wildcard characters:

- `%` matches any sequence of zero or more characters
- `_` matches any single character

Examples:

```sql
-- Match strings starting with "error"
WHERE blob1 LIKE 'error%'

-- Match strings ending with ".jpg" (case-insensitive)
WHERE blob2 ILIKE '%.jpg'

-- Match strings containing "test" anywhere
WHERE blob3 LIKE '%test%'

-- Match exactly 5 characters starting with "log"
WHERE blob4 LIKE 'log__'

-- Exclude strings containing "debug" (case-insensitive)
WHERE blob5 NOT ILIKE '%debug%'
```

## Boolean operators

| Operator | Description |
| --- | --- |
| `AND` | boolean "AND" (true if both sides are true) |
| `OR` | boolean "OR" (true if either side or both sides are true) |
| `NOT` | boolean "NOT" (true if following expression is false and visa-versa) |

## Unary operators

| Operator | Description |
| --- | --- |
| `-` | negation operator (for example, `-42`) |

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/operators/#page","headline":"Operators","description":"Arithmetic, comparison, and logical SQL operators.","url":"https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/operators/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/operators/og.png?v=7988826db27eee17","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: SQL statements supported by Analytics Engine.
title: Statements
image: https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/statements/og.png?v=cf580b188c7fa118
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Statements

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/statements/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

## SHOW TABLES statement

`SHOW TABLES` can be used to list the tables on your account. The table name is the name you specified as `dataset` when configuring the workers binding (refer to [Get started with Workers Analytics Engine](https://developers.cloudflare.com/analytics/analytics-engine/get-started/), for more information). The table is automatically created when you write event data in your worker.

```sql
SHOW TABLES
[FORMAT <format>]
```

Refer to [FORMAT clause](#format-clause) for the available `FORMAT` options.

## SHOW TIMEZONES statement

`SHOW TIMEZONES` can be used to list all of the timezones supported by the SQL API. Most common timezones are supported.

```sql
SHOW TIMEZONES
[FORMAT <format>]
```

## SHOW TIMEZONE statement

`SHOW TIMEZONE` responds with the current default timezone in use by SQL API. This should always be `Etc/UTC`.

```sql
SHOW TIMEZONE
[FORMAT <format>]
```

## SELECT statement

`SELECT` is used to query tables.

Usage:

```sql
SELECT <expression_list>
[FROM <table>|(<subquery>)]
[WHERE <expression>]
[GROUP BY <expression>, ...]
[HAVING <expression>]
[ORDER BY <expression_list>]
[LIMIT <n>|ALL]
[FORMAT <format>]
```

Below you can find the syntax of each clause. Refer to the [SQL API](https://developers.cloudflare.com/analytics/analytics-engine/sql-api/) documentation for some example queries.

### SELECT clause

The `SELECT` clause specifies the list of columns to be included in the result. Columns can be aliased using the `AS` keyword.

Usage:

```sql
SELECT <expression> [AS <alias>], ...
```

Examples:

```sql
-- return the named columns
SELECT blob2, double3

-- return all columns
SELECT *

-- alias columns to more descriptive names
SELECT
    blob2 AS probe_name,
    double3 AS temperature
```

Additionally, expressions using supported functions and [operators](https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/operators/) can be used in place of column names:

```sql
SELECT
    blob2 AS probe_name,
    double3 AS temp_c,
    double3*1.8+32 AS temp_f -- compute a value

SELECT
    blob2 AS probe_name,
    if(double3 <= 0, 'FREEZING', 'NOT FREEZING') AS description -- use of functions

SELECT
    blob2 AS probe_name,
    avg(double3) AS avg_temp -- aggregation function
```

### FROM clause

`FROM` is used to specify the source of the data for the query.

Usage:

```sql
FROM <table_name>|(subquery)
```

Examples:

```sql
-- query data written to a workers dataset called "temperatures"
FROM temperatures

-- use a subquery to manipulate the table
FROM (
    SELECT
        blob1 AS probe_name,
        count() as num_readings
    FROM
        temperatures
    GROUP BY
        probe_name
)
```

Note that queries can only operate on a single table. `UNION`, `JOIN` etc. are not currently supported.

### WHERE clause

`WHERE` is used to filter the rows returned by a query before grouping and aggregation.

Usage:

```sql
WHERE <condition>
```

`<condition>` can be any expression that evaluates to a boolean.

[Comparison operators](https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/operators/#comparison-operators) can be used to compare values and [boolean operators](https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/operators/#boolean-operators) can be used to combine conditions.

Expressions containing functions and [operators](https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/operators/) are supported.

To filter results after grouping and aggregation, use the [`HAVING` clause](#having-clause) instead.

Examples:

```sql
-- simple comparisons
WHERE blob1 = 'test'
WHERE double1 = 4

-- inequalities
WHERE double1 > 4

-- use of operators (see below for supported operator list)
WHERE double1 + double2 > 4
WHERE blob1 = 'test1' OR blob2 = 'test2'

-- expression using inequalities, functions and operators
WHERE if(unit = 'f', (temp-32)/1.8, temp) <= 0
```

### GROUP BY clause

When using aggregate functions, `GROUP BY` specifies the groups over which the aggregation is run.

Usage:

```sql
GROUP BY <expression>, ...
```

For example, if you had a table of temperature readings:

```sql
-- return the average temperature for each probe
SELECT
    blob1 AS probe_name,
    avg(double1) AS average_temp
FROM temperature_readings
GROUP BY probe_name
```

In the usual case the `<expression>` can just be a column name but it is also possible to supply a complex expression here. Multiple expressions or column names can be supplied separated by commas.

### HAVING clause New

`HAVING` is used to filter the results after grouping and aggregation.

Usage:

```sql
HAVING <condition>
```

`<condition>` can be any expression that evaluates to a boolean, and can reference aggregate functions or grouped columns.

Unlike `WHERE`, which filters rows before grouping, `HAVING` filters groups after aggregation. This allows you to filter based on aggregate values.

[Comparison operators](https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/operators/#comparison-operators) can be used to compare values and [boolean operators](https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/operators/#boolean-operators) can be used to combine conditions.

Examples:

```sql
-- filter groups where the average is greater than 10
SELECT
    blob1 AS probe_name,
    avg(double1) AS average_temp
FROM temperature_readings
GROUP BY probe_name
HAVING average_temp > 10

-- filter groups with more than 100 readings
SELECT
    blob1 AS probe_name,
    count() AS num_readings
FROM temperature_readings
GROUP BY probe_name
HAVING num_readings > 100

-- combine multiple conditions
SELECT
    blob1 AS city,
    avg(double1) AS avg_temp,
    count() AS readings
FROM weather_data
GROUP BY city
HAVING avg_temp > 20 AND readings >= 50
```

### ORDER BY clause

`ORDER BY` can be used to control the order in which rows are returned.

Usage:

```sql
ORDER BY <expression> [ASC|DESC], ...
```

`<expression>` can just be a column name.

`ASC` or `DESC` determines if the ordering is ascending or descending. `ASC` is the default, and can be omitted.

Examples:

```sql
-- order by double2 then double3, both in ascending order
ORDER BY double2, double3

-- order by double2 in ascending order then double3 is descending order
ORDER BY double2, double3 DESC
```

### LIMIT clause

`LIMIT` specifies a maximum number of rows to return.

Usage:

```sql
LIMIT <n>|ALL
```

Supply the maximum number of rows to return or `ALL` for no restriction.

For example:

```sql
LIMIT 10 -- return at most 10 rows
```

### OFFSET clause

`OFFSET` specifies a number of rows to skip in the query result.

Usage:

```sql
OFFSET <n>
```

For example:

```sql
OFFSET 10 -- skip the first 10 result rows
```

### FORMAT clause

`FORMAT` controls how to the returned data is encoded.

Usage:

```sql
FORMAT [JSON|JSONEachRow|TabSeparated]
```

If no format clause is included then the default format of `JSON` will be used.

Override the default by setting a format. For example:

```sql
FORMAT JSONEachRow
```

The following formats are supported:

#### JSON

Data is returned as a single JSON object with schema data included:

```json
{
    "meta": [
        {
            "name": "<column 1 name>",
            "type": "<column 1 type>"
        },
        {
            "name": "<column 2 name>",
            "type": "<column 2 type>"
        },
        ...
    ],
    "data": [
        {
            "<column 1 name>": "<column 1 value>",
            "<column 2 name>": "<column 2 value>",
            ...
        },
        {
            "<column 1 name>": "<column 1 value>",
            "<column 2 name>": "<column 2 value>",
            ...
        },
        ...
    ],
    "rows": 10
}
```

#### JSONEachRow

Data is returned with a separate JSON object per row. Rows are newline separated and there is no header line or schema data:

```json
{"<column 1 name>": "<column 1 value>", "<column 2 name>": "<column 2 value>"}
{"<column 1 name>": "<column 1 value>", "<column 2 name>": "<column 2 value>"}
...
```

#### TabSeparated

Data is returned with newline separated rows. Columns are separated with tabs. There is no header.

```txt
column 1 value  column 2 value
column 1 value  column 2 value
...
```

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/statements/#page","headline":"Statements","description":"SQL statements supported by Analytics Engine.","url":"https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/statements/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/statements/og.png?v=cf580b188c7fa118","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: String manipulation SQL functions for Analytics Engine.
title: String functions
image: https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/string-functions/og.png?v=70fb059a57309419
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# String functions

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/string-functions/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

## length

Usage:

```sql
length({string})
```

Returns the length of a string. This function is UTF-8 compatible.

Examples:

```sql
SELECT length('a string') AS s;
SELECT length(blob1) AS s FROM your_dataset;
```

For backwards-compatibility, this function is the equivalent of ClickHouse's `lengthUTF8` function, rather than ClickHouse's `length` function.

## empty

Usage:

```sql
empty({string})
```

Returns a boolean saying whether the string was empty. This computation can also be done as a binary operation: `{string} = ''`.

Examples:

```sql
SELECT empty('a string') AS b;
SELECT empty(blob1) AS b FROM your_dataset;
```

For backwards compatibility, this function can also be called using `empty(<string>)`.

## lower

Usage:

```sql
lower({string})
```

Returns the string converted to lowercase. This function is NOT Unicode compatible - refer to `lowerUTF8` for that.

Examples:

```sql
SELECT lower('STRING TO DOWNCASE') AS s;
SELECT lower(blob1) AS s FROM your_dataset;
```

## lowerUTF8 New

Usage:

```sql
lowerUTF8({string})
```

Returns the string converted to lowercase. This function is Unicode compatible. This may not be perfect for all languages and users with stringent needs, should do the operation in their own code.

Examples:

```sql
SELECT lowerUTF8('STRING TO DOWNCASE') AS s;
SELECT lowerUTF8(blob1) AS s FROM your_dataset;
```

For backwards compatibility, this function can also be called using `toLower({string})`.

## upper

Usage:

```sql
upper({string})
```

Returns the string converted to uppercase. This function is NOT Unicode compatible - refer to `upperUTF8` for that.

Examples:

```sql
SELECT upper('string to uppercase') AS s;
SELECT upper(blob1) AS s FROM your_dataset;
```

## upperUTF8 New

Usage:

```sql
upperUTF8({string})
```

Returns the string converted to uppercase. This function is Unicode compatible. The results may not be perfect for all languages and users with strict needs. These users should do the operation in their own code.

Examples:

```sql
SELECT upperUTF8('string to uppercase') AS s;
SELECT upperUTF8(blob1) AS s FROM your_dataset;
```

For backwards compatibility, this function can also be called using `toUpper({string})`.

## startsWith

Usage:

```sql
startsWith({string}, {string})
```

Returns a boolean of whether the first string has the second string at its start.

Examples:

```sql
SELECT startsWith('prefix ...', 'prefix') AS b;
SELECT startsWith(blob1, 'prefix') AS b FROM your_dataset;
```

## endsWith

Usage:

```sql
endsWith({string}, {string})
```

Returns a boolean of whether the first string contains the second string at its end.

Examples:

```sql
SELECT endsWith('prefix suffix', 'suffix') AS b;
SELECT endsWith(blob1, 'suffix') AS b FROM your_dataset;
```

## position

Usage:

```sql
position({needle:string} IN {haystack:string})
```

Returns the position of one string, `needle`, in another, `haystack`. In SQL, indexes are usually 1-based. That means that position returns `1` if your needle is at the start of the haystack. It only returns `0` if your string is not found.

Examples:

```sql
SELECT position(':' IN 'hello: world') AS p;
SELECT position(':' IN blob1) AS p FROM your_dataset;
```

## substring

Usage:

```sql
substring({string}, {offset:integer}[. {length:integer}])
```

Extracts part of a string, starting at the Unicode code point indicated by the offset and returning the number of code points requested by the length. As previously mentioned, in SQL, indexes are usually 1-based. That means that the offset provided to substring should be at least `1`.

Examples:

```sql
SELECT substring('hello world', 6) AS s;
SELECT substring('hello: world', 1, position(':' IN 'hello: world')-1) AS s;
```

## format

Usage:

```sql
format({string}[, ...])
```

This function supports formatting strings, integers, floats, datetimes, intervals, etc, except `NULL`. The function does not support literal `{` and `}` characters in the format string.

Examples:

```sql
SELECT format('blob1: {}', blob1) AS s FROM dataset;
```

The [formatDateTime](https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/date-time-functions/#formatdatetime) function might also be useful.

## extract

Usage:

```sql
extract(<time unit> from <datetime>)
```

`extract` returns an integer number of time units from a datetime. It supports `YEAR`, `MONTH`, `DAY`, `HOUR`, `MINUTE` and `SECOND`.

Examples:

```sql
-- extract the number of seconds from a timestamp (returns 15 in this example)
extract(SECOND from toDateTime('2022-06-06 11:30:15'))
```

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/string-functions/#page","headline":"String functions","description":"String manipulation SQL functions for Analytics Engine.","url":"https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/string-functions/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/string-functions/og.png?v=70fb059a57309419","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Type conversion SQL functions for Analytics Engine.
title: Type conversion functions
image: https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/type-conversion-functions/og.png?v=8ed8bd1cc8f9eacf
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Type conversion functions

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/type-conversion-functions/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

## toUInt8 New

Usage:

```sql
toUInt8(<expression>)
```

Converts any numeric expression, or expression resulting in a string representation of a decimal, into an unsigned 8 bit integer.

Behaviour for negative numbers is undefined.

## toUInt32

Usage:

```sql
toUInt32(<expression>)
```

Converts any numeric expression, or expression resulting in a string representation of a decimal, into an unsigned 32 bit integer.

Behaviour for negative numbers is undefined.

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/type-conversion-functions/#page","headline":"Type conversion functions","description":"Type conversion SQL functions for Analytics Engine.","url":"https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/type-conversion-functions/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/type-conversion-functions/og.png?v=8ed8bd1cc8f9eacf","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Access Analytics Engine data from within a Worker.
title: Querying from a Worker
image: https://developers.cloudflare.com/analytics/analytics-engine/worker-querying/og.png?v=2ba5a22dec4f9be8
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Querying from a Worker

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/analytics-engine/worker-querying/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

If you want to access Analytics Engine data from within a Worker you can use `fetch` to access the SQL API. The API can return JSON data that is easy to interact with in JavaScript.

## Authentication

In order that your Worker can authenticate with the API you will need your account ID and an API token.

- Your 32 character account ID can be obtained from the Cloudflare dashboard.
- An API token can also be generated in the dashboard. Refer to the [SQL API docs](https://developers.cloudflare.com/analytics/analytics-engine/sql-api/#authentication) for more information on this.

We recommend storing the account ID as an environment variable and the API token as a secret in your worker. This can be done through the dashboard or through Wrangler. Refer to the [Workers documentation](https://developers.cloudflare.com/workers/configuration/environment-variables/) for more details on this.

## Querying

Use the JavaScript `fetch` API as follows to execute a query:

```js
const query = "SELECT * FROM my_dataset";
const API = `https://api.cloudflare.com/client/v4/accounts/${env.ACCOUNT_ID}/analytics_engine/sql`;
const response = await fetch(API, {
	method: "POST",
	headers: {
		Authorization: `Bearer ${env.API_TOKEN}`,
	},
	body: query,
});
const responseJSON = await response.json();
```

The data will be returned in the format described in the [FORMAT](https://developers.cloudflare.com/analytics/analytics-engine/sql-reference/statements/#json) section of the documentation, allowing you to extract meta information about the names and types of returned columns in addition to the data itself and a row count.

## Example Worker

The following is a sample Worker which executes a query against a dataset of weather readings and displays minimum and maximum values for each city.

### Environment variable setup

First the environment variables are set up with the account ID and API token.

The account ID is set in the [Wrangler configuration file](https://developers.cloudflare.com/workers/wrangler/configuration/):

```jsonc
{
	"vars": {
		"ACCOUNT_ID": "<account_id>"
	}
}
```

```toml
[vars]
ACCOUNT_ID = "<account_id>"
```

The API\_TOKEN can be set as a secret, using the wrangler command line tool, by running the following and entering your token string:

```sh
npx wrangler secret put API_TOKEN
```

### Worker script

The worker script itself executes a query and formats the result:

```js
export default {
	async fetch(request, env) {
		// This worker only responds to requests at the root.
		if (new URL(request.url).pathname != "/") {
			return new Response("Not found", { status: 404 });
		}

		// SQL string to be executed.
		const query = `
            SELECT
                blob1 AS city,
                max(double1) as max_temp,
                min(double1) as min_temp
            FROM weather
            WHERE timestamp > NOW() - INTERVAL '1' DAY
            GROUP BY city
            ORDER BY city`;

		// Build the API endpoint URL and make a POST request with the query string
		const API = `https://api.cloudflare.com/client/v4/accounts/${env.ACCOUNT_ID}/analytics_engine/sql`;
		const queryResponse = await fetch(API, {
			method: "POST",
			headers: {
				Authorization: `Bearer ${env.API_TOKEN}`,
			},
			body: query,
		});

		// The API will return a 200 status code if the query succeeded.
		// In case of failure we log the error message and return a failure message.
		if (queryResponse.status != 200) {
			console.error("Error querying:", await queryResponse.text());
			return new Response("An error occurred!", { status: 500 });
		}

		// Read the JSON data from the query response and render the data as HTML.
		const queryJSON = await queryResponse.json();
		return new Response(renderResponse(queryJSON.data), {
			headers: { "content-type": "text/html" },
		});
	},
};

// renderCity renders a table row as HTML from a data row.
function renderCity(row) {
	return `<tr><td>${row.city}</td><td>${row.min_temp}</td><td>${row.max_temp}</td></tr>`;
}

// renderResponse renders a simple HTML table of results.
function renderResponse(data) {
	return `<!DOCTYPE html>
<html>
    <body>
        <table>
            <tr><th>City</th><th>Min Temp</th><th>Max Temp</th></tr>
            ${data.map(renderCity).join("\n")}
        </table>
    </body>
<html>`;
}
```

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/analytics-engine/worker-querying/#page","headline":"Querying from a Worker","description":"Access Analytics Engine data from within a Worker.","url":"https://developers.cloudflare.com/analytics/analytics-engine/worker-querying/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/analytics-engine/worker-querying/og.png?v=2ba5a22dec4f9be8","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Query Cloudflare analytics data using SQL.
title: SQL API
image: https://developers.cloudflare.com/analytics/sql-api/og.png?v=eae470f8bdad1c3a
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# SQL API

Last updated Oct 2, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/sql-api/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

The SQL API lets you query Cloudflare analytics and observability datasets with SQL. Use the API to select fields, filter events, calculate aggregates, group results, and integrate analytics data with your applications.

The SQL API provides `GET` and `POST` query endpoints at:

```txt
https://api.cloudflare.com/client/v4/analytics/sql
```

Send one `SELECT` statement in each request. Use `POST` to send raw SQL or a JSON request with parameters, request-level scope, and a time range. Use `GET` for URL-encoded queries. The API validates the statement against the available datasets and supported SQL language before it executes the query.

Use the [introspection endpoint](https://developers.cloudflare.com/analytics/sql-api/datasets/#discover-datasets) to discover dataset names, categories, descriptions, kinds, columns, and data types. You can also run queries with [`cf sql query`](https://developers.cloudflare.com/analytics/sql-api/get-started/#use-the-cloudflare-cli) and list datasets with `cf sql datasets`.

The SQL API supports a deliberately limited SQL dialect. It does not pass arbitrary SQL through to the underlying data store. For the complete language surface, refer to the [SQL language reference](https://developers.cloudflare.com/analytics/sql-api/sql-reference/).

## Query scope

Every query must include:

- An account or zone scope, supplied in the SQL statement or request body, that identifies the data you are authorized to query.
- A lower time bound that limits how far back the query reads.
- One schema-qualified dataset, such as `events.httpRequests`.

Dataset and field availability depends on your Cloudflare plan and permissions. The API authorizes every account or zone named by a query.

## Get started

Refer to [Get started](https://developers.cloudflare.com/analytics/sql-api/get-started/) to create an API token and run your first query.

To query datasets from a Cloudflare Worker without managing an API token, use the [Workers binding](https://developers.cloudflare.com/analytics/sql-api/workers-binding/).

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"WebPage","@id":"https://developers.cloudflare.com/analytics/sql-api/#page","headline":"SQL API","description":"Query Cloudflare analytics data using SQL.","url":"https://developers.cloudflare.com/analytics/sql-api/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/sql-api/og.png?v=eae470f8bdad1c3a","dateModified":"2026-10-02","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Understand SQL API dataset types and discover available datasets and columns.
title: Datasets
image: https://developers.cloudflare.com/analytics/sql-api/datasets/og.png?v=4961a8dc07d46080
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Datasets

Last updated Oct 2, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/sql-api/datasets/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

Each SQL API dataset has a schema-qualified name. The prefix identifies what one row represents and how you should interpret the data:

| Prefix | Row meaning |
| --- | --- |
| `events.` | Each row is a unique event. Event datasets are often sampled. |
| `states.` | Each row represents the current state of a system when the observation was recorded. |
| `logs.` | Each row is a unique event or log entry. Log datasets are typically unsampled, but can be sampled. This includes Log Explorer datasets. |

## Event datasets

Use an `events.` dataset for aggregate analysis, such as creating tables, charts, and dashboards. You can also retrieve individual events. For example, the following query counts HTTP requests by response status:

```sql
SELECT edgeResponseStatus AS status, COUNT(*) AS requests
FROM events.httpRequests
WHERE accountTag = '<ACCOUNT_TAG>'
  AND timestamp >= NOW() - INTERVAL '1' HOUR
GROUP BY edgeResponseStatus
ORDER BY requests DESC
LIMIT 10
```

Event datasets are often adaptively sampled. The SQL API automatically applies sample weights to `COUNT`, `SUM`, and `AVG`. A query that selects individual rows only returns the sampled rows and cannot reconstruct events that were not retained.

## State datasets

Use a `states.` dataset to inspect observations of system state, such as D1 database storage. Each row describes the state at the time in its `timestamp` field. It does not represent a unique action or transaction.

```sql
SELECT timestamp, databaseId, databaseSizeBytes
FROM states.d1Storage
WHERE accountTag = '<ACCOUNT_TAG>'
  AND timestamp >= NOW() - INTERVAL '1' HOUR
ORDER BY timestamp DESC
LIMIT 100
```

Each state dataset defines which aggregate functions are meaningful for its values. The API rejects aggregate functions that are not supported by the selected state dataset. [Introspection](#discover-datasets) lists these as `valid_aggregations` on the dataset's `kind`:

```json
{
	"kind": {
		"states": {
			"sampling": "adaptive",
			"valid_aggregations": ["max"]
		}
	}
}
```

## Log datasets

Use a `logs.` dataset for fine-grained investigation of individual events and log entries. You can also aggregate log data to identify trends. This category includes datasets served by Log Explorer.

```sql
SELECT timestamp, scriptName, logType
FROM logs.workersLogs
WHERE accountTag = '<ACCOUNT_TAG>'
  AND timestamp >= NOW() - INTERVAL '15' MINUTE
ORDER BY timestamp DESC
LIMIT 100
```

Log datasets are typically unsampled, but some use adaptive sampling. As with event datasets, the SQL API automatically applies sample weights to supported aggregate functions when a log dataset is sampled.

## Workers Analytics Engine datasets

Query a Workers Analytics Engine dataset as `events.analyticsEngine.<DATASET_NAME>`, replacing `<DATASET_NAME>` with the name configured for the binding. Use an unquoted SQL identifier for names such as `myDataset`, or a double-quoted identifier for names containing characters such as hyphens: `events.analyticsEngine."example-dataset"`. These datasets require `accountTag` or `scope.accountTag`. Zone scope is not supported.

```sql
SELECT timestamp, index1, blob1, double1
FROM events.analyticsEngine."example-dataset"
WHERE accountTag = '<ACCOUNT_TAG>'
  AND timestamp >= NOW() - INTERVAL '1' HOUR
ORDER BY timestamp DESC
LIMIT 100
```

This interface uses the Analytics SQL API endpoint and SQL dialect. It is separate from the [Workers Analytics Engine SQL API](https://developers.cloudflare.com/analytics/analytics-engine/sql-api/).

Workers Analytics Engine datasets are adaptively sampled. The SQL API applies sample weights to supported aggregates. To preserve compatibility with existing Workers Analytics Engine queries, these datasets also support aggregate `DISTINCT`, `argMax`, and `argMin`. They permit `ORDER BY` without `LIMIT` and `OFFSET` without `LIMIT`. These compatibility exceptions do not apply to other adaptively sampled datasets.

[Introspection](#discover-datasets) discovers Workers Analytics Engine dataset names from the account's own data, up to a limit of 1,000 distinct names by default (truncated silently beyond that, with no time bound: a dataset remains listed for as long as any of its data is retained). This differs from `include_custom_attributes`, which only looks at the preceding seven days. Passing the bare `events.analyticsEngine` namespace as `dataset_name`, with no `<DATASET_NAME>` suffix, returns every Workers Analytics Engine dataset the account has, rather than being rejected as an unknown name.

## Discover datasets

Use the introspection endpoint to list the datasets in the SQL API catalog. The catalog is not a fixed list: datasets can appear or disappear depending on the deployment and, for Workers Analytics Engine and Log Explorer datasets, on the account. Query the catalog rather than hard-coding dataset names, and do not treat a dataset's absence from one response as proof that it can never appear.

You can use the Cloudflare CLI to inspect the catalog:

```bash
cf sql datasets --account-tag "<ACCOUNT_TAG>"
```

```bash
curl --get "https://api.cloudflare.com/client/v4/analytics/sql/introspection" \
  --header "Authorization: Bearer <API_TOKEN>" \
  --data-urlencode "account_tag=<ACCOUNT_TAG>"
```

The response contains dataset names, titles, categories, descriptions, and kinds, sorted by name. Columns are omitted by default. A `kind`'s `sampling` is either `unsampled` or `adaptive`.

```json
{
	"datasets": [
		{
			"name": "events.httpRequests",
			"title": "HTTP Requests",
			"category": "HTTP Traffic",
			"description": "Aggregated HTTP requests data with adaptive sampling",
			"kind": {
				"events": {
					"sampling": "adaptive"
				}
			}
		}
	]
}
```

### Query parameters

The endpoint accepts the following query parameters:

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `account_tag` | string | Yes | Account identifier. Requires Account Analytics Read permission. |
| `dataset_name` | string | No | Exact, case-sensitive schema-qualified dataset name to return. |
| `include_columns` | boolean | No | Set to `true` to include column names, descriptions, and data types. Defaults to `false`. |
| `include_custom_attributes` | boolean | No | Set to `true` to discover custom attribute names and types from account data. Requires a nonempty `dataset_name`. |
| `include_wae` | boolean | No | Set to `false` to omit Workers Analytics Engine datasets, which are discovered from the account's own data. Defaults to `true`. |
| `include_lex` | boolean | No | Set to `false` to omit Log Explorer datasets, which are listed only for accounts that have them. Defaults to `true`. |

### Columns

To inspect one dataset and its columns, provide both optional parameters:

```bash
curl --get "https://api.cloudflare.com/client/v4/analytics/sql/introspection" \
  --header "Authorization: Bearer <API_TOKEN>" \
  --data-urlencode "account_tag=<ACCOUNT_TAG>" \
  --data-urlencode "dataset_name=events.httpRequests" \
  --data-urlencode "include_columns=true"
```

```json
{
	"datasets": [
		{
			"name": "events.httpRequests",
			"title": "HTTP Requests",
			"category": "HTTP Traffic",
			"description": "Aggregated HTTP requests data with adaptive sampling",
			"kind": {
				"events": {
					"sampling": "adaptive"
				}
			},
			"columns": [
				{
					"name": "accountTag",
					"description": "Account tag (hex identifier)",
					"data_type": "String"
				},
				{
					"name": "timestamp",
					"description": "The date and time the event occurred at the edge",
					"data_type": "DateTime"
				}
			]
		}
	]
}
```

A column's `data_type` is one of `String`, `UInt8`, `UInt16`, `UInt32`, `UInt64`, `Int64`, `Float64`, `Date`, `DateTime`, `DateTime64(3)`, `Array(<scalar type>)` (for example `Array(String)`), or `Json`.

### Custom attributes

Introspection normally returns static catalog metadata without querying the underlying data store. Setting `include_custom_attributes=true` queries the preceding seven days of the selected dataset within the specified account:

- Each custom-attribute type is capped at the service's configured attribute limit (1,000 by default), so the response might not include every historical custom attribute.
- Truncation is silent: the response gives no indication that the limit was reached.
- A custom attribute's `data_type` is one of `String`, `Float64`, or `Bool`, a smaller set than the column `data_type` values.
- `custom_attributes` is omitted, not returned as an empty array, for a dataset that has no custom attributes to discover.

### Log Explorer availability

Log Explorer datasets include an `availability` field alongside `kind`, listing the scopes where the account has enabled the dataset:

```json
{
	"availability": [
		{ "scope": "account" },
		{ "scope": "zone", "zone": "<ZONE_TAG>" }
	]
}
```

`availability` is omitted for datasets that are not backed by Log Explorer.

### Errors

Introspection uses the same [HTTP status codes as the rest of the SQL API](https://developers.cloudflare.com/analytics/sql-api/errors/). The following `422` causes are specific to introspection:

- `account_tag` is invalid or unknown.
- `include_custom_attributes=true` was set without a nonempty `dataset_name`.
- `dataset_name` identifies a Workers Analytics Engine dataset while `include_wae=false`.
- A Workers Analytics Engine dataset name used for direct lookup is malformed or contains unsupported characters.
- The supplied criteria, such as `dataset_name`, match no dataset. A dataset that exists but is not describable in this deployment returns the identical error, with a message naming the criteria that matched nothing, so the two cases cannot be told apart.

A dataset or column appearing in the response does not guarantee that your plan and permissions allow you to query it. The SQL API applies dataset and field authorization when you submit a query.

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/sql-api/datasets/#page","headline":"Datasets","description":"Understand SQL API dataset types and discover available datasets and columns.","url":"https://developers.cloudflare.com/analytics/sql-api/datasets/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/sql-api/datasets/og.png?v=4961a8dc07d46080","dateModified":"2026-10-02","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Understand SQL API HTTP errors and how to resolve them.
title: Error responses
image: https://developers.cloudflare.com/analytics/sql-api/errors/og.png?v=0831ad0117bcd00d
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Error responses

Last updated Oct 2, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/sql-api/errors/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

The SQL API uses HTTP status codes to report errors. Errors returned by the SQL service usually have a `text/plain` body with a customer-safe description. Authentication errors rejected by the API gateway use the standard Cloudflare API JSON response envelope.

| Status | Meaning | Action |
| --- | --- | --- |
| `400` | The request is malformed, or the API gateway rejected missing or invalid authentication credentials. | Correct the request or authentication headers before retrying. |
| `403` | Authentication or authorization failed, including an explicitly selected field being denied. | Verify token permissions, resource scope, plan, and requested fields. |
| `422` | The request or SQL statement is invalid or unsupported. | Correct the request using the [SQL language reference](https://developers.cloudflare.com/analytics/sql-api/sql-reference/). |
| `429` | The request exceeded a rate, concurrency, queue, policy, or query-resource limit. | Wait before retrying or reduce query cost. Honor `Retry-After` when present. |
| `500` | An unexpected internal error occurred. | Retry later. Contact Cloudflare Support if the error persists. |
| `501` | The requested SQL processing behavior is not implemented. | Remove unsupported syntax. |
| `503` | Authorization, tenancy resolution, queueing, or the data store is unavailable. | Verify resource identifiers, then retry transient failures with bounded exponential backoff and jitter. |
| `507` | The data store could not complete the query within its resource limits. | Reduce the time range, selected data, or result size. |

## Invalid SQL

An HTTP `422` response begins with `Input was invalid:` and describes the validation failure. Common causes include:

- For HTTP API requests, missing account or zone scope in both SQL and the request body. The [Workers binding](https://developers.cloudflare.com/analytics/sql-api/workers-binding/) supplies scope automatically and rejects SQL tenancy predicates.
- Missing lower timestamp bound in both SQL and `time_range`.
- Supplying tenancy or time bounds in both SQL and the corresponding request field.
- A bare dataset name instead of a schema-qualified name.
- An unknown or unavailable field.
- `ORDER BY` without `LIMIT`, except for a Workers Analytics Engine dataset.
- Multiple SQL statements.
- Missing, duplicate, or conflicting parameter values.
- An unsupported SQL clause, output format, or function for the selected backend.

## Introspection errors

The [introspection endpoint](https://developers.cloudflare.com/analytics/sql-api/datasets/#discover-datasets) returns the same status codes as query execution, but its `422` causes relate to introspection parameters rather than SQL syntax. Refer to [Errors](https://developers.cloudflare.com/analytics/sql-api/datasets/#errors) for the causes specific to introspection.

## Retry behavior

Retry `429`, `500`, `503`, and `507` responses only when repeating the query is safe for your application. Use bounded exponential backoff with jitter. If a `429` response includes `Retry-After`, do not retry before that interval has elapsed. For `Unable to authorize` or `Unable to resolve account information`, first verify that the account or zone identifier is correct. Contact Cloudflare Support if the error persists after bounded retries.

Do not retry `400`, `403`, `422`, or `501` responses without changing the credentials, permissions, or query.

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/sql-api/errors/#page","headline":"Error responses","description":"Understand SQL API HTTP errors and how to resolve them.","url":"https://developers.cloudflare.com/analytics/sql-api/errors/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/sql-api/errors/og.png?v=0831ad0117bcd00d","dateModified":"2026-10-02","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Authenticate and run your first SQL API query.
title: Get started
image: https://developers.cloudflare.com/analytics/sql-api/get-started/og.png?v=bc12057ae3200e6d
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Get started

Last updated Oct 2, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/sql-api/get-started/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

## Prerequisites

To run an account-scoped query, you need an account identifier and an API token with **Account Analytics Read** permission for that account. A query containing `zoneTag` requires either **Zone Analytics Read** permission for every named zone or **Account Analytics Read** permission for their owning account.

SQL API datasets represent different Cloudflare products. Some datasets and fields require additional API token permissions for the products whose data they expose. Include the permissions required by every dataset and field you plan to query.

Cloudflare recommends API tokens because you can restrict each token to specific resources. Refer to [Create an API token](https://developers.cloudflare.com/fundamentals/api/get-started/create-token/) for instructions.

## Run a query

Send a `POST` request to the SQL API endpoint. Pass the SQL statement and its parameters as JSON.

The following query returns the five most common HTTP response statuses for one account after a specified start time. Replace `<START_TIME>` with a recent ISO 8601 timestamp within the dataset's retention period.

```bash
curl "https://api.cloudflare.com/client/v4/analytics/sql" \
  --header "Authorization: Bearer <API_TOKEN>" \
  --header "Content-Type: application/json" \
  --data '{
    "query": "SELECT edgeResponseStatus AS status, COUNT(*) AS requests FROM events.httpRequests WHERE accountTag = $account AND timestamp >= $start GROUP BY edgeResponseStatus ORDER BY requests DESC LIMIT 5",
    "params": {
      "account": "<ACCOUNT_TAG>",
      "start": "<START_TIME>"
    }
  }'
```

A successful response has the following structure:

```json
{
	"data": [
		{
			"status": 200,
			"requests": 125430
		},
		{
			"status": 404,
			"requests": 8240
		},
		{
			"status": 301,
			"requests": 5175
		},
		{
			"status": 304,
			"requests": 3960
		},
		{
			"status": 500,
			"requests": 82
		}
	],
	"rows": 5,
	"statistics": {
		"elapsed_ms": 42,
		"rows_read": 250000,
		"bytes_read": 18000000
	}
}
```

The `data` array contains one object for each result row. The object keys match selected field names or aliases. The `rows` value is the number of returned rows. The `statistics` object describes the work performed by the data store.

This response shape applies to the default output from ClickHouse-backed datasets. Log Explorer and explicit output formats have different response shapes. Refer to [Response formats](https://developers.cloudflare.com/analytics/sql-api/query-api/#response-formats).

## Use the Cloudflare CLI

The Cloudflare CLI provides `cf sql query`. Pass the SQL statement as a positional argument, then provide exactly one scope flag and a lower time bound:

```bash
cf sql query \
  'SELECT edgeResponseStatus AS status, COUNT(*) AS requests FROM events.httpRequests GROUP BY edgeResponseStatus ORDER BY requests DESC LIMIT 5' \
  --scope-account "<ACCOUNT_TAG>" \
  --time-since "<START_TIME>"
```

Use `--scope-zone` instead of `--scope-account` for zone scope. You can optionally add `--time-until`. Both time bounds are inclusive. Do not include tenancy or timestamp predicates in SQL when you supply the corresponding CLI flags.

For request options and parameter binding, refer to [Query the API](https://developers.cloudflare.com/analytics/sql-api/query-api/).

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/sql-api/get-started/#page","headline":"Get started","description":"Authenticate and run your first SQL API query.","url":"https://developers.cloudflare.com/analytics/sql-api/get-started/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/sql-api/get-started/og.png?v=bc12057ae3200e6d","dateModified":"2026-10-02","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Review SQL API query and request limits.
title: Limits
image: https://developers.cloudflare.com/analytics/sql-api/limits/og.png?v=decb1da875bf878f
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Limits

Last updated Oct 2, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/sql-api/limits/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

The following limits apply to SQL API queries:

| Limit | Value |
| --- | --- |
| SQL statements per request | 1 |
| SQL statement length | 10 KiB |
| Parser nesting depth | 10 |
| Datasets per statement | 1 |
| Accounts per statement | 1 |
| Minimum time constraint | A lower timestamp bound is required. |
| `ORDER BY` | Requires `LIMIT`, except for Workers Analytics Engine datasets. |
| `LIMIT` and `OFFSET` | Non-negative integer literals. `OFFSET` normally requires `LIMIT`. |

The lower timestamp bound and tenancy scope can be supplied in SQL or through the JSON request fields.

Dataset-specific limits can restrict field availability, the number of selected fields, historical retention, query duration, and the maximum number of returned rows. These limits depend on the dataset, your plan, and the account or zone being queried. A dataset-specific maximum page size rejects an explicit `LIMIT` above the maximum. It does not add a limit to a query that omits one.

The API also applies request-rate, concurrency, queue, execution-time, and resource-consumption limits. Cloudflare can adjust these operational limits to protect service availability.

When a request exceeds a rate or resource limit, the API returns HTTP `429`, `507`, or `503`. Reduce the requested time range or returned row count before retrying. Honor the `Retry-After` response header when it is present.

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/sql-api/limits/#page","headline":"Limits","description":"Review SQL API query and request limits.","url":"https://developers.cloudflare.com/analytics/sql-api/limits/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/sql-api/limits/og.png?v=decb1da875bf878f","dateModified":"2026-10-02","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Send SQL statements, parameters, and time ranges to the SQL API.
title: Query the API
image: https://developers.cloudflare.com/analytics/sql-api/query-api/og.png?v=dbb6827d9de5f3f6
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Query the API

Last updated Oct 2, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/sql-api/query-api/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

Send a `GET` or `POST` request to:

```txt
https://api.cloudflare.com/client/v4/analytics/sql
```

Include an `Authorization: Bearer <API_TOKEN>` header with every request.

Cloudflare recommends `POST` with a JSON body. `POST` also accepts raw SQL, and `GET` accepts SQL in the `query` query parameter.

## JSON request

The recommended request format is a JSON object:

```json
{
	"query": "SELECT timestamp, clientRequestHttpHost FROM events.httpRequests WHERE accountTag = $1 AND timestamp >= $2 LIMIT 100",
	"params": ["<ACCOUNT_TAG>", "2026-09-15T00:00:00Z"]
}
```

The request object supports the following fields:

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `query` | string | Yes | One SQL `SELECT` statement. |
| `params` | array or object | No | Values for positional or named placeholders in `query`. |
| `scope` | object | No | An account or zone scope supplied separately from SQL. |
| `time_range` | object | No | A time range supplied separately from the SQL statement. |

## Parameters

Use parameters instead of inserting user-provided values into SQL text. Parameters keep values separate from SQL syntax.

Use `$1`, `$2`, and subsequent placeholders with an array:

```json
{
	"query": "SELECT timestamp FROM events.httpRequests WHERE accountTag = $1 AND timestamp >= $2 LIMIT 10",
	"params": ["<ACCOUNT_TAG>", "2026-09-15T00:00:00Z"]
}
```

Use `$name` placeholders with an object:

```json
{
	"query": "SELECT timestamp FROM events.httpRequests WHERE accountTag = $account AND timestamp >= $start LIMIT 10",
	"params": {
		"account": "<ACCOUNT_TAG>",
		"start": "2026-09-15T00:00:00Z"
	}
}
```

Parameter values can be strings, numbers, booleans, or `null`. The API infers the required type from the expression. Every placeholder must have a corresponding value.

For `GET` and raw SQL `POST` requests, bind placeholders with URL query parameters named `param_<NAME>`. For example, `param_status=404` binds `$status`, and `param_1=404` binds `$1`. Duplicate parameter names are rejected. Do not combine URL parameters with `params` in a JSON body.

## Request-level scope

You can supply the account or zone scope outside the SQL statement. This allows applications to reuse SQL without embedding a tenancy predicate.

Use `accountTag` for account scope:

```json
{
	"query": "SELECT edgeResponseStatus AS status, COUNT(*) AS requests FROM events.httpRequests WHERE timestamp >= $start GROUP BY edgeResponseStatus",
	"params": {
		"start": "<START_TIME>"
	},
	"scope": {
		"accountTag": "<ACCOUNT_TAG>"
	}
}
```

Use `zoneTag` for zone scope:

```json
{
	"query": "SELECT COUNT(*) AS requests FROM events.httpRequests WHERE timestamp >= $start",
	"params": {
		"start": "<START_TIME>"
	},
	"scope": {
		"zoneTag": "<ZONE_TAG>"
	}
}
```

A query that contains `zoneTag`, including request-level zone scope, requires either **Zone Analytics Read** permission for every named zone or **Account Analytics Read** permission for their owning account.

The `scope` object must contain exactly one of `accountTag` or `zoneTag`. Do not combine request-level scope with an `accountTag`, `zoneTag`, or resource tenancy predicate in SQL. The API returns HTTP `422` if the request specifies tenancy in both places.

Account and zone tags must be 32-character lowercase hexadecimal strings.

Request-level scope is available only with the JSON request format.

## Request-level time range

You can supply a time range outside the SQL statement. This is useful when an application controls the query window separately from saved SQL.

```json
{
	"query": "SELECT edgeResponseStatus AS status, COUNT(*) AS requests FROM events.httpRequests WHERE accountTag = $account GROUP BY edgeResponseStatus",
	"params": {
		"account": "<ACCOUNT_TAG>"
	},
	"time_range": {
		"start": "2026-09-15T00:00:00Z",
		"end": "2026-09-15T01:00:00Z"
	}
}
```

The `start` value is required. The `end` value is optional. Both bounds are inclusive.

Do not combine `time_range` with a time predicate in SQL. The API rejects a request that specifies the time range in both places.

## Raw SQL request

The API also accepts SQL text as the request body:

```bash
curl "https://api.cloudflare.com/client/v4/analytics/sql" \
  --header "Authorization: Bearer <API_TOKEN>" \
  --data "SELECT COUNT(*) AS requests FROM events.httpRequests WHERE accountTag = '<ACCOUNT_TAG>' AND timestamp >= NOW() - INTERVAL '1' HOUR"
```

Raw SQL requests can use URL parameter bindings:

```bash
curl --get "https://api.cloudflare.com/client/v4/analytics/sql" \
  --header "Authorization: Bearer <API_TOKEN>" \
  --data-urlencode 'query=SELECT COUNT(*) AS requests FROM events.httpRequests WHERE accountTag = $account AND timestamp >= $start' \
  --data-urlencode "param_account=<ACCOUNT_TAG>" \
  --data-urlencode "param_start=<START_TIME>"
```

For a raw SQL `POST`, place SQL in the request body and use the same `param_*` URL parameters for values. Use the JSON request format when an application supplies request-level scope or a time range.

## Response formats

Without a `FORMAT` clause, ClickHouse-backed datasets return JSON with `data`, `rows`, and `statistics`:

```json
{
	"data": [],
	"rows": 0,
	"statistics": {
		"elapsed_ms": 12,
		"rows_read": 10000,
		"bytes_read": 720000
	}
}
```

| Field | Type | Description |
| --- | --- | --- |
| `data` | array | Result rows represented as JSON objects. |
| `rows` | integer | Number of objects in `data`. |
| `statistics.elapsed_ms` | integer | Data-store execution time in milliseconds. |
| `statistics.rows_read` | integer | Number of rows read to execute the query. |
| `statistics.bytes_read` | integer | Number of bytes read to execute the query. |

Execution statistics do not include queue time, retries, network transfer, or client-side processing. A value can be `0` when the data store does not report that statistic.

Log Explorer-backed datasets return `data` and `rows` without `statistics`.

Add one of the following clauses to the end of a query to select an explicit output format:

| Clause | Content type | Output |
| --- | --- | --- |
| `FORMAT JSON` | `application/json` | JSON with typed `meta`, `data`, `rows`, `rows_before_limit_at_least`, and `statistics` for ClickHouse. |
| `FORMAT JSONEachRow` | `application/x-ndjson` | One JSON object per line without a response envelope. |
| `FORMAT TabSeparated` | `text/tab-separated-values` | Tab-separated rows without a header or response envelope. |
| `FORMAT TSV` | `text/tab-separated-values` | Alias for `FORMAT TabSeparated`. |

For Log Explorer datasets, `FORMAT JSON` returns the same `data` and `rows` shape as the default response. It does not add ClickHouse metadata or statistics.

```sql
SELECT timestamp, edgeResponseStatus
FROM events.httpRequests
WHERE accountTag = '<ACCOUNT_TAG>'
  AND timestamp >= NOW() - INTERVAL '1' HOUR
LIMIT 10
FORMAT JSONEachRow
```

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/sql-api/query-api/#page","headline":"Query the API","description":"Send SQL statements, parameters, and time ranges to the SQL API.","url":"https://developers.cloudflare.com/analytics/sql-api/query-api/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/sql-api/query-api/og.png?v=dbb6827d9de5f3f6","dateModified":"2026-10-02","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Reference for the SQL syntax supported by the SQL API.
title: SQL language reference
image: https://developers.cloudflare.com/analytics/sql-api/sql-reference/og.png?v=8e7234eb8b0d8a77
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# SQL language reference

Last updated Oct 2, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/sql-api/sql-reference/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

The SQL API supports a read-only subset of SQL for analytics queries. SQL keywords and function names are case-insensitive. Dataset and field names are case-sensitive.

Every query must read one schema-qualified dataset and must include an account or zone scope and a lower time bound. For HTTP API requests, you can provide scope and time bounds in SQL or through the JSON request fields. Workers binding queries are the exception: the binding supplies account scope automatically, so include only the time bound in SQL. For example:

```sql
SELECT
  clientRequestHttpHost AS host,
  COUNT(*) AS requests
FROM events.httpRequests
WHERE accountTag = '<ACCOUNT_TAG>'
  AND timestamp >= NOW() - INTERVAL '1' HOUR
GROUP BY clientRequestHttpHost
ORDER BY requests DESC
LIMIT 10
```

## Reference

- [Statements and clauses](https://developers.cloudflare.com/analytics/sql-api/sql-reference/statements/)
- [Operators](https://developers.cloudflare.com/analytics/sql-api/sql-reference/operators/)
- [Functions](https://developers.cloudflare.com/analytics/sql-api/sql-reference/functions/)
- [Data types and literals](https://developers.cloudflare.com/analytics/sql-api/sql-reference/data-types/)

## Unsupported features

The SQL API does not support arbitrary ClickHouse SQL. Unsupported features include:

- Data modification or definition statements, including `INSERT`, `UPDATE`, `DELETE`, `CREATE`, `ALTER`, and `DROP`.
- Joins, unions, common table expressions, and general subqueries. One restricted derived-table projection is supported.
- Window functions.
- Row-level `SELECT DISTINCT`. `COUNT`, `SUM`, and `AVG` support `DISTINCT` on unsampled datasets and Workers Analytics Engine datasets.
- `FETCH`. ClickHouse-backed datasets support `OFFSET` with `LIMIT`.
- `EXPLAIN`, `ANALYZE`, `DESCRIBE`, `VALUES`, and `UNNEST`.
- `SIMILAR TO`, `LIKE ... ESCAPE`, and user-authored casts.
- Aggregate `FILTER` and aggregate-local `ORDER BY` clauses.

The API returns an HTTP `422` response when a statement contains unsupported syntax.

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/sql-api/sql-reference/#page","headline":"SQL language reference","description":"Reference for the SQL syntax supported by the SQL API.","url":"https://developers.cloudflare.com/analytics/sql-api/sql-reference/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/sql-api/sql-reference/og.png?v=8e7234eb8b0d8a77","dateModified":"2026-10-02","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Data types, literals, arrays, and JSON values supported by the SQL API.
title: Data types and literals
image: https://developers.cloudflare.com/analytics/sql-api/sql-reference/data-types/og.png?v=e0a6da4814b37cd9
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Data types and literals

Last updated Oct 2, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/sql-api/sql-reference/data-types/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

Dataset schemas can expose the following field types:

| Type | Description |
| --- | --- |
| `String` | UTF-8 text. |
| `UInt8`, `UInt16`, `UInt32`, `UInt64` | Unsigned integers. |
| `Int64` | Signed integer. |
| `Float64` | Double-precision floating-point number. |
| `Date` | Calendar date. |
| `DateTime` | Timestamp with second precision. |
| `DateTime64(3)` | Timestamp with millisecond precision. |
| `Array(type)` | List of values of one scalar type. |
| `Json` | Object with dynamically typed values. |

## Literals

The SQL API supports integer, floating-point, string, and Boolean literals.

```sql
SELECT
  42 AS integer_value,
  3.14 AS float_value,
  'example' AS string_value,
  TRUE AS boolean_value
FROM events.httpRequests
WHERE accountTag = '<ACCOUNT_TAG>'
  AND timestamp >= '2026-09-15T00:00:00Z'
LIMIT 1
```

Escape a single quote inside a string according to standard SQL string literal syntax.

Standalone `NULL` literals are not supported. Expressions can still produce null values, and `IS NULL` and `IS NOT NULL` predicates are supported.

## Timestamp values

Use an ISO 8601 timestamp with a timezone:

```sql
timestamp >= '2026-09-15T08:30:00Z'
timestamp >= '2026-09-15T10:30:00+02:00'
```

The API normalizes timestamp values to UTC. A date without a time is interpreted as midnight UTC:

```sql
timestamp >= '2026-09-15'
```

A date and time without a timezone is rejected. For example, do not use `'2026-09-15T08:30:00'`.

## Arrays

An array field can only be selected as a complete, top-level result field:

```sql
SELECT botTags
FROM logs.httpRequests
WHERE zoneTag = '<ZONE_TAG>'
  AND timestamp >= '2026-09-15T00:00:00Z'
LIMIT 10
```

Array filtering, grouping, sorting, aggregation, indexing, and unnesting are not supported.

## JSON fields

Some datasets expose unstructured fields as JSON objects. You can select the complete object or one exact top-level key:

```sql
SELECT attributes, attributes['http.method'] AS method
FROM logs.workersLogs
WHERE accountTag = '<ACCOUNT_TAG>'
  AND timestamp >= NOW() - INTERVAL '1' HOUR
LIMIT 10
```

Key lookup is exact. A key such as `http.method` is one top-level key, not a path through a nested object. A missing key returns JSON `null`.

Depending on the dataset backend, an exact-key lookup can also be compared with a string, number, or Boolean literal, grouped, or passed to `SUM` and `AVG`:

```sql
SELECT attributes['http.method'] AS method, COUNT(*) AS events
FROM logs.workersLogs
WHERE accountTag = '<ACCOUNT_TAG>'
  AND timestamp >= NOW() - INTERVAL '1' HOUR
  AND attributes['http.method'] = 'GET'
GROUP BY attributes['http.method']
```

JSON casts, nested traversal, ordering by JSON values, comparisons between two JSON values, and `COUNT` of a JSON key are not supported. Dynamic JSON lookups also cannot be wrapped in `LIKE`, `BETWEEN`, `IS NULL`, or `CASE` expressions.

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/sql-api/sql-reference/data-types/#page","headline":"Data types and literals","description":"Data types, literals, arrays, and JSON values supported by the SQL API.","url":"https://developers.cloudflare.com/analytics/sql-api/sql-reference/data-types/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/sql-api/sql-reference/data-types/og.png?v=e0a6da4814b37cd9","dateModified":"2026-10-02","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: SQL aggregate, scalar, and time functions supported by the SQL API.
title: Functions
image: https://developers.cloudflare.com/analytics/sql-api/sql-reference/functions/og.png?v=16c84c1bc000dc43
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Functions

Last updated Oct 2, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/sql-api/sql-reference/functions/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

Function names are case-insensitive.

## Aggregate functions

| Function | Description |
| --- | --- |
| `COUNT(*)` or `COUNT()` | Count matching rows or represented events. `COUNT(expression)` is not supported. |
| `SUM(expression)` | Sum a numeric expression. |
| `AVG(expression)` | Calculate the arithmetic mean of a numeric expression. |
| `MIN(expression)`, `MAX(expression)` | Return an exact extremum on an unsampled dataset. |
| `APPROX_MIN(expression)`, `APPROX_MAX(expression)` | Return the smallest or largest value observed in retained rows of an adaptively sampled dataset. |
| `countIf(condition)` | Count rows that satisfy a condition. |
| `sumIf(expression, condition)` | Sum values from rows that satisfy a condition. |
| `avgIf(expression, condition)` | Average values from rows that satisfy a condition. |
| `first_value(expression)`, `last_value(expression)` | Return the first or last value in the aggregate input. |
| `argMax(value, expression)`, `argMin(value, expression)` | Return `value` from the row with the largest or smallest `expression`. |
| `topK(expression)` | Return an array of the most frequent values. Supports ClickHouse-style parameters such as `topK(10)(expression)`. |
| `topKWeighted(expression, weight)` | Return the most frequent values using explicit weights. Supports parameters such as `topKWeighted(10)(expression, weight)`. |
| `quantileWeighted(level, expression, weight)` | Calculate a weighted quantile. `level` must be between `0` and `1`. |
| `quantileExactWeighted(level)(expression, weight)` | Alias form of `quantileWeighted`. |

`topK` accepts up to three optional parameters before its value expression. `topKWeighted` accepts the same parameters before its value and weight expressions. The requested top-k size and load factor must each be between `1` and `100`.

The compatibility aggregates from `countIf` through `quantileExactWeighted` in the table are supported by ClickHouse-backed datasets. Log Explorer-backed datasets support `COUNT`, `SUM`, `AVG`, `MIN`, `MAX`, `APPROX_MIN`, and `APPROX_MAX`.

### Adaptive sampling

For adaptively sampled event and log datasets, the SQL API automatically applies sample weights to `COUNT`, `SUM`, `AVG`, `countIf`, `sumIf`, `avgIf`, and `topK`. You do not need to use `sampleInterval` yourself for these functions. Weighted averages exclude null expression values from both the numerator and denominator.

`topKWeighted` and `quantileWeighted` use the explicit weight argument supplied by the query. Pass `sampleInterval` when you want that weight to represent the dataset's adaptive sampling.

```sql
SELECT countIf(edgeResponseStatus >= 500) AS server_errors
FROM events.httpRequests
WHERE accountTag = '<ACCOUNT_TAG>'
  AND timestamp >= NOW() - INTERVAL '1' HOUR
```

Exact `MIN` and `MAX` are rejected for adaptively sampled event and log datasets. Use `APPROX_MIN` and `APPROX_MAX` to calculate extrema from retained sample rows. These functions cannot reconstruct values from events that sampling did not retain.

`argMax` and `argMin` are also rejected on adaptively sampled datasets, except Workers Analytics Engine datasets, which preserve their existing compatibility behavior.

### DISTINCT aggregates

The following forms are supported by ClickHouse-backed unsampled datasets:

```sql
COUNT(DISTINCT expression)
SUM(DISTINCT expression)
AVG(DISTINCT expression)
```

Other `DISTINCT` aggregates and row-level `SELECT DISTINCT` are not supported. Adaptively sampled datasets reject `DISTINCT` aggregates because omitted values cannot be reconstructed. Workers Analytics Engine datasets retain `COUNT`, `SUM`, and `AVG DISTINCT` for compatibility.

Log Explorer-backed datasets support `COUNT(DISTINCT expression)` and `SUM(DISTINCT expression)`, but not `AVG(DISTINCT expression)`.

### State datasets

State dataset rows represent observations of a system's state rather than unique events. Unrestricted aggregation could produce misleading or nonsensical results, so each state dataset exposes a `valid_aggregations` list through [introspection](https://developers.cloudflare.com/analytics/sql-api/datasets/#discover-datasets). The list can contain `count`, `sum`, `avg`, `min`, or `max`.

`countIf`, `sumIf`, and `avgIf` require the corresponding base aggregation. Other compatibility aggregates, including approximate extrema, are not supported on state datasets.

## Scalar functions

The following scalar functions are supported on ClickHouse-backed datasets. Function names are case-insensitive.

| Category | Functions |
| --- | --- |
| Conditional | `if(condition, then, else)` |
| Numeric | `intDiv`, `round`, `ceil`, `floor`, `log`, `pow` |
| String | `length`, `isEmpty`, `toLower`, `toUpper`, `startsWith`, `endsWith`, `substring`, `position`, `format` |
| Conversion and representation | `toUInt8`, `toUInt32`, `bin`, `hex` |
| Bitwise | `bitAnd`, `bitCount`, `bitHammingDistance`, `bitNot`, `bitOr`, `bitRotateLeft`, `bitRotateRight`, `bitShiftLeft`, `bitShiftRight`, `bitTest`, `bitXor` |
| Date parts | `date_part`, `EXTRACT`, `toYear`, `toMonth`, `toDayOfMonth`, `toDayOfWeek`, `toHour`, `toMinute`, `toSecond`, `toYYYYMM` |
| Date and time conversion | `toUnixTimestamp`, `formatDateTime`, `toDateTime`, `toDate`, `timezone` |
| Time buckets | `toStartOfInterval`, `toStartOfDay`, `toStartOfMinute`, `toStartOfFiveMinutes`, `toStartOfTenMinutes`, `toStartOfFifteenMinutes`, `toStartOfHour`, `toStartOfWeek`, `toStartOfMonth`, `toStartOfYear` |
| Interval constructors | `toIntervalSecond`, `toIntervalMinute`, `toIntervalHour`, `toIntervalDay`, `toIntervalWeek`, `toIntervalMonth`, `toIntervalQuarter`, `toIntervalYear` |

Supported aliases include `lengthUTF8`, `empty`, `lower`, `lowerUTF8`, `upper`, `upperUTF8`, `substr`, `strpos`, `ceiling`, `ln`, `dayOfWeek`, and `toStartOfFiveMinute`.

Log Explorer-backed datasets support only a subset of these functions: `if`, `isEmpty`, `startsWith`, `endsWith`, `pow`, `length`, `toLower`, `toUpper`, `position`, one-argument `ceil` and `floor`, `log`, `toYear`, `toMonth`, `toHour`, `toMinute`, `toSecond`, `toDayOfMonth`, `toDayOfWeek`, `toYYYYMM`, `toDate`, `toStartOfWeek`, `toStartOfMonth`, and `toStartOfYear`. The API returns HTTP `422` when the selected backend does not support a function.

## Current date and time

The API resolves current-time functions once when it plans the query. Repeated uses in one query represent the same instant.

| Function | Description |
| --- | --- |
| `NOW()` | Return the current UTC timestamp. |
| `CURRENT_TIMESTAMP()` | Equivalent to `NOW()`. |
| `TODAY()` | Return the start of the current day in UTC. |
| `CURRENT_DATE()` | Equivalent to `TODAY()`. |

```sql
SELECT CURRENT_TIMESTAMP() AS queried_at, COUNT(*) AS requests
FROM events.httpRequests
WHERE accountTag = '<ACCOUNT_TAG>'
  AND timestamp >= TODAY()
```

## Time buckets and intervals

`toStartOfInterval(timestamp, interval[, timezone])` rounds a `DateTime` or `DateTime64(3)` value down to the beginning of an interval:

```sql
SELECT
  toStartOfInterval(timestamp, INTERVAL '15' MINUTE) AS bucket,
  COUNT(*) AS requests
FROM events.httpRequests
WHERE accountTag = '<ACCOUNT_TAG>'
  AND timestamp >= NOW() - INTERVAL '1' DAY
GROUP BY bucket
```

The interval must contain a positive integer and one of the following units: `YEAR`, `QUARTER`, `MONTH`, `WEEK`, `DAY`, `HOUR`, `MINUTE`, `SECOND`, `MILLISECOND`, `MICROSECOND`, or `NANOSECOND`. The optional timezone must be a string literal. `toStartOfInterval` is not supported for Log Explorer-backed datasets.

Add an interval to or subtract an interval from a timestamp expression:

```sql
NOW() - INTERVAL '15' MINUTE
NOW() - INTERVAL '7' DAY
```

The SQL API rejects scalar and aggregate functions that are not listed on this page.

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/sql-api/sql-reference/functions/#page","headline":"Functions","description":"SQL aggregate, scalar, and time functions supported by the SQL API.","url":"https://developers.cloudflare.com/analytics/sql-api/sql-reference/functions/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/sql-api/sql-reference/functions/og.png?v=16c84c1bc000dc43","dateModified":"2026-10-02","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: SQL operators supported by the SQL API.
title: Operators
image: https://developers.cloudflare.com/analytics/sql-api/sql-reference/operators/og.png?v=7988826db27eee17
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Operators

Last updated Oct 2, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/sql-api/sql-reference/operators/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

## Arithmetic operators

| Operator | Description | Example |
| --- | --- | --- |
| `+` | Addition | `requests + 1` |
| `-` | Subtraction | `bytes - cachedBytes` |
| `*` | Multiplication | `requests * 100` |
| `/` | Division | `bytes / requests` |
| `%` | Modulo | `edgeResponseStatus % 100` |
| unary `-` | Negation | `-1` |

The field types in a dataset determine which arithmetic operations are valid.

## Comparison operators

| Operator | Description |
| --- | --- |
| `=` | Equal to |
| `!=` or `<>` | Not equal to |
| `<` | Less than |
| `<=` | Less than or equal to |
| `>` | Greater than |
| `>=` | Greater than or equal to |

## Logical operators

| Operator | Description |
| --- | --- |
| `AND` | Both predicates are true. |
| `OR` | At least one predicate is true. |
| `NOT` | Negates a predicate. |

Parentheses control evaluation order:

```sql
WHERE accountTag = '<ACCOUNT_TAG>'
  AND timestamp >= NOW() - INTERVAL '1' HOUR
  AND (edgeResponseStatus = 429 OR edgeResponseStatus >= 500)
```

Tenancy predicates are an exception. Keep `accountTag` and `zoneTag` predicates at the top level and join them with `AND`.

## IN

Use `IN` or `NOT IN` to compare a scalar expression with a non-empty list:

```sql
edgeResponseStatus IN (403, 404, 429)
```

`NOT IN` is not supported for account or zone tenancy predicates.

## BETWEEN

Use `BETWEEN` to test an inclusive range. `NOT BETWEEN` negates the test:

```sql
timestamp BETWEEN '2026-09-15T00:00:00Z' AND '2026-09-15T01:00:00Z'
edgeResponseStatus BETWEEN 400 AND 499
```

## Pattern matching

Use `LIKE` and `NOT LIKE` for case-sensitive pattern matching. Use `ILIKE` and `NOT ILIKE` for case-insensitive matching. In a pattern, `%` matches any sequence of characters and `_` matches one character.

```sql
clientRequestHttpHost ILIKE 'api.%'
```

`LIKE ... ESCAPE` is not supported.

## Null predicates

Use `IS NULL` or `IS NOT NULL` to test whether an expression is null:

```sql
originResponseStatus IS NOT NULL
```

This does not make a standalone `NULL` literal valid in other expressions.

## CASE

The SQL API supports searched and simple `CASE` expressions:

```sql
CASE
  WHEN edgeResponseStatus >= 500 THEN 'server error'
  WHEN edgeResponseStatus >= 400 THEN 'client error'
  ELSE 'other'
END

CASE edgeResponseStatus
  WHEN 200 THEN 'ok'
  ELSE 'other'
END
```

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/sql-api/sql-reference/operators/#page","headline":"Operators","description":"SQL operators supported by the SQL API.","url":"https://developers.cloudflare.com/analytics/sql-api/sql-reference/operators/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/sql-api/sql-reference/operators/og.png?v=7988826db27eee17","dateModified":"2026-10-02","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: SQL statements and clauses supported by the SQL API.
title: Statements and clauses
image: https://developers.cloudflare.com/analytics/sql-api/sql-reference/statements/og.png?v=c0195f3b9cab1c15
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Statements and clauses

Last updated Oct 2, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/sql-api/sql-reference/statements/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

## SELECT

The SQL API accepts one `SELECT` statement per request.

```sql
SELECT select_expression [, ...]
FROM schema.dataset
[WHERE predicate]
[GROUP BY expression [, ...]]
[HAVING aggregate_predicate]
[ORDER BY expression [ASC | DESC] [, ...]]
[LIMIT non_negative_integer [OFFSET non_negative_integer]]
[FORMAT JSON | JSONEachRow | TabSeparated | TSV]
```

Use a schema-qualified dataset name, such as `events.httpRequests`. Bare dataset names are not supported.

Use `AS` to set result field names:

```sql
SELECT
  clientRequestHttpHost AS host,
  edgeResponseStatus AS status
FROM events.httpRequests
WHERE accountTag = '<ACCOUNT_TAG>'
  AND timestamp >= NOW() - INTERVAL '1' DAY
LIMIT 100
```

`SELECT *` returns every field that is available to the caller. If permissions deny a field reached only through `*`, the API omits it. Explicitly selecting a denied field returns HTTP `403`. Explicit field lists provide a more stable response when a dataset gains fields.

## WHERE

Use `WHERE` to set tenancy, time, and data filters.

```sql
WHERE accountTag = '<ACCOUNT_TAG>'
  AND timestamp >= NOW() - INTERVAL '1' DAY
  AND edgeResponseStatus >= 500
```

Every HTTP API query requires an account or zone scope. You can provide scope through the JSON request instead of SQL. The [Workers binding](https://developers.cloudflare.com/analytics/sql-api/workers-binding/) supplies account scope automatically, so do not include a tenancy predicate in binding queries. Supported SQL tenancy forms for HTTP API queries are:

```sql
accountTag = '<ACCOUNT_TAG>'
zoneTag = '<ZONE_TAG>'
zoneTag IN ('<ZONE_TAG_1>', '<ZONE_TAG_2>')
```

A query can select only one account. Specify zone tenancy in one `zoneTag` predicate. Use `IN` to select multiple zones. Tenancy predicates must be top-level conditions joined with `AND`. Do not place `accountTag` or `zoneTag` inside `OR`, `NOT`, or `NOT IN` expressions.

Any query containing `zoneTag` requires either **Zone Analytics Read** permission for every named zone or **Account Analytics Read** permission for their owning account.

Every query also requires a lower bound on the dataset timestamp field. Use `>`, `>=`, or `BETWEEN` to provide the lower bound, or use request-level `time_range`. The timestamp field name varies by dataset.

## GROUP BY

Use `GROUP BY` with aggregate functions to return one row for each unique group.

```sql
SELECT edgeResponseStatus AS status, COUNT(*) AS requests
FROM events.httpRequests
WHERE accountTag = '<ACCOUNT_TAG>'
  AND timestamp >= NOW() - INTERVAL '1' HOUR
GROUP BY edgeResponseStatus
```

## HAVING

Use `HAVING` to filter grouped results. A `HAVING` expression must reference an aggregate function.

```sql
SELECT clientRequestHttpHost AS host, COUNT(*) AS requests
FROM events.httpRequests
WHERE accountTag = '<ACCOUNT_TAG>'
  AND timestamp >= NOW() - INTERVAL '1' HOUR
GROUP BY clientRequestHttpHost
HAVING COUNT(*) > 100
```

## ORDER BY

Use `ORDER BY` to sort results in ascending (`ASC`) or descending (`DESC`) order. `ASC` is the default.

Every query that uses `ORDER BY` must also use `LIMIT`. Workers Analytics Engine datasets preserve compatibility with `ORDER BY` without `LIMIT`.

```sql
ORDER BY requests DESC
LIMIT 10
```

`NULLS FIRST` and `NULLS LAST` are not supported.

## LIMIT

`LIMIT` accepts a non-negative integer literal. Parameters and expressions are not supported as limit values.

```sql
LIMIT 100
```

## OFFSET

ClickHouse-backed datasets support `OFFSET` after `LIMIT`. Both values must be non-negative integer literals. Log Explorer-backed datasets do not support `OFFSET`.

```sql
LIMIT 100 OFFSET 200
```

Workers Analytics Engine datasets also preserve compatibility with `OFFSET` without `LIMIT`.

## FORMAT

Add a top-level `FORMAT` clause to select the response format:

```sql
FORMAT JSON
FORMAT JSONEachRow
FORMAT TabSeparated
FORMAT TSV
```

`TSV` is an alias for `TabSeparated`. Refer to [Response formats](https://developers.cloudflare.com/analytics/sql-api/query-api/#response-formats) for content types and response shapes. A `FORMAT` clause inside a derived table is not supported.

## Derived table projection

The SQL API supports one restricted derived table when the outer query only projects expressions from the inner query:

```sql
SELECT value
FROM (
  SELECT COUNT(*) AS value
  FROM events.httpRequests
  WHERE accountTag = '<ACCOUNT_TAG>'
    AND timestamp >= NOW() - INTERVAL '1' HOUR
)
```

The outer query cannot add filtering, grouping, aggregation, ordering, or a limit. The inner query can contain supported ordering and limits. Derived table aliases and nested derived tables are not supported.

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/sql-api/sql-reference/statements/#page","headline":"Statements and clauses","description":"SQL statements and clauses supported by the SQL API.","url":"https://developers.cloudflare.com/analytics/sql-api/sql-reference/statements/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/sql-api/sql-reference/statements/og.png?v=c0195f3b9cab1c15","dateModified":"2026-10-02","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Query the SQL API directly from a Cloudflare Worker.
title: Workers binding
image: https://developers.cloudflare.com/analytics/sql-api/workers-binding/og.png?v=84705ed1b99f3db3
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Workers binding

Last updated Oct 2, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/sql-api/workers-binding/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

The Analytics SQL binding lets a Cloudflare Worker query SQL API datasets without making an HTTP request or managing an API token. Each binding is scoped to the Cloudflare account that owns the Worker.

## Configure the binding

Add an Analytics SQL binding to your Worker's Wrangler configuration. The `analytics` key requires Wrangler 4.145.0 or later.

```jsonc
{
	"analytics": {
		"binding": "ANALYTICS_SQL"
	}
}
```

```toml
[analytics]
binding = "ANALYTICS_SQL"
```

The `binding` value determines how you access the binding on your Worker's `env` object.

## Query from a Worker

Call the binding's `query()` method with a SQL statement and optional parameters:

```js
export default {
	async fetch(_request, env) {
		const start = new Date(Date.now() - 60 * 60 * 1000).toISOString();
		const result = await env.ANALYTICS_SQL.query({
			query: `
        SELECT edgeResponseStatus AS status, COUNT(*) AS requests
        FROM events.httpRequests
        WHERE timestamp >= $start
        GROUP BY edgeResponseStatus
        ORDER BY requests DESC
        LIMIT 10
      `,
			params: { start },
		});

		return Response.json(result);
	},
};
```

```ts
interface Env {
	ANALYTICS_SQL: AnalyticsSQLBinding;
}

export default {
	async fetch(_request, env): Promise<Response> {
		const start = new Date(Date.now() - 60 * 60 * 1000).toISOString();
		const result = await env.ANALYTICS_SQL.query({
			query: `
        SELECT edgeResponseStatus AS status, COUNT(*) AS requests
        FROM events.httpRequests
        WHERE timestamp >= $start
        GROUP BY edgeResponseStatus
        ORDER BY requests DESC
        LIMIT 10
      `,
			params: { start },
		});

		return Response.json(result);
	},
} satisfies ExportedHandler<Env>;
```

Do not include an `accountTag` or `zoneTag` predicate in a binding query. The binding supplies the Worker's account scope separately and the API rejects a query that also specifies tenancy in SQL.

The binding can query only datasets that support account scope.

The binding can query Workers Analytics Engine datasets through names such as `events.analyticsEngine."example-dataset"`. Access still depends on the account's Workers Analytics Engine entitlement.

## Request

The `query()` method accepts the following fields:

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `query` | string | Yes | One SQL `SELECT` statement. |
| `params` | array or object | No | Positional or named string, number, boolean, or `null` values. |

The binding does not accept `scope` because it derives scope from the Worker. It does not currently expose request-level `time_range`. Include the time constraint in SQL.

## Response

The method returns the default ClickHouse-backed result structure:

```json
{
	"data": [
		{
			"status": 200,
			"requests": 125430
		}
	],
	"rows": 1,
	"statistics": {
		"elapsed_ms": 42,
		"rows_read": 250000,
		"bytes_read": 18000000
	}
}
```

Do not add a `FORMAT` clause to binding queries. The binding expects the default JSON response with `statistics`. Log Explorer-backed datasets currently return a different response shape and are not supported through the binding.

The binding does not retry failed requests automatically. A thrown error includes a boolean `retryable` property that indicates whether retrying may succeed. Apply bounded exponential backoff only when `retryable` is `true`.

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/sql-api/workers-binding/#page","headline":"Workers binding","description":"Query the SQL API directly from a Cloudflare Worker.","url":"https://developers.cloudflare.com/analytics/sql-api/workers-binding/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/sql-api/workers-binding/og.png?v=84705ed1b99f3db3","dateModified":"2026-10-02","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Integrate Cloudflare analytics with third-party platforms.
title: Analytics integrations
image: https://developers.cloudflare.com/analytics/analytics-integrations/og.png?v=0e04ea4251834627
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Analytics integrations

Last updated Oct 2, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/analytics-integrations/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

Cloudflare Enterprise customers can use Cloudflare integrations with their preferred analytics provider and configure ready-to-use Cloudflare Dashboards. Most analytics integrations are built on Cloudflare Logs by using Logpush with either Amazon S3 bucket or GCP Storage bucket.

Analyze [Cloudflare Logs](https://developers.cloudflare.com/logs/) data with the following analytics platforms:

- [Datadog](https://developers.cloudflare.com/analytics/analytics-integrations/datadog/)
- [Prometheus](https://developers.cloudflare.com/analytics/analytics-integrations/prometheus/)
- [Graylog](https://developers.cloudflare.com/analytics/analytics-integrations/graylog/)
- [New Relic](https://developers.cloudflare.com/analytics/analytics-integrations/new-relic/)
- [Splunk](https://developers.cloudflare.com/analytics/analytics-integrations/splunk/)
- [Sentinel](https://developers.cloudflare.com/analytics/analytics-integrations/sentinel/)

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"WebPage","@id":"https://developers.cloudflare.com/analytics/analytics-integrations/#page","headline":"Analytics integrations","description":"Integrate Cloudflare analytics with third-party platforms.","url":"https://developers.cloudflare.com/analytics/analytics-integrations/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/analytics-integrations/og.png?v=0e04ea4251834627","dateModified":"2026-10-02","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: This tutorial explains how to analyze Cloudflare metrics using the Cloudflare Integration tile for Datadog
title: Datadog
image: https://developers.cloudflare.com/analytics/analytics-integrations/datadog/og.png?v=5328cc21194b361a
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Datadog

Last updated May 5, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/analytics-integrations/datadog/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

This tutorial explains how to analyze Cloudflare metrics using the [Cloudflare Integration tile for Datadog ↗︎](https://docs.datadoghq.com/integrations/cloudflare/).

## Overview

Before viewing the Cloudflare dashboard in Datadog, note that this integration:

- Is available to all Cloudflare customer plans (Free, Pro, Business and Enterprise)
- Is based on the Cloudflare Analytics API
- Provides Cloudflare web traffic and DNS metrics only
- Does not feature data coming from request logs stored in Cloudflare Logs

## Task 1 - Install the Cloudflare App

To install the Cloudflare App for Datadog:

1. Log in to **Datadog**.
2. Click the **Integrations** tab.
3. In the **search box**, start typing *Cloudflare*. The app tile should appear below the search box. ![Searching for Cloudflare App in the Datadog Integrations tab](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=1210,height=738,format=webp/_astro/datadog-integrations.BJs60jr6.png)
4. Click the **Cloudflare** tile to begin the installation.
5. Next, click **Configuration** and then complete the following:
   - **Account name**: (Optional) This can be any value. It has not impact on the site data pulled from Cloudflare.
   - **Email**: This value helps keep your account safe. We recommend creating a dedicated Cloudflare user for analytics with the [*Analytics* role](https://developers.cloudflare.com/fundamentals/manage-members/roles/) (read-only). Note that the *Analytics* role is available to Enterprise customers only.
   - **API Key**: Enter your Cloudflare Global API key. For details refer to [API Keys](https://developers.cloudflare.com/fundamentals/api/get-started/keys/).
6. Click **Install Integration**. ![Configuring and installing the Datadog integration](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=1324,height=656,format=webp/_astro/cloudflare-tile-datadog-fill-details.Bd14uPIs.png)

The Cloudflare App for Datadog should be installed now and you can view the dashboard.

## Task 2 - View the dashboard

By default, the dashboard displays metrics for all sites in your Cloudflare account. Use the dashboard filters see metrics for a specific domain.

The dashboard displays the following metrics:

- **Threats** (threats by type, threats by country)
- **Requests** (total requests, cached requests, uncached requests, top countries by request, requests by IP class, top content types)
- **Bandwidth** (total bandwidth, encrypted and unencrypted traffic cached bandwidth, uncached bandwidth)
- **Caching** (Cache hit rate, request caching rate over time)
- **HTTP response status errors**
- **Page views**
- **Search Engine Bot Traffic**
- **DNS** (DNS queries, response time, top hostnames, queries by type, stale vs. uncached queries)

![Dashboard displaying metrics for a site on a Cloudflare account](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=3476,height=1732,format=webp/_astro/cloudflare-dashboard-datadog.BETjd10H.png)

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/analytics-integrations/datadog/#page","headline":"Datadog","description":"This tutorial explains how to analyze Cloudflare metrics using the Cloudflare Integration tile for Datadog","url":"https://developers.cloudflare.com/analytics/analytics-integrations/datadog/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/analytics-integrations/datadog/og.png?v=5328cc21194b361a","dateModified":"2026-05-05","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: This tutorial explains how to analyze Cloudflare Logs using Graylog. The Graylog integration is available on GitHub.
title: Graylog
image: https://developers.cloudflare.com/analytics/analytics-integrations/graylog/og.png?v=51979eec4128c70b
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Graylog

Last updated May 5, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/analytics-integrations/graylog/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

This tutorial explains how to analyze [Cloudflare Logs ↗︎](https://www.cloudflare.com/products/cloudflare-logs/) using [Graylog ↗︎](https://github.com/Graylog2/graylog-s3-lambda/blob/master/content-packs/cloudflare/cloudflare-logpush-content-pack.json).

## Overview

If you haven't used Cloudflare Logs before, visit our [Logs documentation](https://developers.cloudflare.com/logs/) for more details. Contact your Cloudflare Customer Account Team to enable logs for your account.

### Prerequisites

Before sending your Cloudflare log data to Graylog, make sure that you:

- Have an existing Graylog installation. Both single-node and cluster configurations are supported
- Have a Cloudflare Enterprise account with Cloudflare Logs enabled
- Configure [Logpush](https://developers.cloudflare.com/logs/logpush/)

Note

Cloudflare logs are HTTP/HTTPS request logs in JSON format and are gathered from our 200+ data centers globally. By default, timestamps are returned as UNIX nanosecond integers. All timestamp formats are supported by Graylog.

## Task 1 - Preparation

Before getting Cloudflare logs into Graylog:

1. Configure Cloudflare [Logpush](https://developers.cloudflare.com/logs/logpush/) to push logs with all desired fields to an AWS S3 bucket of your choice.
2. Download the latest [Graylog Integration for Cloudflare ↗︎](https://github.com/Graylog2/graylog-s3-lambda/blob/master/content-packs/cloudflare/cloudflare-logpush-content-pack.json).
3. Decompress the zip file.

Once decompressed, the integration package includes:

- *graylog-s3-lambda.jar*
- *content-packs/cloudflare/cloudflare-logpush-content-pack.json*
- *content-packs/cloudflare/threat-lookup.csv*

## Task 2 - Create and configure the AWS Lambda Function

1. Navigate to the Lambda service page in the AWS web console.
2. Create a new Lambda function and specify a *function name* of your choice and the *Java-8 runtime*.
3. Create or specify an execution role with the following permissions. You can also further restrict the resource permissions as desired for your specific set-up.

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "Policy",
      "Effect": "Allow",
      "Action": [
        "logs:CreateLogGroup"
        "s3:GetObject",
        "logs:CreateLogStream",
        "logs:PutLogEvents"
      ],
      "Resource": [
        "arn:aws:logs:your-region:your-account-number:*",
        "arn:aws:s3:your-region::cloudflare-bucket-name/*"
      ]
    }
  ]
}
```

**Note:** If your Graylog cluster is running in a VPC, you may need to add the *AWSLambdaVPCAccessExecutionRole* managed role to allow the Lambda function to route traffic to the VPC.

4. Once you've created the Lambda function, upload the function code ***graylog-s3-lambda.jar*** downloaded in [Task 1](#task-1---preparation).  Specify the following method for the Handler: *org.graylog.integrations.s3.GraylogS3Function::handleRequest*.
5. Specify at least the following required environment variables to configure the Lambda function for your Graylog cluster:
   - **CONTENT\_TYPE** (required) - *application/x.cloudflare.log* value to indicate that the Lambda function will process Cloudflare logs.
   - **COMPRESSION\_TYPE** ***(required*** **)** - *gzip* since Cloudflare logs are gzip compressed.
   - **GRAYLOG\_HOST** *(required)* - hostname or IP address of the Graylog host or cluster load balancer.
   - **GRAYLOG\_PORT** *(optional - defaults to 12201)* - The Graylog service port.
   - **CONNECT\_TIMEOUT** *(optional - defaults to 10000)* - The number of milliseconds to wait for the connection to be established.
   - **LOG\_LEVEL** *(optional - defaults to INFO)* - The level of detail to include in the CloudWatch logs generated from the Lambda function. Supported values are *OFF*, *ERROR*, *WARN*, *INFO*, *DEBUG*, *TRACE*, and *ALL*. Increase the logging level to help with troubleshooting. See [Defining Custom Log Levels in Code ↗︎](https://logging.apache.org/log4j/2.0/manual/customloglevels.html) for more information.
   - **CLOUDFLARE\_LOGPUSH\_MESSAGE\_FIELDS** *(optional - defaults to all)* - The fields to parse from the message. Specify as a comma-separated list of field names.
   - **CLOUDFLARE\_LOGPUSH\_MESSAGE\_SUMMARY\_FIELDS** *(optional - defaults to ClientRequestHost, ClientRequestPath, OriginIP, ClientSrcPort, EdgeServerIP, EdgeResponseBytes)* - The fields to include in the message summary that appears above the parsed fields at the top of each message in Graylog. Specify as a comma-separated list of field names. ![List of required Graylog environment variables](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=1048,height=287,format=webp/_astro/graylog-environment-variables.Db3fSAfE.png)

     **Note:** More configuration variables are available to fine-tune the function configuration in the Graylog Lambda S3 [README ↗︎](https://github.com/Graylog2/graylog-s3-lambda/blob/master/README.md#step-2-specify-configuration) file.
6. Create an AWS S3 Trigger for the Lambda function so that the function can process each Cloudflare log field that is written. Specify the same S3 bucket from [Task 1](#task-1---preparation) and choose the *All object create events* option. Any other desired file filters can be applied here. ![Add trigger dialog with an example AWS S3 Trigger](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=602,height=469,format=webp/_astro/aws-s3-add-trigger.CKwYBqmZ.png)
7. If your Graylog cluster is located within a VPC, you will need to [configure your Lambda function to access resources in a VPC ↗︎](https://docs.aws.amazon.com/lambda/latest/dg/configuration-vpc.html). You may also need to create a [VPC endpoint for the AWS S3 service ↗︎](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-endpoints.html#create-vpc-endpoint). This allows the Lambda function to access S3 directly when running in a VPC.

Note

By default, all log messages are sent over TCPt. TLS encryption between the Lambda function and Graylog is not currently supported. We recommend taking appropriate measures to secure the log messages in transit, such as placing the Lambda function within a secure VPC subnet where the Graylog node or cluster is running.

## Task 3 - Import the content pack in Graylog

Importing the Cloudflare Logpush content pack into Graylog loads the necessary configuration to receive Cloudflare logs and installs the Cloudflare dashboards.

The following components install with the content pack:

- Cloudflare dashboards ([Task 4](#task-4---view-the-cloudflare-dashboards)).
- A Cloudflare GELF (TCP) input that allows Graylog to receive Cloudflare logs.
- A Cloudflare message [stream ↗︎](https://docs.graylog.org/en/3.1/pages/streams.html).
- [Pipeline ↗︎](https://docs.graylog.org/en/3.1/pages/pipelines/pipelines.html) rules that help to process and parse Cloudflare log fields.

To import the content pack:

1. Locate the *cloudflare-logpush-content-pack.json* file that you downloaded and extracted in [Task 1](#task-1---preparation).
2. In Graylog, go to **System** > **Content Packs** and click **Upload** in the top right. Once uploaded, the Cloudflare Logpush content pack will appear in the list of uploaded content packs. ![Uploading Graylog content packs](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=1179,height=198,format=webp/_astro/graylog-content-packs.D1kZ2lWL.png)
3. Click **Install**. ![Installing Graylog content packs](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=1177,height=278,format=webp/_astro/graylog-content-packs-uploaded.DEaypq4Q.png)
4. In the **Install** dialog, enter an optional install comment, and verify that the correct values are entered for all configuration parameters.
   - A path is required for the MaxMind™️ database, available at [https://dev.maxmind.com/geoip/ ↗︎](https://dev.maxmind.com/geoip/).
   - A path is also required for the *Threat Lookup* CSV file, extracted in [Task 1](#task-1---preparation).![Adding an install comment and configuring parameters in Install Dialog screen](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=910,height=602,format=webp/_astro/graylog-content-pack-install.B5_Hmivu.png)
5. Once installed, your Graylog cluster will be ready to receive Cloudflare logs from the Lambda function.

Refer to the Graylog Lambda S3 [README ↗︎](https://github.com/Graylog2/graylog-s3-lambda/blob/master/README.md) for additional information and troubleshooting tips.

## Task 4 - View the Cloudflare Dashboards

You can view your dashboard in the [Graylog Cloudflare integration page ↗︎](https://go.graylog.com/cloudflare). The dashboards include:

### Cloudflare - Snapshot

This is an at-a-glance overview of the most important metrics from your websites and applications on the Cloudflare network. You can use dashboard filters to further slice and dice the information for granular analysis of events and trends.

Use this dashboard to:

- Monitor the most important web traffic metrics of your websites and applications on the Cloudflare network
- View which countries and IPs your traffic is coming from, and analyze the breakdown between mobile and desktop traffic, protocol, methods, and content types

![Visualizing Cloudflare log metrics in the Graylog dashboard](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=1278,height=946,format=webp/_astro/snapshot-cloudflare-dashboard-graylog.CRVPLE-B.png)

### Cloudflare - Security

This overview provides insights into threats to your websites and applications, including number of threats stopped,threats over time, top threat countries, and more.

Use this dashboard to:

- Monitor the most important security and threat metrics for your websites and applications
- Fine-tune and configure your IP firewall

![Visualizing an analysis of Cloudflare threat traffic in the Graylog dashboard](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=1278,height=897,format=webp/_astro/security-cloudflare-dashboard-graylog.Bm8-7dyC.png)

### Cloudflare - Performance

This dashboard helps to identify and address performance issues and caching misconfigurations. Metrics include total vs. cached bandwidth, saved bandwidth, total requests, cache ratio, top uncached requests, and more.

Use this dashboard to:

- Monitor caching behavior and identify misconfigurations
- Improve configuration and caching ratio

![Visualizing Cloudflare Performance metrics in the Graylog dashboard](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=1278,height=897,format=webp/_astro/performance-cloudflare-dashboard-graylog.BJk_tceI.png)

### Cloudflare - Reliability

This dashboard provides insights on the availability of your websites and applications. Metrics include origin response error ratio, origin response status over time, percentage of 3xx/4xx/5xx errors over time, and more.

Use this dashboard to:

- Investigate errors on your websites and applications by viewing edge and origin response status codes
- Further analyze errors based on status codes by countries, client IPs, hostnames, and other metrics

![Graylog dashboard Cloudflare Reliability](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=1278,height=897,format=webp/_astro/reliability-cloudflare-dashboard-graylog.9KgmAZJm.png)

### Cloudflare - Bots

Use this dashboard to detect and mitigate bad bots so that you can prevent credential stuffing, spam registration, content scraping, click fraud, inventory hoarding, and other malicious activities.

Note

To get bot requests identified correctly, use only one WAF custom rule (or firewall rule), configured with the action *Interactive Challenge*. To learn more about custom rules, refer to the [WAF documentation](https://developers.cloudflare.com/waf/custom-rules/).

Use this dashboard to:

- Investigate bot activity on your website and prevent content scraping, checkout fraud, spam registration, and other malicious activities.
- Use insight to tune Cloudflare to prevent bots from excessive usage and abuse across websites, applications, and API endpoints.

![Graylog dashboard Cloudflare Bot Management](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=1278,height=897,format=webp/_astro/bot-management-cloudflare-dashboard-graylog.DUQmn7po.png)

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/analytics-integrations/graylog/#page","headline":"Graylog","description":"This tutorial explains how to analyze Cloudflare Logs using Graylog. The Graylog integration is available on GitHub.","url":"https://developers.cloudflare.com/analytics/analytics-integrations/graylog/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/analytics-integrations/graylog/og.png?v=51979eec4128c70b","dateModified":"2026-05-05","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: This tutorial explains how to analyze Cloudflare metrics using the New Relic One Cloudflare Quickstart.
title: New Relic
image: https://developers.cloudflare.com/analytics/analytics-integrations/new-relic/og.png?v=e5e487cc8fdc9547
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# New Relic

Last updated May 5, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/analytics-integrations/new-relic/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

This tutorial explains how to analyze Cloudflare metrics using the [New Relic One Cloudflare Quickstart ↗︎](https://newrelic.com/instant-observability/cloudflare/fc2bb0ac-6622-43c6-8c1f-6a4c26ab5434).

## Prerequisites

Before sending your Cloudflare log data to New Relic, make sure that you:

- Have a Cloudflare Enterprise account with Cloudflare Logs enabled.
- Have a New Relic account.
- Configure [Logpush to New Relic](https://developers.cloudflare.com/logs/logpush/logpush-job/enable-destinations/new-relic/).

## Task 1 - Install the Cloudflare Network Logs quickstart

1. Log in to New Relic.
2. Click the Instant Observability button (top right).
3. Search for **Cloudflare Network Logs**.

![Cloudflare Network Logs install screen](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=1999,height=1030,format=webp/_astro/cloudflare-network-logs.CYJYSb1Z.png)

4. Click **Install this quickstart**.
5. Follow the steps to deploy.

## Task 2 - View the Cloudflare Dashboards

You can view your dashboards on the New Relic dashboard page. The dashboards include the following information:

### Overview

Get a quick overview of the most important metrics from your websites and applications on the Cloudflare network.

![Cloudflare Network Logs install screen](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=1407,height=817,format=webp/_astro/dash-1.CTd2mveX.png)

### Security

Get insights on threats to your websites and applications, including number of threats taken action on by the Web Application Firewall (WAF), threats over time, top threat countries, and more.

![Cloudflare Network security metrics screen](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=1402,height=511,format=webp/_astro/dash-2.DpiyWwxC.png)

### Performance

Identify and address performance issues and caching misconfigurations. Metrics include total requests, total versus cached requests, total versus origin requests.

![Cloudflare Network Logs performance metrics screen](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=1400,height=609,format=webp/_astro/dash-3.DMdRroU0.png)

### Reliability

Get insights on the availability of your websites and Applications. Metrics include, edge response status over time, percentage of `3xx`/`4xx`/`5xx` errors over time, and more.

![Cloudflare Network Logs reliability metrics screen](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=929,height=510,format=webp/_astro/dash-4.BIqk6bUl.png)

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/analytics-integrations/new-relic/#page","headline":"New Relic","description":"This tutorial explains how to analyze Cloudflare metrics using the New Relic One Cloudflare Quickstart.","url":"https://developers.cloudflare.com/analytics/analytics-integrations/new-relic/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/analytics-integrations/new-relic/og.png?v=e5e487cc8fdc9547","dateModified":"2026-05-05","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: This tutorial explains how to export Cloudflare metrics to Prometheus using the Cloudflare Prometheus Exporter.
title: Prometheus
image: https://developers.cloudflare.com/analytics/analytics-integrations/prometheus/og.png?v=002be16aea0979ff
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Prometheus

Last updated May 5, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/analytics-integrations/prometheus/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

This tutorial explains how to export Cloudflare metrics to [Prometheus ↗︎](https://prometheus.io/) using the [Cloudflare Prometheus Exporter ↗︎](https://github.com/cloudflare/cloudflare-prometheus-exporter), an open-source tool built on Cloudflare Workers with Durable Objects.

## Overview

Before setting up the Cloudflare Prometheus Exporter, note that this integration:

- Is available to all Cloudflare customer plans (Free, Pro, Business, and Enterprise). Zones on the Free plan have limited metrics availability.
- Is based on the Cloudflare GraphQL Analytics API and REST API.
- Exports 90+ Prometheus metrics covering requests, bandwidth, threats, Workers, load balancers, SSL certificates, firewall events, health checks, Magic Transit, Stream, and more.
- Runs as a Cloudflare Worker with Durable Objects for stateful counter accumulation and background refresh.
- Supports multi-account setups, automatically discovering all accessible accounts and zones.

## Prerequisites

Before deploying the exporter, make sure that you:

- Have a Cloudflare account.
- Have a [Cloudflare API token](https://developers.cloudflare.com/fundamentals/api/get-started/create-token/) with the required permissions (see [Create an API token](#task-2---create-an-api-token) below).
- Have a Prometheus instance to scrape the exporter.

## Task 1 - Deploy the exporter

You can deploy the exporter using one-click deploy or manually.

### One-click deploy

Select the button below to deploy the exporter to your Cloudflare Workers account:

[![Deploy to Cloudflare Workers](https://deploy.workers.cloudflare.com/button)](https://deploy.workers.cloudflare.com/?url=https://github.com/cloudflare/cloudflare-prometheus-exporter)

After deployment, configure `CLOUDFLARE_API_TOKEN` as a secret. Optionally configure `BASIC_AUTH_USER` and `BASIC_AUTH_PASSWORD` to protect the exporter with HTTP Basic Auth.

### Manual deployment

```bash
git clone https://github.com/cloudflare/cloudflare-prometheus-exporter.git
cd cloudflare-prometheus-exporter
bun install
wrangler secret put CLOUDFLARE_API_TOKEN
bun run deploy
```

## Task 2 - Create an API token

Create a Cloudflare API token with the following permissions:

[Create token with pre-filled permissions ↗︎](https://dash.cloudflare.com/profile/api-tokens?permissionGroupKeys=%5B%7B%22key%22%3A%22analytics%22%2C%22type%22%3A%22read%22%7D%2C%7B%22key%22%3A%22account_analytics%22%2C%22type%22%3A%22read%22%7D%2C%7B%22key%22%3A%22workers_scripts%22%2C%22type%22%3A%22read%22%7D%2C%7B%22key%22%3A%22ssl_and_certificates%22%2C%22type%22%3A%22read%22%7D%2C%7B%22key%22%3A%22firewall_services%22%2C%22type%22%3A%22read%22%7D%2C%7B%22key%22%3A%22load_balancers%22%2C%22type%22%3A%22read%22%7D%2C%7B%22key%22%3A%22account_logs%22%2C%22type%22%3A%22read%22%7D%2C%7B%22key%22%3A%22magic_transit%22%2C%22type%22%3A%22read%22%7D%5D&name=Cloudflare%20Prometheus%20Exporter)

| Permission | Access | Required |
| --- | --- | --- |
| Zone > Analytics | Read | Yes |
| Account > Account Analytics | Read | Yes |
| Account > Workers Scripts | Read | Yes |
| Zone > SSL and Certificates | Read | Optional |
| Zone > Firewall Services | Read | Optional |
| Zone > Load Balancers | Read | Optional |
| Account > Logs | Read | Optional |
| Account > Magic Transit | Read | Optional |

## Task 3 - Configure Prometheus

Add the exporter as a scrape target in your Prometheus configuration:

```yaml
scrape_configs:
  - job_name: 'cloudflare'
    scrape_interval: 60s
    scrape_timeout: 30s
    static_configs:
      - targets: ['your-worker.your-subdomain.workers.dev']
```

### With Basic Auth

If you configured Basic Auth on the exporter, update your Prometheus configuration:

```yaml
scrape_configs:
  - job_name: 'cloudflare'
    scrape_interval: 60s
    scrape_timeout: 30s
    basic_auth:
      username: 'your-username'
      password: 'your-password'
    static_configs:
      - targets: ['your-worker.your-subdomain.workers.dev']
```

## Configuration

Configuration is resolved in order: **KV overrides** > **environment variables** > **defaults**. You can use the runtime config API for dynamic changes without redeployment.

Set environment variables in `wrangler.jsonc` or via `wrangler secret put`:

| Variable | Default | Description |
| --- | --- | --- |
| `CLOUDFLARE_API_TOKEN` | - | Cloudflare API token (secret) |
| `SCRAPE_DELAY_SECONDS` | `300` | Delay before fetching metrics (data propagation) |
| `TIME_WINDOW_SECONDS` | `60` | Query time window |
| `METRIC_REFRESH_INTERVAL_SECONDS` | `60` | Background refresh interval |
| `CF_ACCOUNTS` | - | Comma-separated account IDs to include (default: all) |
| `CF_ZONES` | - | Comma-separated zone IDs to include (default: all) |
| `METRICS_DENYLIST` | - | Comma-separated list of metrics to exclude |
| `EXCLUDE_HOST` | `false` | Exclude host labels from metrics |
| `METRICS_PATH` | `/metrics` | Custom path for metrics endpoint |
| `BASIC_AUTH_USER` | - | Username for Basic Auth (secret) |
| `BASIC_AUTH_PASSWORD` | - | Password for Basic Auth (secret) |

For a full list of configuration options, refer to the [exporter README ↗︎](https://github.com/cloudflare/cloudflare-prometheus-exporter#configuration).

## Endpoints

| Path | Method | Description |
| --- | --- | --- |
| `/` | GET | Landing page |
| `/metrics` | GET | Prometheus metrics |
| `/health` | GET | Health check |
| `/config` | GET | Get all runtime config |
| `/config/:key` | PUT | Set a config override (persisted in KV) |
| `/config/:key` | DELETE | Reset a config key to its default |

## Available metrics

The exporter provides 90+ metrics across the following categories:

- **Zone requests** - Total requests, cached requests, requests by status code, country, content type, HTTP version, and more.
- **Zone bandwidth** - Total bandwidth, cached bandwidth, bandwidth by content type and country.
- **Zone threats** - Threat counts by country and type.
- **Firewall** - Firewall events by action, source, and rule. Bot detection metrics.
- **Workers** - Request counts, error counts, CPU time, and duration by script.
- **Load balancers** - Pool health status, request counts, RTT, steering policy, and origin weights.
- **Health checks** - Health check events, RTT, TTFB, TCP connection time, and TLS handshake time.
- **SSL certificates** - Certificate validation status by type and issuer.
- **Cache** - Cache hit ratio and cache miss origin duration.
- **Error rates** - 4xx/5xx error counts, edge and origin error rates, origin response duration.
- **Logpush** - Failed job counts at account and zone level.
- **Magic Transit** - Tunnel health, SLO status, and per-tunnel traffic (bits and packets).
- **Magic Firewall** - Per-rule sampled traffic (bits and packets).
- **Network Analytics** - Traffic volume across Magic Transit, DDoS defense, IDPS, TCP protection, and DNS protection.
- **Stream** - Video playback counts, time viewed, live input metrics.
- **Hostname metrics** - Per-hostname request counts, latency averages, and percentiles (requires `HOST_METRICS_ALLOWLIST`).

For a complete list of metrics with types and labels, refer to the [exporter README ↗︎](https://github.com/cloudflare/cloudflare-prometheus-exporter#available-metrics).

## Free tier zone limitations

Zones on Cloudflare's Free plan do not have access to the GraphQL Analytics API. The exporter automatically detects and skips free tier zones for metrics that require this API.

Free tier zones still export:

- `cloudflare_zone_certificate_validation_status` (SSL certificates)
- `cloudflare_zone_lb_origin_weight` (Load balancer weights, if configured)

You can monitor skipped zones with the `cloudflare_zones_skipped_free_tier` metric.

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/analytics-integrations/prometheus/#page","headline":"Prometheus","description":"This tutorial explains how to export Cloudflare metrics to Prometheus using the Cloudflare Prometheus Exporter.","url":"https://developers.cloudflare.com/analytics/analytics-integrations/prometheus/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/analytics-integrations/prometheus/og.png?v=002be16aea0979ff","dateModified":"2026-05-05","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Ingest Cloudflare logs into Microsoft Sentinel.
title: Sentinel
image: https://developers.cloudflare.com/analytics/analytics-integrations/sentinel/og.png?v=dfafeceeae956e41
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Sentinel

Last updated Oct 12, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/analytics-integrations/sentinel/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

Cloudflare has integrations with Microsoft Sentinel to make analyzing your Cloudflare data easier and in a centralized space. Cloudflare has two versions of this connector available. We recommend utilizing the latest Codeless Connector integration as it provides easier setup, cost management, and integrates with [Sentinel Data Lake ↗︎](https://learn.microsoft.com/en-us/azure/sentinel/datalake/sentinel-lake-overview).

**[Sentinel CCF Solution ↗︎](https://marketplace.microsoft.com/en-us/product/azure-application/cloudflare.azure-sentinel-solution-cloudflare-ccf?tab=Overview)** (recommended): The Codeless Connector Framework (CCF) provides partners, advanced users, and developers the ability to create custom connectors for ingesting data to Microsoft Sentinel.

**[Sentinel Function Based Connector ↗︎](https://azuremarketplace.microsoft.com/en-us/marketplace/apps/cloudflare.cloudflare_sentinel?tab=Overview)**: The Cloudflare connector for Microsoft Sentinel uses [Azure Functions ↗︎](https://azure.microsoft.com/en-us/products/functions) to process security logs from Cloudflare's Logpush service and ingest them directly into the SIEM platform.

Legacy connector deprecation

Microsoft is deprecating the Azure Monitor HTTP Data Collector API. As a result, Cloudflare will no longer maintain the Azure Functions-based Microsoft Sentinel connector after the API end-of-support date. Cloudflare Enterprise customers using the Function-based connector must migrate to the CCF connector documented in this guide. Refer to the [deprecation changelog entry](https://developers.cloudflare.com/changelog/post/2026-08-26-sentinel-functions-connector-deprecation/) for the exact end-of-support date and migration details.

This guide provides clear, step-by-step instructions for integrating Cloudflare logs with the CCF connector for Microsoft Sentinel using Azure Blob Storage. By following these steps, you will be able to securely collect, store, and analyze your Cloudflare logs within Microsoft Sentinel, enhancing your organization's security monitoring and incident response capabilities.

## Step 1: Prerequisites

Before you begin, make sure the following prerequisites are met.

### Azure resources

- **Azure subscription** with permission to create and manage resources ( `Contributor` or `Owner` role recommended).
- **Azure Storage account** with [Azure Data Lake Storage Gen2 enabled ↗︎](https://learn.microsoft.com/en-us/azure/storage/blobs/create-data-lake-storage-account) (hierarchical namespace on). Although the generic Logpush Azure destination supports standard Blob Storage, the CCF connector requires hierarchical namespace. Logpush writes the Cloudflare log files to this account.
- **Azure Blob container** inside the storage account, dedicated to receiving Cloudflare Logpush files. The CCF connector monitors this container for new files via Event Grid.
- **Microsoft Sentinel workspace** already deployed on top of a Log Analytics workspace. The connector's Data Collection Rule (DCR) and Data Collection Endpoint (DCE) are tied to this Log Analytics workspace, and all ingested Cloudflare log records land in tables within it.
- **Cloudflare account** with access to the domain or account whose logs you want to export, and permission to configure Logpush jobs.

### RBAC roles

The CCF connector authenticates to Azure using a service principal that belongs to the Cloudflare CCF connector application, registered as a multi-tenant Microsoft Entra application. The ARM template that deploys the connector assigns the required roles to this service principal automatically.

The deploying user must have **Microsoft Sentinel Contributor**, `Contributor`, or `Owner` on the Microsoft Sentinel workspace to deploy the connector resources. Because the ARM template creates role assignments for the service principal, the user must also have `Owner` or `User Access Administrator` at the storage account scope. `Contributor` and **Microsoft Sentinel Contributor** alone cannot create role assignments.

At deployment time, the Cloudflare CCF connector service principal receives `Storage Blob Data Reader` on the storage account to read log files from the Blob container and `Storage Queue Data Contributor` to read and delete pointer messages from the Storage Queue.

Refer to the Microsoft documentation on [Azure roles for Microsoft Sentinel ↗︎](https://learn.microsoft.com/en-us/azure/sentinel/roles) and [Azure roles for storage ↗︎](https://learn.microsoft.com/en-us/azure/storage/blobs/assign-azure-role-data-access) for details.

### Event Grid resource provider

The `Microsoft.EventGrid` resource provider must be registered in the subscription that hosts the storage account. Verify the registration state in the Azure portal under **Subscriptions** > select the subscription > **Settings** > **Resource providers** > search for `Microsoft.EventGrid`.

Alternatively, run the following Azure CLI commands:

```sh
az provider register --namespace Microsoft.EventGrid --subscription <subscription-id>
az provider show --namespace Microsoft.EventGrid --subscription <subscription-id> --query "registrationState"
```

The registration state should report `Registered` before you continue.

### Network access configuration

By default, the storage account must allow public network access so that the connector's managed resources can reach both the Blob container endpoint and the Storage Queue endpoint.

- If you are not restricting access with a Network Security Perimeter (NSP), open the storage account's **Networking** blade and set **Public network access** to **Enabled from all networks**.
- Restricting access using selected virtual networks or IPv4 CIDR ranges is not supported for this connector, because of Azure Storage firewall limitations around IP ranges and caller region affinity.
- If network restrictions are required for compliance, use an [Azure Network Security Perimeter (NSP) ↗︎](https://learn.microsoft.com/en-us/azure/private-link/network-security-perimeter-concepts) instead. Include the Sentinel service tag inbound ranges in the NSP rules and configure the Event Grid system topic subscription to use system-assigned managed identity delivery.

Refer to Microsoft's guidance on [enabling storage network security for Sentinel ↗︎](https://learn.microsoft.com/en-us/azure/sentinel/enable-storage-network-security) for the full options.

### Storage account and Sentinel co-location

The Azure Blob Storage account and the Microsoft Sentinel workspace must live in the **same Azure subscription and the same resource group**. Deployments where these resources are split across subscriptions or resource groups fail during ARM template validation. Refer to [Troubleshooting](#troubleshooting) for details.

## Step 2: Set up a Logpush job

1. Log in to the [Cloudflare dashboard ↗︎](https://dash.cloudflare.com/), and select your account and domain.
2. Go to **Analytics** > **Logs** and select **Logpush**.
3. Select **Create Logpush Job**. Choose the log type you want to export (for example, **HTTP requests**).
4. For the destination, select **Azure Blob Storage**.
5. Enter your Azure Blob Storage details:
   - SAS Token (Shared Access Signature)

   To generate a SAS token from the Azure portal, first navigate to your storage account. Under the **Data Storage** section, select **Containers** and choose the relevant container. Within the settings, locate and select **Shared access signature**. Configure the required permissions, such as `write` and `create`, and specify the start and expiration dates for the token. Once configured, generate the SAS token accordingly.
6. Save and activate the Logpush job.

For complete details, refer to the [Cloudflare Logpush to Azure documentation](https://developers.cloudflare.com/logs/logpush/logpush-job/enable-destinations/azure/).

## Step 3: Install the Cloudflare CCF solution

1. Log in to the Azure portal and open your Microsoft Sentinel workspace. If you do not have one yet, follow Microsoft's [onboarding guide ↗︎](https://learn.microsoft.com/en-us/azure/sentinel/quickstart-onboard) to create a Log Analytics workspace and enable Microsoft Sentinel on it.
2. In the left navigation pane, under **Content management**, select **Content hub**. If the page appears empty, refresh and wait for the content list to load.
3. In the search bar, enter `Cloudflare` and press **Enter**.
4. Select the **Cloudflare CCF** solution and select **Install**.
5. After you install the solution, select **Manage**.
6. Select **Cloudflare (Using Blob Container) (via Codeless Connector Framework)** and select **Open connector page**.

![Azure portal](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=2172,height=1250,format=webp/_astro/azure-portal.DumVF0xP.png)

## Step 4: Configure the CCF connector

On the connector page, fill in the following fields:

- **Service Principal ID**: this field is prepopulated with the object ID of the Cloudflare CCF connector service principal in your tenant. If it is empty, ensure that admin consent has been granted for the Cloudflare CCF connector application in your Microsoft Entra tenant, then reload the page. Refer to Microsoft's [admin consent workflow ↗︎](https://learn.microsoft.com/en-us/entra/identity/enterprise-apps/configure-admin-consent-workflow) for details.
- **Blob Container URL**: in the Azure portal, open the storage account that receives Cloudflare logs. Under **Data storage** > **Containers**, open the target container, go to **Properties**, and copy the URL.
- **Storage Account Resource Group Name**, **Storage Account Location**, and **Storage Account Subscription ID**: available on the storage account's **Overview** page.
- **Event Grid System Topic Name**: leave this field blank on the first deployment. The ARM template creates the topic automatically. If you are reconfiguring an existing deployment, open **Event Grid** > **System topics** in the Azure portal, filter by location, and copy the name of the topic whose **Source** matches your storage account.

Select **Connect** to start the deployment. When the deployment completes, the Azure portal shows a `Deployment succeeded` notification and the button changes to **Disconnect**.

![Configuration fields](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=1954,height=1132,format=webp/_astro/configuration.ypRscF1K.png)

## Step 5: Verify log ingestion

1. In the Azure portal, open the Log Analytics workspace backing your Sentinel instance.
2. In the left navigation pane, select **Logs**.
3. Enter the following query in the editor and select **Run**:

   ```kusto
   CloudflareV2_CL
   | take 10
   ```

4. Confirm that Cloudflare log records are returned.

Note

Data usually starts appearing in the workspace within 20 to 30 minutes of the connector reporting a successful deployment. If logs do not appear after that window, review your storage account permissions, Cloudflare Logpush configuration, Event Grid subscription, and Sentinel connector settings.

![Data connectors](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=1942,height=1236,format=webp/_astro/data-connectors.By58rEfp.png) ![Cloudflare traffic overview](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=2248,height=1286,format=webp/_astro/traffic-overview.C9qSRy0T.png)

## Troubleshooting

### `CreateDataFlowResources` deployment error

The ARM template deployment fails with an error similar to:

```txt
InvalidTemplate: Deployment template validation failed:
'The resource 'Microsoft.Resources/deployments/CreateDataFlowResources' is not defined in the template.'
```

The CCF connector's ARM template operates within a single resource group scope and cross-references the storage account, Blob container, Event Grid system topic, Storage Queue, Data Collection Rule (DCR), Data Collection Endpoint (DCE), and Microsoft Sentinel workspace as co-located resources. If any of those resources live outside the deployment scope, the template cannot resolve the references and validation fails before anything is created.

To resolve the error:

1. **Verify co-location**: in the Azure portal, open both the storage account and the Microsoft Sentinel workspace (or its underlying Log Analytics workspace) and confirm that **Resource group** and **Subscription** match on the **Overview** blade. If they differ, move the storage account into the resource group that hosts Sentinel, or create a new storage account in that resource group.
2. **Verify network access**: confirm that public network access is enabled on the storage account, or that a Network Security Perimeter is configured as described in [Prerequisites](#network-access-configuration). Selected network limits using IPv4 CIDR addresses are not supported.
3. **Retry the deployment**: after you align the resources, re-run the ARM template deployment. The `CreateDataFlowResources` error should not recur.

For the full list of storage-related failure modes and mitigations, refer to Microsoft's [Azure Storage Blob connector troubleshooting guide ↗︎](https://learn.microsoft.com/en-us/azure/sentinel/azure-storage-blob-connector-troubleshoot).

## Supported Logs

We support the following fields to be utilized within the Sentinel Connectors (CCF & Function based). You can push all log fields to Azure using our logpush function as described in [Enable Microsoft Azure](https://developers.cloudflare.com/logs/logpush/logpush-job/enable-destinations/azure/) documentation.

The CCF connector normalizes Cloudflare log fields to the [Microsoft Sentinel ASIM schema ↗︎](https://learn.microsoft.com/en-us/azure/sentinel/normalization) where a canonical equivalent exists (for example, `ClientIP` becomes `SrcIpAddr`, `EdgeResponseStatus` becomes `HttpStatusCode`), and preserves Cloudflare-native names for fields that do not have a schema equivalent. Use the field names in the following tables in your KQL queries against the connector's output table.

<details>

<summary>

Parser fields

</summary>

Application<br> BotScore<br> BotScoreSrc<br> CacheCacheStatus<br> CacheResponseBytes<br> CacheResponseStatus<br> CacheTieredFill<br> ClientASN<br> ClientASNDescription<br> ClientDeviceType<br> ClientIPClass<br> ClientMatchedIpFirewall<br> ClientRefererHost<br> ClientRefererPath<br> ClientRefererQuery<br> ClientRefererScheme<br> ClientRequestPath<br> ClientRequestProtocol<br> ClientRequestQuery<br> ClientRequestScheme<br> ClientRequestURI<br> ClientTcpRtt<br> ClientTlsClientHelloServerName<br> ClientTlsStatus<br> ClientXRequestedWith<br> ColoCode<br> ConnectTimestamp<br> Datetime<br> DisconnectTimestamp<br> DstBytes<br> DstIpAddr<br> DstPortNumber<br> DvcAction<br> EdgeColoCode<br> EdgeColoID<br> EdgeEndTimestamp<br> EdgePathingOp<br> EdgePathingSrc<br> EdgePathingStatus<br> EdgeRateLimitAction<br> EdgeRateLimitID<br> EdgeRequestHost<br> EdgeResponseCompressionRatio<br> EdgeResponseStatus<br> EdgeServerIP<br> EdgeStartTimestamp<br> EventResult<br> EventSubType<br> FirewallMatchesSources<br> HttpContentType<br> HttpReferrerOriginal<br> HttpRequestHeaderHost<br> HttpRequestMethod<br> HttpStatusCode<br> HttpUserAgentOriginal<br> IpFirewall<br> MatchIndex<br> NetworkProtocol<br> NetworkRuleName<br> OriginProto<br> OriginResponseBytes<br> OriginResponseHTTPExpires<br> OriginResponseHTTPLastModified<br> OriginResponseTime<br> OriginSSLProtocol<br> OriginTcpRtt<br> OriginTlsCipher<br> OriginTlsFingerprint<br> OriginTlsMode<br> OriginTlsProtocol<br> OriginTlsStatus<br> OriginatorRayID<br> ParentRayID<br> ProxyProtocol<br> RayID<br> SecurityLevel<br> SrcBytes<br> SrcGeoCountry<br> SrcIpAddr<br> SrcPortNumber<br> TimeGenerated<br> Timestamp<br> TlsCipher<br> TlsVersion<br> WAFAction<br> WAFFlags<br> WAFMatchedVar<br> WAFProfile<br> WAFRuleID<br> WAFRuleMessage<br> WorkerCPUTime<br> WorkerStatus<br> WorkerSubrequest<br> WorkerSubrequestCount<br> ZoneID<br>

</details>

<details>

<summary>

Workbook fields

</summary>

ClientDeviceType<br> SrcIpAddr<br> ClientIPClass<br> ClientRequestProtocol<br> ClientRequestReferer<br> ClientRequestURI<br> ClientRequestUserAgent<br> EdgePathingOp<br> EdgePathingSrc<br> EdgePathingStatus<br> EdgeResponseContentType<br> HttpRequestMethod<br> HttpStatusCode<br> TimeGenerated<br> threat<br>

</details>

<details>

<summary>

Analytic rules

</summary>

ClientIPClass<br> ClientRequestURI<br> DstBytes<br> HttpRequestMethod<br> HttpStatusCode<br> HttpUserAgentOriginal<br> SrcBytes<br> SrcGeoCountry<br> SrcIpAddr<br> TimeGenerated<br> WAFAction<br> WAFRuleID<br> WAFRuleMessage<br>

</details>

<details>

<summary>

Hunting queries

</summary>

ClientRequestURI<br> ClientTlsStatus<br> EdgeRequestHost<br> EdgeResponseStatus<br> HttpStatusCode<br> HttpUserAgentOriginal<br> NetworkRuleName<br> OriginTlsStatus<br> SrcGeoCountry<br> SrcIpAddr<br> TimeGenerated<br>

</details>

## Resources

[Download Cloudflare's CCF Sentinel Solution ↗︎](https://marketplace.microsoft.com/en-us/product/azure-application/cloudflare.azure-sentinel-solution-cloudflare-ccf?tab=Overview)  
[Microsoft Data Lake Overview ↗︎](https://learn.microsoft.com/en-us/azure/sentinel/datalake/sentinel-lake-overview)  
[About the CCF Platform ↗︎](https://learn.microsoft.com/en-us/azure/sentinel/create-codeless-connector)

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/analytics-integrations/sentinel/#page","headline":"Sentinel","description":"Ingest Cloudflare logs into Microsoft Sentinel.","url":"https://developers.cloudflare.com/analytics/analytics-integrations/sentinel/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/analytics-integrations/sentinel/og.png?v=dfafeceeae956e41","dateModified":"2026-10-12","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Resolve common issues when integrating Cloudflare with Microsoft Sentinel.
title: Troubleshooting
image: https://developers.cloudflare.com/analytics/analytics-integrations/sentinel/troubleshooting/og.png?v=a82f5705220ea820
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Troubleshooting

Last updated Sep 3, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/analytics-integrations/sentinel/troubleshooting/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

Use this guide to resolve common issues when integrating Cloudflare logs with [Microsoft Sentinel](https://developers.cloudflare.com/analytics/analytics-integrations/sentinel/) through the Codeless Connector Framework (CCF).

Support scope

Cloudflare Support can help troubleshoot [Cloudflare Logpush](https://developers.cloudflare.com/logs/logpush/) and the Cloudflare CCF connector. Support can validate deployment prerequisites and investigate known issues involving Azure Resource Manager (ARM) template deployment, service principals, Azure roles, storage network access, Data Collection Rules (DCRs), table schemas, and field mappings.

Cloudflare Support can guide you through these checks but cannot access or modify resources in your Azure environment. If the issue remains after validating the recommended setup and is isolated to Microsoft Azure or the Microsoft Sentinel CCF environment, contact Microsoft Support.

## Connector deployment fails with `InternalServerError (HTTP 500)`

**Cause:** The Microsoft-managed service principal required by the Cloudflare CCF connector has not been provisioned in your Microsoft Entra ID tenant. This typically happens when the **Grant tenant-wide admin consent** button on the connector configuration page cannot complete the OAuth redirect — for example, due to browser extensions, a cached session, a conflicting signed-in account, a Conditional Access policy, or an unmet Multi-Factor Authentication (MFA) challenge.

**Fix:**

1. Confirm that the `Microsoft.SecurityInsights` resource provider is registered on your subscription:

   ```sh
   az provider show --namespace Microsoft.SecurityInsights --query "{state:registrationState}"
   ```

   The output should return `"state": "Registered"`.
2. In an **InPrivate/Incognito** browser session, sign in as a user holding one of these Microsoft Entra roles: **Privileged Role Administrator**, **Cloud Application Administrator**, **AI Administrator**, or **Application Administrator**.
3. Open the direct tenant-wide admin consent URL for the Microsoft-managed application (App ID `4f05ce56-95b6-4612-9d98-a45c8cc33f9f`), replacing `{tenant-id}` with your Entra tenant ID:

   ```txt
   https://login.microsoftonline.com/{tenant-id}/adminconsent?client_id=4f05ce56-95b6-4612-9d98-a45c8cc33f9f
   ```

4. Complete the consent flow, including any MFA challenge.

**Verify:** Refresh the Cloudflare connector configuration page in Microsoft Sentinel. The **Service Principal ID** field should populate automatically, and the **Grant tenant-wide admin consent** button should no longer be displayed. Retry the connector deployment.

## Deployment fails with `InvalidTemplate` on `CreateDataFlowResources`

You see a deployment failure with an error similar to:

```txt
Deployment template validation failed: 'The resource
'Microsoft.Resources/deployments/CreateDataFlowResources'
is not defined in the template.'
```

**Cause:** The ARM template requires the Azure Blob Storage account and the Microsoft Sentinel workspace (and its underlying Log Analytics workspace) to reside in the **same Azure subscription and the same resource group**. When they are in different subscriptions or different resource groups, the nested `CreateDataFlowResources` sub-deployment cannot resolve the required resource references and validation fails.

A less common variant of this error occurs when the `Microsoft.EventGrid` resource provider is not registered in the target subscription.

**Fix:**

1. Confirm that both resources are co-located in the same Azure subscription and the same resource group. If they are not, redeploy or migrate them so they share both.
2. Register the required resource providers on the target subscription:

   ```sh
   az provider register --namespace Microsoft.SecurityInsights
   az provider register --namespace Microsoft.EventGrid
   ```

3. After deployment, confirm that the Microsoft-managed service principal holds these role assignments on the Storage account:
   - `Storage Blob Data Reader`
   - `Storage Queue Data Contributor`
4. Confirm that the Storage account's networking configuration allows the connector to access the Azure Storage Queue.

**Verify:** Redeploy the connector. The Deployments blade should show status **Succeeded**, and the connector should transition to **Connected**.

## Connector update fails with `Invalid output table schema`

You see a deployment failure with an error similar to:

```txt
Failed to create required resources for data connector.
Invalid output table schema: The following columns which exist
in the current schema do not exist in the new schema or have
different types.
```

**Cause:** An earlier version of the Cloudflare CCF connector created a `CloudflareV2_CL` table in your Log Analytics workspace. When you deploy a newer connector version, the ARM template attempts to update this table schema. Azure Monitor rejects the update if the new schema omits columns that exist in the current table, or changes an existing column to an incompatible datatype.

**Fix:** Update the existing table schema directly through the Azure Monitor REST API before redeploying the connector. Run the update from Azure Cloud Shell using an account that holds the `Log Analytics Contributor` role on the workspace.

1. Download the latest `CloudflareV2_CL.json` schema definition from the Cloudflare CCF connector solution package (available in the [Microsoft Sentinel Content Hub ↗︎](https://marketplace.microsoft.com/en-us/product/cloudflare.azure-sentinel-solution-cloudflare-ccf?tab=Overview)) and upload it to your Cloud Shell session.
2. Request an Azure Resource Manager access token:

   ```sh
   az account get-access-token --resource https://management.azure.com/
   ```

3. Apply the updated table schema, replacing the placeholders with your values:

   ```sh
   az rest --method PUT \
     --url "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<resource-group>/providers/Microsoft.OperationalInsights/workspaces/<workspace-name>/tables/CloudflareV2_CL?api-version=2025-07-01" \
     --headers "Authorization=Bearer <access-token>" "Content-Type=application/json" \
     --body @CloudflareV2_CL.json
   ```

**Verify:** The command returns the updated table definition as JSON. Redeploy the Cloudflare CCF connector — the deployment should complete without a schema validation error.

## Fields are missing or `null` in `CloudflareV2_CL`

**Cause:** The Data Collection Rule (DCR) schema is out of sync with the Cloudflare Logpush schema being delivered. Two variants are common:

- **Datatype mismatch:** A field is declared with the wrong Sentinel datatype in the DCR `streamDeclarations` — for example, a numeric field declared as `string`, or a variable-shape field such as `BotDetectionIDs` declared as anything other than `dynamic`. The record is ingested, but the mismatched column is populated with `null`.
- **Reserved column name conflict:** A Cloudflare field name collides with a [Microsoft Sentinel reserved column name ↗︎](https://learn.microsoft.com/azure/azure-monitor/logs/create-custom-table?tabs=azure-portal-1%2Cazure-portal-2%2Cazure-portal-3#add-or-delete-a-custom-column). For example, the Cloudflare Network Error Logging (NEL) dataset contains a `Type` field, but `Type` is reserved in Sentinel. Fields with reserved names cannot be stored under their original name.

**Fix:**

1. Upgrade the Cloudflare CCF solution to the latest version from the [Microsoft Sentinel Content Hub ↗︎](https://marketplace.microsoft.com/en-us/product/cloudflare.azure-sentinel-solution-cloudflare-ccf?tab=Overview). New releases progressively correct field datatypes shipped by the connector and add support for new Cloudflare Logpush fields.
2. If missing fields persist after upgrading — for example, because the DCR has been customized — apply a manual fix:
   - **For datatype mismatches:** Update the field's datatype in both the DCR `streamDeclarations` and the `CloudflareV2_CL` table definition to match the Cloudflare Logpush schema (for example, `real` for floating-point values such as `EdgeResponseCompressionRatio`, or `dynamic` for `BotDetectionIDs`).
   - **For reserved name conflicts:** Rename the field in the DCR `transformKql` transformation and add the renamed column to the `CloudflareV2_CL` table definition. For example, to preserve the NEL `Type` value:

     ```kusto
     source
     | extend NELType = Type
     | project-away Type
     ```

     Add a `NELType` column to `CloudflareV2_CL` with datatype `string`.

**Verify:** Send a fresh Logpush batch and query `CloudflareV2_CL` for the affected fields. Values should now be populated and no longer `null`.

Known unsupported fields

The `JSDetectionPassed` and `VerifiedBotCategory` fields are not currently ingested by the Cloudflare CCF connector, regardless of DCR or table configuration. Support for these fields requires changes to the connector implementation. This page will be updated when support is available.

## The Cloudflare CCF solution workbook does not populate

The Cloudflare workbook shipped with the CCF solution loads but shows no data, or its queries fail with an error indicating that the referenced table or connector does not exist.

**Cause:** In earlier releases, the workbook shipped with the Cloudflare CCF solution referenced the legacy `Cloudflare_CL` table and the legacy `CloudflareDataConnector`. The CCF connector ingests into `CloudflareV2_CL` through a parser, so workbook queries against the legacy table return no results even when logs are ingesting correctly.

**Fix:** Upgrade the Cloudflare CCF solution to a version whose workbook references the CCF connector's parser and the `CloudflareV2_CL` table. The latest solution release is available from the [Microsoft Sentinel Content Hub ↗︎](https://marketplace.microsoft.com/en-us/product/cloudflare.azure-sentinel-solution-cloudflare-ccf?tab=Overview).

**Verify:** Reopen the workbook. Panels should populate with recent Cloudflare log data.

## Still not resolved

If your issue is not covered here:

- Consult the [Cloudflare CCF solution page ↗︎](https://azuremarketplace.microsoft.com/marketplace/apps/cloudflare.azure-sentinel-solution-cloudflare-ccf) on the Azure Marketplace for the latest solution version and deployment prerequisites.
- Review the [Cloudflare Logs change notices](https://developers.cloudflare.com/logs/reference/change-notices/) for recent schema changes that may affect your DCR or table definitions.
- [Contact Cloudflare Support](https://developers.cloudflare.com/support/contacting-cloudflare-support/) for issues involving Cloudflare-side log delivery.
- Contact Microsoft Support for issues isolated to Microsoft Azure or the Microsoft Sentinel CCF environment.

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/analytics-integrations/sentinel/troubleshooting/#page","headline":"Troubleshooting","description":"Resolve common issues when integrating Cloudflare with Microsoft Sentinel.","url":"https://developers.cloudflare.com/analytics/analytics-integrations/sentinel/troubleshooting/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/analytics-integrations/sentinel/troubleshooting/og.png?v=a82f5705220ea820","dateModified":"2026-09-03","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: This tutorial explains how to analyze Cloudflare Logs using the Cloudflare App for Splunk.
title: Splunk
image: https://developers.cloudflare.com/analytics/analytics-integrations/splunk/og.png?v=7bfa5b3e4285a22b
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Splunk

Last updated Sep 1, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/analytics-integrations/splunk/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

This tutorial explains how to analyze [Cloudflare Logs ↗︎](https://www.cloudflare.com/products/cloudflare-logs/) using the [Cloudflare App for Splunk ↗︎](https://splunkbase.splunk.com/app/4501/).

## Prerequisites

Before sending your Cloudflare log data to Splunk, ensure that you:

- Have an existing Splunk Enterprise or Cloud account
- Have a Cloudflare Enterprise account
- Consult the [Splunk documentation ↗︎](https://splunkbase.splunk.com/app/4501/) for the Cloudflare App

## Task 1 - Install and Configure the Cloudflare App for Splunk

To install the [Cloudflare App for Splunk ↗︎](https://splunkbase.splunk.com/app/4501/):

1. Log in to your Splunk instance.
2. Under **Apps** > **Find More Apps**, search for *Cloudflare App for Splunk.*
3. Click **Install**.

![Splunk website with Apps menu expanded and Search \& Reporting menu item along with Cloudflare App for Splunk](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=2410,height=1174,format=webp/_astro/splunk-cloudflare-app-for-splunk.CSImDJTK.png)

4. Restart and reopen your Splunk instance.
5. Edit the `cloudflare:json` source type in the Cloudflare App for Splunk. To edit the source type:
   1. Click the **Settings** dropdown and select **Source types**.
   2. Uncheck **Show only popular** and search for *cloudflare*.
   3. Click **Edit** and change the Regex expression to `([\r\n]+)`.
   4. Save your edits.
6. Create an index on Splunk to store the HTTP Event logs. To create an index:
   1. Open the setup screen by clicking the **Settings** dropdown, then click **Indexes**.
   2. Select **New Index**. Note that the **Indexes** page also gives you the status of all your existing indexes so that you can see whether you're about to use up your licensed amount of space.
   3. Name the index **cloudflare**, which is the default index that the Cloudflare App will use.
   4. Set **Index Data Type** to **Events**, then select **Save**.
7. Set up the HTTP Event Collector (HEC) on Splunk. To create an HEC:
   1. Click the **Settings** dropdown and select **Data inputs**.
   2. Select **+Add new** next to **HTTP Event Collector** and follow the wizard. When prompted, submit the following responses:
      - Name: Cloudflare
      - Source Type: Select > `cloudflare:json`
      - App Context: Cloudflare App for Splunk (cloudflare)
      - Index: cloudflare
   3. At the end of the wizard you will see a **Token Value**. This token authorizes the Cloudflare Logpush job to send data to your Splunk instance. If you forget to copy it now, Splunk allows you to get the value at any time.

   Enable HEC and SSL

   After creating the token, go to **Settings** > **Data inputs** > **HTTP Event Collector** > **Global Settings** and confirm that **All Tokens** is turned on and that **Enable SSL** is selected, then select **Save**. Verify that the status of your new HEC token is enabled in the token list. Refer to the [Splunk HEC documentation ↗︎](https://docs.splunk.com/Documentation/Splunk/latest/Data/UsetheHTTPEventCollector) for details.
8. Verify whether Splunk is using a self-signed certificate. You'll need this information when creating the Logpush job.
9. Determine the endpoint to use to send the data to. The endpoint should be:

```sql
"<protocol>://input-<host>:<port>/<endpoint>" or "<protocol>://http-inputs-<host>:<port>/<endpoint>"
```

Where:

- `protocol`: HTTP or HTTPS
- `input`: `input` or `http-inputs` based on whether you have a self-service or managed cloud plan
- `host`: The hostname of your Splunk instance. The easiest way to determine the hostname is to look at the URL you went to when you logged in to Splunk.
- `port`: 443 or 8088
- `endpoint`: services/collector/raw

For example: `https://prd-p-0qk3h.splunkcloud.com:8088/services/collector/raw`. Refer to the [Splunk Documentation ↗︎](https://docs.splunk.com/Documentation/SplunkCloud/latest/Data/UsetheHTTPEventCollector) for more details and examples.

**Post Installation Notes**

You can change the **Index Name** after the initial configuration by clicking on the **Settings** dropdown and navigating to **Advanced search**. There you can select **Search macros** and look for the Cloudflare App for Splunk.

![Splunk interface highlighting Apps menu and Manage Apps option along with Enable Acceleration checkbox](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=2534,height=1104,format=webp/_astro/splunk-settings-advanced-search-search-macros.Bt1szjjM.png)

The Cloudflare App for Splunk comes with a custom Cloudflare Data Model that has an acceleration time frame of 1 day but is not accelerated by default. If you enable [Data Model acceleration ↗︎](https://docs.splunk.com/Documentation/Splunk/latest/Knowledge/Acceleratedatamodels), we recommend that the Data Model is only accelerated for 1 or 7 days to ensure there are no adverse effects within your Splunk environment.

Enable or disable acceleration after the initial configuration by accessing the app Set up page by clicking the **Apps** dropdown, then **Manage Apps** > **Cloudflare Set Up**.

![Splunk Advanced Search page highlighted Search macros and Advanced search](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=2522,height=1060,format=webp/_astro/splunk-apps-manage-apps-cloudflare-set-up-enable-data-model-acceleration.KQW0iwYr.png)

You can also manually configure Data Models by going to **Settings** > **Data models**. Learn more about data model acceleration in the [Splunk documentation ↗︎](https://docs.splunk.com/Documentation/Splunk/latest/Knowledge/Acceleratedatamodels).

## Task 2 - create the Cloudflare Logpush job to Splunk

Create the Logpush job by following [Enable Logpush to Splunk](https://developers.cloudflare.com/logs/logpush/logpush-job/enable-destinations/splunk/). When you fill in the Splunk destination:

- Use the endpoint you configured in [Task 1](#task-1---install-and-configure-the-cloudflare-app-for-splunk) for **Splunk HEC URL**, including the `/services/collector/raw` path.
- Use the HEC token you created in [Task 1](#task-1---install-and-configure-the-cloudflare-app-for-splunk) for **Auth Token**, prefixed with `Splunk` (for example, `Splunk 12345678-1234-1234-1234-1234567890ab`).
- Set **Source Type** to the value that matches the dataset you want to push, so the Cloudflare App for Splunk parses events correctly:
  - HTTP requests, Firewall events, Spectrum events, and most zone-scoped datasets: `cloudflare:json`
  - DNS logs, including Zero Trust Gateway DNS: `cloudflare:dns`
  - Audit logs: `cloudflare:audit`
  - Access requests: `cloudflare:access`
  - CASB findings: `cloudflare:casb`
  - Zero Trust Gateway HTTP: `cloudflare:http`
  - Zero Trust Gateway Network: `cloudflare:network`
- Only turn on **Use insecure skip verify option** if your Splunk instance uses a self-signed certificate, as noted in [Task 1](#task-1---install-and-configure-the-cloudflare-app-for-splunk).

Under **Send the following fields**, keep the defaults or refer to the [Dashboard section](#task-3---view-the-dashboards) to select the fields required to fully populate the Cloudflare App for Splunk dashboards.

After you create the job, enable it to start sending logs. To confirm end-to-end delivery, run the following search in Splunk:

```txt
index="cloudflare"
```

Cloudflare sends two system confirmation events to verify connectivity and delivery setup as soon as you enable the job. Regular Cloudflare logs start streaming shortly afterward. Data can take a few minutes to appear.

## Task 3 - View the Dashboards

You can analyze Cloudflare logs with the thirteen (13) dashboards listed below.

You can use filters within these dashboards to help narrow the analysis by date and time, device type, country, user agent, client IP, hostname, and more to further help with debugging and tracing.

### About the Dashboards

The following dashboards outlined below are available as part of the Cloudflare App for Splunk.

#### Cloudflare - Snapshot

*Web Traffic Overview* and *Web Traffic Types*: Get an overview of the most important metrics from your websites and applications on the Cloudflare network. ![Splunk dashboard with Web Traffic Overview metrics](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=2770,height=1850,format=webp/_astro/splunk-cloudflare-snapshot-dashboard.Du4lsJw_.png)

#### Cloudflare - Reliability

*Summary* and *Detailed*: Get insights on the availability of your websites and applications. Metrics include origin response error ratio, origin response status over time, percentage of 3xx/4xx/5xx errors over time, and more. ![Splunk dashboard with a high level summary of Reliability metrics](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=2776,height=1340,format=webp/_astro/splunk-cloudflare-reliability-summary-dashboard.C1py_8XX.png)

![Splunk dashboard with a detailed summary of Reliability metrics](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=2780,height=1398,format=webp/_astro/splunk-cloudflare-reliability-detailed-dashboard.jeSlAQnq.png)

#### Cloudflare - Security

*Overview*: Get insights on threats to your websites and applications, including number of threats stopped, threats over time, top threat countries, and more. ![Splunk dashboard with an overview of Security metrics](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=2780,height=1890,format=webp/_astro/splunk-cloudflare-security-overview.D-c4Punh.png)

*WAF*: Get insights on threat identification and mitigation by our Web Application Firewall, including events like SQL injections, XSS, and more. Use this data to fine tune the firewall to target obvious threats and prevent false positives. ![Splunk dashboard with an overview of Security metrics for WAF](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=2778,height=1788,format=webp/_astro/splunk-cloudflare-security-waf-dashboard.DTZrF-bl.png)

*Rate Limiting*: Get insights on rate limiting protection against denial-of-service attacks, brute-force login attempts, and other types of abusive behavior targeted at your websites or applications. ![Splunk dashboard with an overview of Security metrics for Rate Limiting](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=2772,height=1188,format=webp/_astro/splunk-cloudflare-security-rate-limiting-dashboard.CRoUKWVc.png)

*Bots Summary* and *Bots Detailed*: Investigate bot activity on your website to prevent content scraping, checkout fraud, spam registration and other malicious activities. ![Splunk dashboard with a high level summary of Security metrics for Bots](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=2772,height=1304,format=webp/_astro/splunk-cloudflare-security-bot-summary-dashboard.S5k4rphZ.png)

![Splunk dashboard with a detailed summary of Security metrics for Bots](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=2770,height=1622,format=webp/_astro/splunk-cloudflare-security-bots-detailed-dashboard.x_RSBUYB.png)

#### Cloudflare - Performance

*Requests and Cache* and *Bandwidth*: Identify and address performance issues and caching misconfigurations. Metrics include total vs. cached bandwidth, saved bandwidth, total requests, cache ratio, top uncached requests, and more. ![Splunk dashboard with Performance metrics for Requests and Cache](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=2772,height=1934,format=webp/_astro/splunk-cloudflare-performance-requests-and-cache-dashboard.CzCMXwsS.png)

![Splunk dashboard with Performance metrics for Bandwidth](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=2774,height=1334,format=webp/_astro/splunk-cloudflare-performance-bandwidth-dashboard.B0Io0qTc.png)

*Hostname, Content Type, Request Methods, Connection Type*: Get insights into your most popular hostnames, most requested content types, breakdown of request methods, and connection type.

![Splunk dashboard with Cloudflare Performance metrics including for Hostname, Content Type, Request Methods, Connection Type](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=2788,height=1898,format=webp/_astro/splunk-cloudflare-performance-hostname-dashboard.BNc0Yvsw.png)

*Static vs. Dynamic Content*: Get insights into the performance of your static and dynamic content, including slowest URLs. ![Splunk dashboard with Cloudflare Performance metrics for Static vs. Dynamic Content](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=2776,height=1902,format=webp/_astro/splunk-cloudflare-performance-static-vs-dynamic-dashboard.Dx9F5klY.png)

### Filters

All dashboard have a set of filters that you can apply to the entire dashboard, as shown in the following example. Filters are applied across the entire dashboard.

![Available dashboard filters from the Splunk dashboard](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=2792,height=480,format=webp/_astro/splunk-filters.D7I8q-lv.png)

You can use filters to drill down and examine the data at a granular level. Filters include client country, client device type, client IP, client request host, client request URI, client request user agent, edge response status, origin IP, and origin response status.

The default time interval is set to 24 hours. Note that for correct calculations filter will need to exclude Worker subrequests (**WorkerSubrequest** = *false*) and purge requests (**ClientRequestMethod** is not *PURGE*).

Available Filters:

- Time Range (EdgeStartTimestamp)
- Client Country
- Client Device type
- Client IP
- Client Request Host
- Client Request URI
- Client Request User Agent
- Edge response status
- Origin IP
- Origin Response Status
- RayID
- Worker Subrequest
- Client Request Method

## Splunk CIM field mappings

The Cloudflare App for Splunk maps Cloudflare log fields to [Splunk Common Information Model (CIM) ↗︎](https://docs.splunk.com/Documentation/CIM/latest/User/Overview) field names, so that you can search, correlate, and accelerate Cloudflare data alongside other CIM-compliant sources in your Splunk deployment. The following tables list the mappings the app applies per Cloudflare Logpush dataset.

### HTTP requests

The app applies the following mappings:

| Cloudflare field | Splunk CIM field |
| --- | --- |
| `ClientIP` | `src_ip` |
| `ClientRequestBytes` | `bytes_in` |
| `ClientRequestHost` | `dest_host` |
| `ClientRequestMethod` | `http_method` |
| `ClientRequestPath` | `uri_path` |
| `ClientRequestReferer` | `http_referrer` |
| `ClientRequestURI` | `uri` |
| `ClientRequestUserAgent` | `http_user_agent` |
| `ClientSrcPort` | `src_port` |
| `ClientSSLProtocol` | `ssl_protocol` |
| `EdgeRateLimitAction` | `action` |
| `EdgeResponseBytes` | `bytes_out` |
| `EdgeResponseContentType` | `http_content_type` |
| `EdgeResponseStatus` | `status` |
| `OriginIP` | `dest_ip` |
| `OriginResponseTime` | `response_time` |

### CASB findings

The app applies the following mappings:

| Cloudflare field | Splunk CIM field |
| --- | --- |
| `AssetDisplayName` | `dest` |
| `AssetLink` | `url` |
| `FindingTypeDisplayName` | `category` |
| `FindingTypeID` | `category_id` |
| `FindingTypeSeverity` | `severity` |
| `InstanceID` | `signature_id` |

### Zero Trust Gateway DNS

The app applies the following mappings:

| Cloudflare field | Splunk CIM field |
| --- | --- |
| `DstIP` | `dest` |
| `DstPort` | `dest_port` |
| `Protocol` | `transport` |
| `QueryName` | `query` |
| `QueryTypeName` | `query_type` |
| `RCode` | `reply_code` |
| `SrcIP` | `src` |
| `SrcPort` | `src_port` |

### Audit logs

The app applies the following mappings:

| Cloudflare field | Splunk CIM field |
| --- | --- |
| `ActionResult` | `status` |
| `ActionType` | `action` |
| `ActorID` | `user` |
| `ActorIP` | `src` |
| `ActorType` | `user_category` |
| `OwnerID` | `src_user` |

### Access requests

The app applies the following mappings:

| Cloudflare field | Splunk CIM field |
| --- | --- |
| `Action` | `action` |
| `AppDomain` | `app` |
| `Connection` | `authentication_service` |
| `IPAddress` | `src` |
| `PurposeJustificationResponse` | `reason` |
| `RayID` | `signature_id` |
| `UserUID` | `user_id` |

### Zero Trust Gateway HTTP

The app applies the following mappings:

| Cloudflare field | Splunk CIM field |
| --- | --- |
| `Action` | `action` |
| `DestinationIP` | `dest` |
| `DestinationPort` | `dest_port` |
| `HTTPMethod` | `http_method` |
| `Referer` | `http_referrer` |
| `SourceIP` | `src` |
| `URL` | `url` |
| `UserAgent` | `http_user_agent` |
| `UserID` | `user` |

### Zero Trust Gateway Network

The app applies the following mappings:

| Cloudflare field | Splunk CIM field |
| --- | --- |
| `Action` | `action` |
| `DestinationIP` | `dest_ip` |
| `DestinationPort` | `dest_port` |
| `DeviceName` | `dvc` |
| `OverrideIP` | `dest_translated_ip` |
| `OverridePort` | `dest_translated_port` |
| `PolicyID` | `rule` |
| `SessionID` | `session_id` |
| `SourceIP` | `src_ip` |
| `SourcePort` | `src_port` |
| `Transport` | `transport` |
| `UserID` | `user` |

## Debugging tips

### Incomplete dashboards

The Splunk Cloudflare App relies on data from the Cloudflare Enterprise Logs fields outlined below. Depending on which fields you have enabled, certain dashboards might not populate fully.

If that is the case, verify and test the Cloudflare App filters below each dashboard (these filters are the same across all dashboards). You can delete any filters that you do not need, even if such filters include data fields already contained in your logs.

Also, you could compare the list of fields you are getting in Cloudflare Logs with the fields listed in **Splunk** > **Settings** > **Data Model** > **Cloudflare**.

The available fields are:

- CacheCacheStatus
- CacheResponseBytes
- CacheResponseStatus (deprecated)
- ClientASN
- ClientCountry
- ClientDeviceType
- ClientIP
- ClientIPClass
- ClientRequestBytes
- ClientRequestHost
- ClientRequestMethod
- ClientRequestPath
- ClientRequestProtocol
- ClientRequestReferer
- ClientRequestURI
- ClientRequestUserAgent
- ClientSSLCipher
- ClientSSLProtocol
- ClientSrcPort
- EdgeColoCode
- EdgeColoID
- EdgeEndTimestamp
- EdgePathingOp
- EdgePathingSrc
- EdgePathingStatus
- EdgeRequestHost
- EdgeResponseBytes
- EdgeResponseContentType
- EdgeResponseStatus
- EdgeServerIP
- EdgeStartTimestamp
- OriginIP
- OriginResponseStatus
- OriginResponseTime
- OriginSSLProtocol
- RayID
- SecurityAction
- SecurityActions
- SecurityRuleDescription
- SecurityRuleID
- SecurityRuleIDs
- SecuritySources
- WAFFlags
- WAFMatchedVar
- WorkerSubrequest
- ZoneID

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/analytics-integrations/splunk/#page","headline":"Splunk","description":"This tutorial explains how to analyze Cloudflare Logs using the Cloudflare App for Splunk.","url":"https://developers.cloudflare.com/analytics/analytics-integrations/splunk/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/analytics-integrations/splunk/og.png?v=7bfa5b3e4285a22b","dateModified":"2026-09-01","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Resolve common issues when analyzing Cloudflare Logs with the Cloudflare App for Splunk.
title: Troubleshooting
image: https://developers.cloudflare.com/analytics/analytics-integrations/splunk/troubleshooting/og.png?v=a82f5705220ea820
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Troubleshooting

Last updated Oct 19, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/analytics-integrations/splunk/troubleshooting/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

Use this guide to resolve common issues when analyzing [Cloudflare Logs ↗︎](https://www.cloudflare.com/products/cloudflare-logs/) through the [Cloudflare App for Splunk](https://developers.cloudflare.com/analytics/analytics-integrations/splunk/).

Support scope

Cloudflare Support can help you troubleshoot Cloudflare-side log delivery, including [Logpush](https://developers.cloudflare.com/logs/logpush/) job configuration. Configuring or troubleshooting your Splunk environment — including index administration, HTTP Event Collector (HEC) configuration, dashboards, or app deployment — is outside the scope of Cloudflare Support. Contact your Splunk representative or your integration partner for assistance with those components.

## Firewall Events carry incorrect `_time` values

Events under the `cloudflare:json` sourcetype for the Firewall Events dataset carry `_time` values that do not match the event's actual time, and `splunkd.log` shows entries similar to:

```txt
WARN DateParserVerbose - Failed to parse timestamp.
Defaulting to timestamp of previous event.
```

**Cause:** In older versions of the Cloudflare App for Splunk, the `cloudflare:json` sourcetype extracts `_time` from the `EdgeStartTimestamp` JSON key, which only exists in HTTP requests logs. Firewall Events use a different key (`Datetime`), so timestamp extraction fails and Splunk silently falls back to the timestamp of the most recently indexed event.

**Fix:** Upgrade to the latest version of the [Cloudflare App for Splunk ↗︎](https://splunkbase.splunk.com/app/4501/). The current release parses both `EdgeStartTimestamp` and `Datetime` under the `cloudflare:json` sourcetype.

If you cannot upgrade immediately, or if you maintain a customized `props.conf`, update the `cloudflare:json` stanza on your indexer or heavy forwarder to match both keys, then restart the Splunk service:

```ini
[cloudflare:json]
TRUNCATE = 100000
TIME_PREFIX = "(?:EdgeStartTimestamp|Datetime)"\s*:\s*"
TIME_FORMAT = %Y-%m-%dT%H:%M:%SZ
MAX_TIMESTAMP_LOOKAHEAD = 150
```

**Verify:** Newly indexed Firewall Events carry accurate `_time` values, and `DateParserVerbose` warnings no longer appear in `splunkd.log`. Events indexed before the fix retain their original `_time` values unless they are re-indexed.

## The Cloudflare Security (WAF) dashboard is empty

The `Cloudflare – Security (WAF)` dashboard in the Cloudflare App for Splunk loads without errors, but all panels are empty. Other dashboards (Overview, Performance, Reliability) populate normally, and running the WAF panels' underlying SPL directly in the search bar also returns zero results — even when WAF and security events are confirmed present in the target index.

**Cause:** In older versions of the Cloudflare App for Splunk, the WAF dashboard SPL references Cloudflare log fields that were [removed from the HTTP Requests dataset](https://developers.cloudflare.com/logs/reference/change-notices/2023-02-01-security-fields-updates/#http-requests-dataset-changes):

| Deprecated field | Current field |
| --- | --- |
| `FirewallMatchesRuleIDs{}` | `SecurityRuleIDs` |
| `WAFRuleMessage` | `SecurityRuleDescription` |

Splunk does not raise an error when a search references a field that is absent from all indexed events — it completes the search and returns zero results, leaving every dashboard panel empty.

**Fix:** Upgrade to the latest version of the [Cloudflare App for Splunk ↗︎](https://splunkbase.splunk.com/app/4501/). The current release references `SecurityRuleIDs` and `SecurityRuleDescription` throughout the WAF dashboard, saved searches, and macros.

If you maintain a customized fork of the app, replace all references to `FirewallMatchesRuleIDs{}` and `WAFRuleMessage` in your dashboard XML, saved searches, and macros with `SecurityRuleIDs` and `SecurityRuleDescription`, respectively.

**Verify:** Reload the `Cloudflare – Security (WAF)` dashboard. Panels should populate with recent WAF and security events. A direct search such as `index=<your-index> sourcetype=cloudflare:json SecurityRuleIDs=*` should also return matching events.

## Still not resolved

If your issue is not covered here:

- Consult the [Cloudflare App for Splunk page ↗︎](https://splunkbase.splunk.com/app/4501/) on Splunkbase for the latest version and release notes.
- Review the [Cloudflare Logs change notices](https://developers.cloudflare.com/logs/reference/change-notices/) for recent schema changes that may affect your searches or dashboards.
- [Contact Cloudflare Support](https://developers.cloudflare.com/support/contacting-cloudflare-support/) for issues involving Cloudflare-side log delivery.
- Contact your Splunk representative or your integration partner for issues within your Splunk environment.

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/analytics-integrations/splunk/troubleshooting/#page","headline":"Troubleshooting","description":"Resolve common issues when analyzing Cloudflare Logs with the Cloudflare App for Splunk.","url":"https://developers.cloudflare.com/analytics/analytics-integrations/splunk/troubleshooting/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/analytics-integrations/splunk/troubleshooting/og.png?v=a82f5705220ea820","dateModified":"2026-10-19","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: View aggregated metrics across all account domains.
title: Account analytics (beta)
image: https://developers.cloudflare.com/analytics/account-and-zone-analytics/account-analytics/og.png?v=09c868a48cbc7b05
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Account analytics (beta)

Last updated Oct 2, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/account-and-zone-analytics/account-analytics/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

Cloudflare account analytics lets you access a wide range of aggregated metrics from all the sites under a specific Cloudflare account.

Note

For general information about all of Cloudflare's analytics offerings, refer to [About Cloudflare Analytics](https://developers.cloudflare.com/analytics/faq/about-analytics/).

---

## View your account analytics

To view metrics for your site, in the Cloudflare dashboard, go to **Observability** > **Analytics** > **Account analytics**.

[Go to **Account analytics** ↗](https://dash.cloudflare.com/?to=/:account/analytics)

Once it loads, the Account Analytics app displays a collection of categorized charts with aggregated metrics for your account. To understand the various metrics available, refer to *Review your account metrics* below.

---

## Review your account metrics

This section outlines the aggregated metrics under each category. Before reviewing your metrics, let's define a couple of concepts used in some panels:

- *Rate* -  Reflects the ratio between the amount for a specific data category and the total.
- *Bandwidth* - Refers to the number of bytes sent from the Cloudflare edge network to the requesting client.

Also, note that:

- To filter metrics for a specific time period, use the dropdown in the top right.
- Most metrics are grouped into panels representing different aspects of the underlying data.

### Summary of metrics

Below is a brief description of the major elements comprising the metrics available.

#### HTTP Traffic

These charts aggregate data for HTTP traffic, and include:

![Chart showing last week's data for HTTP traffic](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=702,height=394,format=webp/_astro/hc-dash-account-analytics-map.CcPRTQU-.png)

- Spark lines for *Requests*, *Bandwidth*, *Page views*, and *Visitors* (*Unique IPs)*
- An interactive map that breaks down the number of requests by country
- A table combining numerical and spark line data, sorted by total number of requests per country

#### Security

![Panel displaying lines highlighting encryption metrics: requests, requests rate, bandwidth, and bandwidth rate](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=702,height=86,format=webp/_astro/hc-dash-account-analytics_security_panel.5rFJ7hHV.png)

This panel features spark lines highlighting various encryption metrics, including: *requests*, *requests rate*, *bandwidth*, and *bandwidth rate*.  These also include a comparative percentage change based on the previous period.

#### Cache

![Panel displaying lines for caching metrics: requests, requests rate, bandwidth, and bandwidth rate](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=704,height=88,format=webp/_astro/hc-dash-account-analytics_cache_card.BOCedSTx.png)

This panel features spark lines for various caching metrics, including: *requests*, *requests rate*, *bandwidth*, and *bandwidth rate*.  These also include a comparative percentage change based on the previous equivalent period.  For example, if you selected *Last week* as your time period, the previous period refers to the *week* before.

#### Errors

![Panel displaying lines for 4xx and 5xx error rates](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=704,height=88,format=webp/_astro/hc-account-analytics_errors_card.D2i2BrS9.png)

This panel displays spark lines for 4xx and 5xx error rates, respectively. Learn more about [HTTP Status Codes](https://developers.cloudflare.com/support/troubleshooting/http-status-codes/). 

#### Network

![Statistics showing the percentage of requests that use a specific version of HTTP](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=702,height=128,format=webp/_astro/hc-dash-account-analytics_network_card.Fso_4DUE.png)

#### Client HTTP Version Used

These statistics show the percentage of requests that use a specific version of HTTP.

#### Traffic Served Over SSL

These statistics show the percentage of traffic that is encrypted using a specific version of SSL or TLS.

#### Content Type Breakdown

These statistics show the number of requests based on the resource content type.

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/account-and-zone-analytics/account-analytics/#page","headline":"Account analytics (beta)","description":"View aggregated metrics across all account domains.","url":"https://developers.cloudflare.com/analytics/account-and-zone-analytics/account-analytics/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/account-and-zone-analytics/account-analytics/og.png?v=09c868a48cbc7b05","dateModified":"2026-10-02","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Understand how Workers subrequests affect analytics.
title: Cloudflare analytics with Workers
image: https://developers.cloudflare.com/analytics/account-and-zone-analytics/analytics-with-workers/og.png?v=068f3fcda68983ab
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Cloudflare analytics with Workers

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/account-and-zone-analytics/analytics-with-workers/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

Learn how Cloudflare analytics tracks requests made by [Cloudflare Workers](https://developers.cloudflare.com/workers/).

## What is a subrequest

With a no-op Worker (a Worker that simply proxies traffic by passing on the original client request to the origin and proxying the response) running on a particular route, the request to the origin is counted as a 'subrequest', separate from initial client to edge request. Thus, unless the Worker responds with a static response and never hits an origin, the eyeball → edge request, and edge → origin request will each be counted separately towards the request or bandwidth count in Analytics. Subrequests are not included in the **Requests** or **Bandwidth** graphs of the Cloudflare **Analytics** app.

---

## Zone analytics

In the dashboard, the numbers in zone analytics reflect visitor traffic. That is, the number of requests shown in zone analytics (under the Analytics tabs in the dashboard) is the number of requests that were served to the client.

Similarly, the bandwidth is counted based on the bandwidth that is sent to the client, and status codes reflect the status codes that were served back to the client (so if a subrequest received a 500, but you respond with a 200, a 200 will be shown in the status codes breakdown).

---

## Worker analytics

For a breakdown of subrequest traffic (origin facing traffic), you may go to the Cloudflare **Analytics** app and select the **Workers** tab. Under the **Workers** tab, below the Service Workers panel, are a **Subrequests** breakdown by count, **Bandwidth** and **Status Codes**. This will help you spot and debug errors at your origin (such as spikes in 500s), and identify your cache-hit ratio to help you understand traffic going to your origin.

---

## FAQ

**Why do I not have any analytics for Workers?**

- If you are not currently using Workers (do not have Workers deployed on any routes or filters), we will not have any information to show you.
- If your Worker sends a static response back to the client without ever calling fetch() to an origin, you are not making any subrequests, thus, all traffic will be shown in zone Analytics

**Will this impact billing?** 

No,  [billing for Workers](https://developers.cloudflare.com/workers/platform/pricing/) is based on requests that go through a Worker. 

**Why am I seeing such a high cache hit ratio?**

Requests served by a Worker always show as cached. For an accurate cache hit ratio on subrequests, refer to the **Subrequests** graph in the **Analytics** app under the **Workers** analytics tab.

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/account-and-zone-analytics/analytics-with-workers/#page","headline":"Cloudflare analytics with Workers","description":"Understand how Workers subrequests affect analytics.","url":"https://developers.cloudflare.com/analytics/account-and-zone-analytics/analytics-with-workers/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/account-and-zone-analytics/analytics-with-workers/og.png?v=068f3fcda68983ab","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: View account-wide application security reports covering WAF, bots, DDoS, and API Shield.
title: Security reports
image: https://developers.cloudflare.com/analytics/account-and-zone-analytics/app-security-reports/og.png?v=5f8604bf99c289db
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Security reports

Last updated Oct 15, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/account-and-zone-analytics/app-security-reports/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

Application Security reports provide cyber attack insights and trends for all of the Enterprise zones in your Cloudflare account.

The reports are automatically generated on a monthly basis.

You can access reports by going to the **Security reports** page or via the [API](#api). You can access reports from previous months by selecting the month from the dropdown.

[Go to **Security reports** ↗](https://dash.cloudflare.com/?to=/:account/security-center/reports)

To download the report, select **Print report**.

Reports from before April 2025 can be accessed through **Security reports** > **Legacy reports**. Due to limitations in the legacy reports, some customers may not have reports for every month prior to April 2025.

The current reports are curated by Cloudflare and will be expanded to include more insights. The option to create custom reports, filter by various fields, and schedule reports will be added in upcoming improvements.

---

## Report types

Currently, only Application Security reports are available. They cover the entire suite of products such as [HTTP DDoS Protection](https://developers.cloudflare.com/ddos-protection/managed-rulesets/http/), [WAF](https://developers.cloudflare.com/waf/), and [Bot Management](https://developers.cloudflare.com/bots/).

Reports for Application Performance, [Cloudflare One](https://developers.cloudflare.com/cloudflare-one/), and Network Services, such as [Magic Transit](https://developers.cloudflare.com/magic-transit/), will be made available in future improvements.

---

## Report layout

Each report includes the following sections:

- Executive summary
- Distribution of allowed and mitigated requests
- [Industry benchmarks](#industry-benchmarks) that show how you compare to your peers by selecting your industry
- Top five source countries of allowed traffic and mitigated traffic including a map visualization
- Top five most targeted hostnames
- Top five most effective mitigation rules

To view more details, apply filters, analyze the data, and generate ad-hoc reports, use the [Security Analytics dashboard](https://developers.cloudflare.com/waf/analytics/security-analytics/) or [Log Explorer](https://developers.cloudflare.com/observability/logs/log-explorer/).

### Industry benchmarks

Industry benchmarks provide additional context for your mitigated traffic by comparing your organization's attack activity against others in the same industry. These benchmarks help you understand whether the volume and frequency of attacks you experience are typical, higher, or lower than your peers — offering a clear sense of where your organization stands within its threat landscape.

Beyond providing context, benchmarks can also help demonstrate value to stakeholders by quantifying the scale of threats your organization faces and how effectively Cloudflare mitigates them. This information can be useful when communicating your security posture internally or when prioritizing future security investments.

To ensure fairness and accuracy, Cloudflare normalizes your data before comparison. For each month, we calculate the percentage of mitigated requests relative to the total requests across your account and eligible zones. This normalization ensures that benchmarks are based on relative attack intensity rather than total traffic volume so larger or smaller organizations can be compared meaningfully.

The result helps you interpret your mitigated traffic data in context. For example, you may see a statement such as "*You are in the top 25% most attacked companies in the Cosmetics industry.*" This insight enables you to better understand your threat exposure, communicate results to stakeholders, and understand value of the protection Cloudflare provides.

If your account is not assigned an industry or if the shown industry is incorrect, use the link within the report to select the correct industry.

It may take a while for your new selection to take effect, and it may only be applied to future reports.

If you have multiple Cloudflare accounts, select the industry that is most relevant for the specific account.

---

## Prerequisites

You must have at least one Enterprise zone. Application Security reports are automatically enabled on your Enterprise zone. No action is required.

If you do not have any Enterprise zones, a report will not be generated. If you have an account that is not older than one month, a report will not be generated yet.

### Required roles

A Cloudflare user must have one of the following [roles](https://developers.cloudflare.com/fundamentals/manage-members/roles/) to download Application Security reports:

- Super Administrator
- Administrator

---

## API

*List all report policies for a specific accountsh*

```sh
GET /accounts/{account_id}/reporting/policies
```

*Retrieve the details of a single, specific report policysh*

```sh
GET /accounts/{account_id}/reporting/policies/{policy_id}
```

*List all generated reports for a specific accountsh*

```sh
GET /accounts/{account_id}/reporting/reports
```

*Retrieve a single, specific report, including its data and findingssh*

```sh
GET /accounts/{account_id}/reporting/reports/{report_id}
```

<details>

<summary>

Data returned by the API

</summary>

- Account ID - Account Name - Account Industry - Time range - Total zones - Total zones analyzed - Industry percentile (nullable float) - Total requests (count, percentage) - Total mitigated requests (count, percentage) - Total served requests (count, percentage) - Top 5 hostnames by mitigated requests (hostname, count) - Top 5 source countries by served requests (country, count)
- Top 5 source countries by mitigated requests (country, count) - Top 5 rules by mitigated requests (rule name, rule type, count)

</details>

Note

The data's time range is independent of when the report is generated.

### Cross-account reports

Each report is generated per account. You can use the [API](#api) to retrieve the reports for all of your accounts and aggregate the data.

---

## Availability

This feature is available in closed beta to Enterprise customers.

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/account-and-zone-analytics/app-security-reports/#page","headline":"Security reports","description":"View account-wide application security reports covering WAF, bots, DDoS, and API Shield.","url":"https://developers.cloudflare.com/analytics/account-and-zone-analytics/app-security-reports/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/account-and-zone-analytics/app-security-reports/og.png?v=5f8604bf99c289db","dateModified":"2026-10-15","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"},"keywords":["Analytics"]}
```

---

---
description: Analyze HTTP status code distribution per data center.
title: Status codes
image: https://developers.cloudflare.com/analytics/account-and-zone-analytics/status-codes/og.png?v=ec5f8027bbabadf9
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Status codes

Last updated May 6, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/account-and-zone-analytics/status-codes/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

Note

Status Codes analytics by data center is exclusive to the [enterprise level of service ↗︎](https://www.cloudflare.com/plans/enterprise/contact/).

Status Codes metrics in the Cloudflare dashboard **Analytics** app provide customers with a deeper insight into the distribution of errors that are occurring on their website per data center. A data center facility is where Cloudflare runs its servers that make up our edge network ([current locations ↗︎](https://www.cloudflare.com/network/)).

HTTP status codes that appear in a response passing through our edge are displayed in analytics.

The `Origin Status Code` can help you investigate issues on your origin. If your origin returns a `5xx` error, Cloudflare's edge will forward this error to the end user. Comparing the `Edge Status Code` and `Origin Status Code` can help determine whether the issue is occurring on your origin or on the Cloudflare edge.

Errors that originate from our edge servers (blank `502`, `503`, or `504` error page with just `Cloudflare`) are not reported as part of the error analytics.

You can filter out specific error(s) by selecting one or more in the legend. You can also exclude a particular error and it will no longer display as part of the graph.

Note

Users may also see `100x` errors which are not reported. These will be displayed as either `403` or `409` (edge) errors.

![Error analytics by Cloudflare data center](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=1458,height=940,format=webp/_astro/status-codes.BbTZPg-P.png)

---

## Common edge status codes

- `400` - Bad Request intercepted at the Cloudflare Edge (for example, missing or bad HTTP header)
- `403` - Security functionality (for example, Web Application Firewall, Browser Integrity Check, [Cloudflare challenges](https://developers.cloudflare.com/cloudflare-challenges/), and most 1xxx error codes)
- `409` - DNS errors typically in the form of 1000 or 1001 error code
- `413` - File size upload exceeded the maximum size allowed (configured in the dashboard under **Network** > **Maximum Upload Size**.)
- `444` - Used by Nginx to indicate that the server has returned no information to the client, and closed the connection. This error code is internal to Nginx and is **not** returned to the client.
- `499` - Used by Nginx to indicate when a connection has been closed by the client while the server is still processing its request, making the server unable to send a status code back.

For more information, refer to [4xx Client Error](https://developers.cloudflare.com/support/troubleshooting/http-status-codes/4xx-client-error/).

---

## Common origin status codes

- `400` - Origin rejected the request due to bad, or unsupported syntax sent by the application.
- `404` - Only if the origin triggered a 404 response for a request.
- `4xx`
- `50x`

For more information, refer to [4xx Client Error](https://developers.cloudflare.com/support/troubleshooting/http-status-codes/4xx-client-error/) and [Troubleshooting Cloudflare 5XX errors](https://developers.cloudflare.com/support/troubleshooting/http-status-codes/cloudflare-5xx-errors/).

---

## 52x errors

- `520` - This is essentially a "catch-all" response for when the origin server returns something unexpected, or something that is not tolerated/cannot be interpreted by our edge (that is, protocol violation or empty response).
- `522` - Our edge could not establish a TCP connection to the origin server.
- `523` - Origin server is unreachable (for example, the origin IP changed but DNS was not updated, or due to network issues between our edge and the origin).
- `524` - Our edge established a TCP connection, but the origin did not reply with a HTTP response before the connection timed out.
- `525` - This error indicates that the SSL handshake between Cloudflare and the origin web server failed, either due to a network issue or a certificate issue at the origin.
- `526` - The certificate configured at the origin is not valid.

For more information, refer to [Troubleshooting Cloudflare 5XX errors](https://developers.cloudflare.com/support/troubleshooting/http-status-codes/cloudflare-5xx-errors/).

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/account-and-zone-analytics/status-codes/#page","headline":"Status codes","description":"Analyze HTTP status code distribution per data center.","url":"https://developers.cloudflare.com/analytics/account-and-zone-analytics/status-codes/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/account-and-zone-analytics/status-codes/og.png?v=ec5f8027bbabadf9","dateModified":"2026-05-06","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Review threat categories blocked by Cloudflare.
title: Threat types
image: https://developers.cloudflare.com/analytics/account-and-zone-analytics/threat-types/og.png?v=af3e3875aae6d705
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Threat types

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/account-and-zone-analytics/threat-types/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

Cloudflare classifies the threats that it blocks or challenges. To help you understand more about your site’s traffic, the 'Type of Threats Mitigated' metric on the analytics page measures threats blocked or challenged by the following categories:

## Bad browser

The source of the request was not legitimate or the request itself was malicious. Users would receive a  [1010 error page](https://developers.cloudflare.com/support/troubleshooting/http-status-codes/cloudflare-1xxx-errors/error-1010/) in their browser.

Cloudflare's [Browser Integrity Check](https://developers.cloudflare.com/waf/tools/browser-integrity-check/) looks for common HTTP headers abused most commonly by spammers and denies them access to your page. It will also challenge visitors that do not have a user agent or a non standard user agent (also commonly used by bots, crawlers, or visitors).

## Blocked hotlink

[Hotlink Protection](https://developers.cloudflare.com/waf/tools/scrape-shield/hotlink-protection/) ensures that other sites cannot use your bandwidth by building pages that link to images hosted on your origin server. This feature can be turned on and off by Cloudflare's customers.

## Human challenged

Visitors were presented with an interactive challenge page and failed to pass.

*Note: An interactive challenge page is a difficult to read word or set of numbers that only a human can translate. If entered incorrectly or not answered in a timely fashion, the request is blocked.*

## Browser challenge

A bot gave an invalid answer to the JavaScript challenge (in most cases this will not happen, bots typically do not respond to the challenge at all, so "failed" JavaScript challenges would not get logged).

*Note: During a JavaScript challenge you will be shown an interstitial page for about five seconds while Cloudflare performs a series of mathematical challenges to make sure it is a legitimate human visitor.*

## Bad IP

A request that came from an IP address that is not trusted by Cloudflare based on the threat score.

Previously, the threat score was a score from `0` (zero risk) to `100` (high risk) classifying the IP reputation of a visitor. Currently, the threat score is always `0` (zero).

## Country block

Requests from countries that were blocked based on the [user configuration](https://developers.cloudflare.com/waf/tools/ip-access-rules/) set in the WAF.

## IP block (user)

Requests from specific IP addresses that were blocked based on the [user configuration](https://developers.cloudflare.com/waf/tools/ip-access-rules/) set in the WAF.

## IP range block (/16)

A /16 IP range that was blocked based on the [user configuration](https://developers.cloudflare.com/waf/tools/ip-access-rules/) set in the WAF.

## IP range block (/24)

A /24 IP range that was blocked based on the [user configuration](https://developers.cloudflare.com/waf/tools/ip-access-rules/) set in the WAF.

## New Challenge (user)

[Challenge](https://developers.cloudflare.com/cloudflare-challenges/) based on user configurations set for visitor's IP in either WAF managed rules or custom rules, configured in **Security** > **WAF**.

## Challenge error

Requests made by a bot that failed to pass the challenge.

*Note: An interactive challenge page is a difficult to read word or set of numbers that only a human can translate. If entered incorrectly or not answered in a timely fashion, the request is blocked.*

## Bot Request

Request that came from a bot.

## Unclassified

Unclassified threats comprises a number of automatic blocks that are not related to the Browser Integrity Challenge (Bad Browser). These threats usually relate to Hotlink Protection, and other actions that happen on Cloudflare's global network based on the composition of the request (and not its content).

Unclassified means a number of conditions under which we group common threats related to Hotlink Protection as well as specific requests that are blocked at Cloudflare's global network before reaching your servers.

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/account-and-zone-analytics/threat-types/#page","headline":"Threat types","description":"Review threat categories blocked by Cloudflare.","url":"https://developers.cloudflare.com/analytics/account-and-zone-analytics/threat-types/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/account-and-zone-analytics/threat-types/og.png?v=af3e3875aae6d705","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Understand how total threat counts are calculated.
title: Total threats stopped
image: https://developers.cloudflare.com/analytics/account-and-zone-analytics/total-threats-stopped/og.png?v=2346a2fe659d84c3
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Total threats stopped

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/account-and-zone-analytics/total-threats-stopped/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

Total Threats Stopped measures the number of 'suspicious' and 'bad' requests that were aimed at your site. Requests receive these labels as they enter Cloudflare's network:

- **Legitimate:** Request passed directly to your site.
- **Suspicious:** Request has been challenged with a [Cloudflare challenge](https://developers.cloudflare.com/cloudflare-challenges/).
- **Bad:** Request has been blocked because our Browser Integrity Check, or because of user configured settings like WAF rules or IP Access rules.

In addition to threat analytics you can also monitor search engine crawlers going to your websites. For most websites, threats and crawlers make up 20% to 50% of traffic.

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/account-and-zone-analytics/total-threats-stopped/#page","headline":"Total threats stopped","description":"Understand how total threat counts are calculated.","url":"https://developers.cloudflare.com/analytics/account-and-zone-analytics/total-threats-stopped/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/account-and-zone-analytics/total-threats-stopped/og.png?v=2346a2fe659d84c3","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Analyze request and bandwidth data per zone.
title: Zone Analytics
image: https://developers.cloudflare.com/analytics/account-and-zone-analytics/zone-analytics/og.png?v=dcd0a5a0e02df53e
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Zone Analytics

Last updated Oct 2, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/account-and-zone-analytics/zone-analytics/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

The Cloudflare zone analytics is a major component of the overall Cloudflare Analytics product line.  Specifically, this app gives you access to a wide range of metrics, collected at the website or domain level.

Note

Read [Cloudflare Analytics](https://developers.cloudflare.com/analytics/faq/about-analytics/) for general information about all of Cloudflare's analytics offerings. You can also understand the characteristics of the data that Cloudflare captures and processes.

---

## View your website analytics

To view metrics for your website, in the Cloudflare dashboard, select your domain and go to **Analytics**.

[Go to **HTTP Traffic** ↗](https://dash.cloudflare.com/?to=/:account/:zone/analytics/traffic)

The Analytics page has tabs for **Traffic**, **Performance**, **Security**, **Cache**, **Origin**, **DNS**, and **Visitors**, with one time range and one set of filters shared across all tabs. The detailed HTTP Traffic, Security, Performance, and Workers views described in this page remain available from those tabs. To understand the various metrics available, refer to [Review your website metrics](#review-your-website-metrics).

---

## Review your website metrics

This section outlines the metrics available under each Analytics app tab. Before proceeding, note that each tab may contain:

- One or more panels to further categorize the underlying metrics.
- A dropdown (on the panel's top right) to filter metrics for a specific time period. Every plan can view at least the last 30 days. Longer time periods depend on the Cloudflare plan that your domain is associated with.

Note

Cloudflare analytics are case sensitive for paths and URIs. Make sure that filters or queries use the correct case.

Below is a summary of each Analytics app tab.

### HTTP Traffic

#### Free plan

These metrics include legitimate user requests as well as crawlers and threats. The HTTP Traffic tab features the following panels: 

- **Web Traffic** - Displays metrics for *Requests*, *Bandwidth*, and *Unique Visitors*. If you are using Cloudflare Workers, subrequests data will not be visible in zone Traffic Analytics. Instead, you can find subrequests analytics under the **Workers & Pages** tab in the **Overview** section. Refer to [Worker Analytics](https://developers.cloudflare.com/analytics/account-and-zone-analytics/analytics-with-workers/#worker-analytics) for more information.
- **Web Traffic Requests by Country** - Is an interactive map that breaks down the number of requests by country.  This panel also includes a data table for **Top Traffic Countries / Regions** that display the countries with the most number of requests (up to five, if the data exists).

#### Pro, Business, or Enterprise plan

Note

Privacy-first HTTP Traffic Analytics are available on the Pro, Business, and Enterprise plans.

Analytics are based on Cloudflare's edge logs, with no need for third party scripts or trackers. The HTTP Traffic tab features the following metrics:

- **Requests** - An HTTP request. A typical page view requires many requests. If you are using Cloudflare Workers, subrequests data will not be visible in zone HTTP Traffic Analytics. Instead, you can find subrequests analytics under the **Workers & Pages** tab in the **Overview** section. Refer to [Worker Analytics](https://developers.cloudflare.com/analytics/account-and-zone-analytics/analytics-with-workers/#worker-analytics) for more information.
- **Data Transfer** - Total HTTP data transferred in responses.
- **Page views** - A page view is defined as a successful HTTP response with a content-type of HTML.
- **Visits** - A visit is defined as a [page view](#page-views) that originated from a different website, or direct link. Cloudflare checks where the HTTP referer does not match the hostname. One visit can consist of multiple page views.
- **API Requests** - An HTTP request for API data.

To receive more detailed metrics, **Add filter**. You can also filter each metric by:

- Cache status
- Data center
- Source ASN
- Country
- Source device type
- Source IP
- Referer host
- Host
- HTTP method
- HTTP version
- Path
- Query string
- Content type
- Edge status code
- Origin status code
- Security Action
- Security Source
- Source browser
- Source operating system
- Source user agent
- X-Requested-With header

In addition, the following filters are available to Enterprise [Bot Management](https://developers.cloudflare.com/bots/get-started/bot-management/) customers only.

- Source JA4 fingerprint
- Source JA3 fingerprint

To change the time period, use the dropdown menu on the right-hand side above the graph. You can also drag to zoom on the graph.

### Security

For this tab, the number and type of charts may vary based on existing data and customer plan. Most of the metrics in this tab come from the Cloudflare Firewall app. The panels available include:

- **Threats** - Displays a data summary and an area chart showing threats against the site.
- **Threats by Country** - Is an interactive map highlighting the countries where threats originated. It also includes data tables with statistics on **Top Threat Countries / Regions** and **Top Crawlers / Bots.**
- **Rate Limiting** (add-on service) - Features a line chart highlighting matching and blocked requests, based on rate limits.  To learn more, consult [Rate Limiting Analytics](https://developers.cloudflare.com/waf/reference/legacy/old-rate-limiting/#analytics).
- **Overview** - Displays a set of pie charts for: **Total Threats Stopped**, **Traffic Served Over SSL**, and **Types of Threats Mitigated**. If available, the expandable **Details** link display a table with numerical data.

### Performance

The metrics aggregated under this tab span multiple Cloudflare services.  The panels available include:

- **Origin Performance (Argo)** (add-on service) - Displays metrics related to response time between the Cloudflare edge network and origin servers for the last 48 hours.  For additional details, refer to [Argo Analytics](https://developers.cloudflare.com/argo-smart-routing/analytics/).
- **Overview** - Displays a set of pie charts for: **Client HTTP Version Used**, **Bandwidth Saved**, and **Content Type Breakdown**. If available, the expandable **Details** link display a table with numerical data.

### Workers

This panel features metrics for Cloudflare Workers. To learn more, read [Cloudflare analytics with Workers](https://developers.cloudflare.com/analytics/account-and-zone-analytics/analytics-with-workers/).

### Logs

The Logs tab is not a metrics feature. Instead, Customers in the Enterprise plan can enable the [Cloudflare Logs Logpush](https://developers.cloudflare.com/logs/logpush/) service. You can use Logpush to download and analyze data using any analytics tool of your choice. 

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"WebPage","@id":"https://developers.cloudflare.com/analytics/account-and-zone-analytics/zone-analytics/#page","headline":"Zone Analytics","description":"Analyze request and bandwidth data per zone.","url":"https://developers.cloudflare.com/analytics/account-and-zone-analytics/zone-analytics/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/account-and-zone-analytics/zone-analytics/og.png?v=dcd0a5a0e02df53e","dateModified":"2026-10-02","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Overview of Cloudflare analytics data and processing.
title: About Cloudflare Analytics
image: https://developers.cloudflare.com/analytics/faq/about-analytics/og.png?v=eaccfdf56be8130a
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# About Cloudflare Analytics

Last updated Oct 2, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/faq/about-analytics/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

In an effort to make analytics an ubiquitous component of all Cloudflare's products, Cloudflare has implemented, and continues to evolve, several ways in which customers can access and gain insights from Internet properties on Cloudflare.

You can access root-level analytics that give you an overview of metadata related to your Cloudflare account, analytics related to specific properties and products, and the GraphQL API that gives you more control over how you visualize the analytics and log information available on the Cloudflare dashboard.

Refer to [Types of analytics](https://developers.cloudflare.com/analytics/types-of-analytics/) for more information regarding this subject.

## How Cloudflare captures and processes analytics data

The underlying datasets that Cloudflare Analytics captures and processes share the following characteristics:

- All metrics reflect traffic proxied through the Cloudflare network (also known as orange-clouded), as configured via DNS records in the Cloudflare DNS app. Note that for a [CNAME setup](https://developers.cloudflare.com/dns/zone-setups/partial-setup/), Cloudflare is unable to offer DNS metrics.
- Cloudflare does not count traffic for unproxied DNS records. However, if your site is not proxied through Cloudflare but Cloudflare is your authoritative DNS server, then we are able to collect DNS metrics.
- Cloudflare can only proxy information for traffic targeting [specific ports](https://developers.cloudflare.com/fundamentals/reference/network-ports/).
- In determining the originating country, Cloudflare uses the IP address associated with each request. Learn about [Configuring Cloudflare IP Geolocation](https://developers.cloudflare.com/network/ip-geolocation/).

## Apparent data discrepancies

It is possible that your Cloudflare metrics do not fully align with data for the same site as reported by other analytics sources, such as Google Analytics and web server logs.

Once Cloudflare identifies a unique IP address for a request, we identify such request as a visit. Therefore, the number of visitors Cloudflare Analytics shows is probably higher than what other analytics services may report.

For example, Google Analytics and other web-based analytics programs use JavaScript on the web browser to track visitors. As a result, Google Analytics does not record threats, bots, and automated crawlers because those requests typically do not trigger JavaScript. Also, these services do not track visitors who disable JavaScript on their browser or who leave a page before it fully loads.

Finally, it is likely that unique visitor data from the Cloudflare Analytics app is greater than your search analytics unique pageviews. This is because pageviews reflect when someone visits a page via a web browser and loads the entire page. However, when another site or service like a bot, plugin, or API is consuming partial content from your site (but not loading a full page), this counts as a unique visitor in Cloudflare and not as a pageview.

## About missing metrics

You may not be seeing metrics on Cloudflare Analytics for the following reasons:

- You only recently signed up for Cloudflare. Metrics are delayed 24 hours for domains on a free Cloudflare plan.
- If you signed up directly with Cloudflare, your nameservers might not be pointing to Cloudflare at your registrar just yet. Registrars can take 24-72 hours to update their nameservers. Metrics will not start gathering until we detect the nameservers pointing to Cloudflare.
- If you signed up through a Cloudflare [hosting partner option ↗︎](https://www.cloudflare.com/partners/), something might not be configured correctly. Contact the hosting partner for support.
- Some browser extensions designed to block ads may prevent analytics from loading. To address this issue, disable the ad block extension or allow `cloudflare.com` on it.

Note

Activations through a hosting partner works via a [CNAME setup](https://developers.cloudflare.com/dns/zone-setups/partial-setup/) on the `www` record. If most of your traffic actually goes to `domain.com`, [forward your traffic](https://developers.cloudflare.com/rules/url-forwarding/bulk-redirects/) from `domain.com` to `www.domain.com`.

## Why does the analytics data on the **Overview** page not match what I have under **View More Analytics**?

The Overview page shows analytics based on all traffic, including subrequests. However, when you go to **Analytics** > **Traffic**, the metrics (for example, `Requests`, `Data`, `Visits`) are filtered to show only end user traffic (that is, `requestSource = eyeball`).

As a result, subrequests are excluded from the **Traffic** view, which can lead to discrepancies between the numbers shown in **Overview** and those displayed in other analytics sections of the dashboard.

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/faq/about-analytics/#page","headline":"About Cloudflare Analytics","description":"Overview of Cloudflare analytics data and processing.","url":"https://developers.cloudflare.com/analytics/faq/about-analytics/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/faq/about-analytics/og.png?v=eaccfdf56be8130a","dateModified":"2026-10-02","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Understand why GraphQL API results may vary slightly.
title: GraphQL API inconsistent results
image: https://developers.cloudflare.com/analytics/faq/graphql-api-inconsistent-results/og.png?v=0f9f6fc2fbac7cde
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# GraphQL API inconsistent results

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/faq/graphql-api-inconsistent-results/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

If you run the same GraphQL Analytics API query multiple times and receive slightly different results, this is caused by Adaptive Bit Rate (ABR) sampling. ABR dynamically adjusts data resolution based on query complexity and timing, which can result in slight variations between query runs.

To reduce variation, query shorter timeframes (daily or weekly instead of monthly), use aggregated datasets (nodes with the `Groups` suffix), and request confidence intervals to understand data quality. For more information, refer to [Sampling](https://developers.cloudflare.com/analytics/graphql-api/sampling/).

## What is sampling?

Cloudflare's data pipeline handles over 700 million events per second across the global network. Processing all this data in real-time for every query would be prohibitively expensive and time-consuming.

Sampling analyzes a subset of data rather than every individual data point. Cloudflare uses Adaptive Bit Rate (ABR) sampling to ensure queries complete quickly, even when working with large datasets.

ABR stores data at multiple resolutions:

- **100%** — Full data (used for smaller datasets)
- **10%** — 10% sample (medium resolution)
- **1%** — 1% sample (lower resolution)

When you run a query, ABR dynamically selects the best resolution based on query complexity, time range requested, number of rows to retrieve, and current system load.

## Why do results vary between query runs?

Results can vary for several reasons:

- **Dynamic resolution selection** — ABR may choose different sampling resolutions on different query runs based on system conditions.
- **Long time ranges** — Querying 30 days at once is an expensive operation that triggers more aggressive sampling.
- **High query complexity** — Complex queries with many filters or aggregations may be sampled differently.
- **System load** — During high-traffic periods, the system may apply more aggressive sampling to ensure fair resource distribution.

For example, running the same 30-day query twice might return 3,500 objects one time and 3,600 objects another time. This indicates different sampling resolutions were used.

## Can I trust sampled data?

Yes. Sampled data is highly reliable and provides insights as dependable as those derived from full datasets. Cloudflare's sampling techniques capture the essential characteristics of the entire dataset.

Aggregated metrics (totals, averages, percentiles) are extrapolated based on the sample size, so reported metrics accurately represent the entire dataset. Results based on thousands of rows are highly likely to be representative.

Note

Sampling may not capture extremely rare events with very low occurrence rates.

## How can I reduce variation in my query results?

### Query shorter time ranges

Instead of querying an entire month at once, break queries into smaller intervals (daily or weekly).

Before (more variable):

```graphql
datetime_geq: "2024-09-01T00:00:00Z"
datetime_lt: "2024-10-01T00:00:00Z"
```

After (more consistent):

```graphql
datetime_geq: "2024-09-01T00:00:00Z"
datetime_lt: "2024-09-02T00:00:00Z"
```

Then aggregate the results client-side. Smaller time windows are less likely to trigger aggressive sampling thresholds.

### Use aggregated datasets

Prefer data nodes with the `Groups` suffix over raw adaptive datasets. Aggregated data is pre-processed and less subject to sampling variability.

For example, use `httpRequestsAdaptiveGroups` instead of raw event data.

### Add explicit sorting

Always include `orderBy` in your queries to ensure consistent result ordering:

```graphql
orderBy: [datetime_ASC]
```

### Use confidence intervals

For adaptive datasets, request [confidence intervals](https://developers.cloudflare.com/analytics/graphql-api/features/confidence-intervals/) to understand data quality and verify sampling:

```graphql
confidence(level: 0.95) {
  count {
    estimate
    lower
    upper
    sampleSize
  }
}
```

A higher `sampleSize` indicates more reliable results.

## Quick reference

| Issue | Mitigation |
| --- | --- |
| Results vary between runs | Query shorter time ranges (daily or weekly instead of monthly) |
| Aggressive sampling on large queries | Break queries into smaller time intervals and aggregate client-side |
| Need consistent ordering | Add `orderBy` clause to all queries |
| Need to verify data quality | Request `confidence` intervals to check sample size and accuracy |
| Using raw adaptive data | Switch to aggregated datasets (nodes with `Groups` suffix) |

## Related resources

- [Understanding Sampling in Cloudflare Analytics](https://developers.cloudflare.com/analytics/sampling/)
- [GraphQL API Sampling](https://developers.cloudflare.com/analytics/graphql-api/sampling/)
- [Confidence Intervals](https://developers.cloudflare.com/analytics/graphql-api/features/confidence-intervals/)
- [GraphQL API Limits](https://developers.cloudflare.com/analytics/graphql-api/limits/)
- [Adaptive Bit Rate blog post ↗︎](https://blog.cloudflare.com/explaining-cloudflares-abr-analytics/)

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/faq/graphql-api-inconsistent-results/#page","headline":"GraphQL API inconsistent results","description":"Understand why GraphQL API results may vary slightly.","url":"https://developers.cloudflare.com/analytics/faq/graphql-api-inconsistent-results/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/faq/graphql-api-inconsistent-results/og.png?v=0f9f6fc2fbac7cde","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Additional frequently asked questions about analytics.
title: Other FAQs
image: https://developers.cloudflare.com/analytics/faq/other-faqs/og.png?v=cd096eeeaea6cdaf
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Other FAQs

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/faq/other-faqs/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

## Why do I see a large amount of traffic from CLOUDFLARENET ASN 13335 in Analytics? Does this indicate a DDoS attack?

There is a number of different types of traffic which may originate from **CLOUDFLARENET ASN 13335**; just because there is a lot of traffic from this AS, it likely does not indicate a DDoS attack.

Some sources of traffic from ASN13335 include:

- [Workers subrequests](https://developers.cloudflare.com/workers/runtime-apis/fetch/)
- [WARP](https://developers.cloudflare.com/warp-client/known-issues-and-faq/#does-warp-reveal-my-ip-address-to-websites-i-visit)
- [iCloud Private Relay ↗︎](https://blog.cloudflare.com/icloud-private-relay/) (For reference, iCloud Private Relay’s egress IP addresses are available in this [CSV form ↗︎](https://mask-api.icloud.com/egress-ip-ranges.csv))
- [Cloudflare Privacy Proxy ↗︎](https://blog.cloudflare.com/building-privacy-into-internet-standards-and-how-to-make-your-app-more-private-today/)
- Other Cloudflare features like [Health Checks](https://developers.cloudflare.com/health-checks/)

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/faq/other-faqs/#page","headline":"Other FAQs","description":"Additional frequently asked questions about analytics.","url":"https://developers.cloudflare.com/analytics/faq/other-faqs/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/faq/other-faqs/og.png?v=cd096eeeaea6cdaf","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Common questions about Workers Analytics Engine.
title: Workers Analytics Engine FAQs
image: https://developers.cloudflare.com/analytics/faq/wae-faqs/og.png?v=74097ee0a3e8f95d
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/analytics/llms.txt  
> Use this file to discover all available pages before exploring further.

# Workers Analytics Engine FAQs

Last updated Apr 23, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/analytics/faq/wae-faqs/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

Below you will find answers to our most commonly asked questions.

## Sampling

### Could I just use many unique index values to get better unique counts?

No, adding a large number of index values does not come without drawbacks. The tradeoff is that reading across many indices is slow.

In practice, due to how ABR works, reading from many indices in one query will result in low-resolution data – possibly unusably low.

On the other hand, if you pick a good index that aligns with how you read the data, your queries will run faster and you will get higher resolution results.

### What if I need to index on multiple values?

It is possible to concatenate multiple values in your index field. So if you want to index on user ID and hostname, you can write, for example `"$userID:$hostname"` into your index field.

Note that, based on your query pattern, it may make sense to write the same dataset with different indices. It is a common misconception that one should avoid "double-writing" data.

Thanks to sampling, the cost of writing data multiple times can be relatively low. However, reading data inefficiently can result in significant expenses or low-quality results due to sampling.

### How do I know if my data is sampled?

You can use the `_sample_interval` field — again, note that this does not tell you if the results are accurate.

You can tell when data is sampled at read time because sample intervals will be multiples of powers of 10, for example `20` or `700`. There is no hard and fast rule for when sampling starts at read time, but in practice reading longer periods (or more index values) will result in a higher sample interval.

### Why is data missing?

Sampling is based largely on the choice of index, as well as other factors like the time range queried and number of indices read. If you are reading from a larger index over a longer time period, and have filtered to a relatively small subgroup within that index, it may not be present due to sampling.

If you need to read accurate results for that subgroup, we suggest that you add that field to your index (refer to [What if I need to index on multiple values](https://developers.cloudflare.com/analytics/faq/wae-faqs/#what-if-i-need-to-index-on-multiple-values)).

### Can I trust sampled data? Are my results accurate?

Sampled data is highly reliable, particularly when a carefully selected index is used.

Admittedly, it is difficult at present to prove that the results returned by ABR queries are within a certain error bound. As a rule of thumb, it is good to check the number of rows read by using count() — think of this like the count of pixels in your image. A higher number of rows read will result in more accurate results. (The flipside is that the `_sample_interval` field does not tell you very much about whether your results are accurate). If you are extrapolating from only one or two rows, it is unlikely you have a representative result; if you are extrapolating from thousands of rows, it is very likely that your results are quite accurate.

In the near future, we plan to expose the [margin of error ↗︎](https://en.wikipedia.org/wiki/Margin_of_error) along with query results so that you can see precisely how accurate your results are.

### How are bursts handled?

Equitable sampling exists both to normalize differences between groups, and also to handle large spikes of traffic to a given index. Equalization happens every few seconds; if you are writing many events very close in time, then it is expected that they will be sampled at write time. The sample interval for a given index will vary from moment to moment, based on the current rate of data being written.

### How much traffic will trigger sampling?

There is no fixed rule determining when sampling will be triggered.

We have observed that for workloads like our global CDN, which distribute load around our network, each index value needs about 100 data points per second before sampling is noticeable at all.

Depending on your workload and how you use Workers Analytics Engine, sampling may start at a higher or lower threshold than this. For example, if you are writing out many data points from a single worker execution, it is more likely that your data will be sampled.

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/analytics/faq/wae-faqs/#page","headline":"Workers Analytics Engine FAQs","description":"Common questions about Workers Analytics Engine.","url":"https://developers.cloudflare.com/analytics/faq/wae-faqs/","inLanguage":"en","image":"https://developers.cloudflare.com/analytics/faq/wae-faqs/og.png?v=74097ee0a3e8f95d","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```
