Skip to content

Metrics and analytics

D1 exposes database analytics that allow you to inspect query volume, query latency, and storage size across all and/or each database in your account.

The metrics displayed in the Cloudflare dashboard โ†— charts are queried from Cloudflareโ€™s GraphQL Analytics API. You can access the metrics programmatically via GraphQL or HTTP client.

Metrics

D1 currently exports the below metrics:

MetricGraphQL Field NameDescription
Read Queries (qps)readQueriesThe number of read queries issued against a database. This is the raw number of read queries, and is not used for billing.
Write Queries (qps)writeQueriesThe number of write queries issued against a database. This is the raw number of write queries, and is not used for billing.
Rows read (count)rowsReadThe number of rows read (scanned) across your queries. See Pricing for more details on how rows are counted.
Rows written (count)rowsWrittenThe number of rows written across your queries.
Query Response (bytes)queryBatchResponseBytesThe total response size of the serialized query response, including any/all column names, rows and metadata. Reported in bytes.
Query Latency (ms)queryBatchTimeMsThe total query response time, including response serialization, on the server-side. Reported in milliseconds.
Storage (Bytes)databaseSizeBytesMaximum size of a database. Reported in bytes.

Metrics can be queried (and are retained) for the past 31 days.

Row counts

D1 returns the number of rows read, rows written (or both) in response to each individual query via the Workers Binding API.

Row counts are a precise count of how many rows were read (scanned) or written by that query. Inspect row counts to understand the performance and cost of a given query, including whether you can reduce the rows read using indexes. Use query counts to understand the total volume of traffic against your databases and to discern which databases are actively in-use.

Refer to the Pricing documentation for more details on how rows are counted.

View metrics in the dashboard

Per-database analytics for D1 are available in the Cloudflare dashboard. To view current and historical metrics for a database:

  1. Log in to the Cloudflare dashboard โ†— and select your account.
  2. Go to Workers & Pages > D1 โ†—.
  3. Select an existing database.
  4. Select the Metrics tab.

You can optionally select a time window to query. This defaults to the last 24 hours.

Query via the GraphQL API

You can programmatically query analytics for your D1 databases via the GraphQL Analytics API. This API queries the same datasets as the Cloudflare dashboard, and supports GraphQL introspection.

D1's GraphQL datasets require an accountTag filter with your Cloudflare account ID and include:

  • d1AnalyticsAdaptiveGroups
  • d1StorageAdaptiveGroups
  • d1QueriesAdaptiveGroups

Examples

To query the sum of readQueries, writeQueries for a given $databaseId, grouping by databaseId and date:

query {
viewer {
accounts(filter: { accountTag: $accountId }) {
d1AnalyticsAdaptiveGroups(
limit: 10000
filter: {
date_geq: $startDate
date_leq: $endDate
databaseId: $databaseId
}
orderBy: [date_DESC]
) {
sum {
readQueries
writeQueries
}
dimensions {
date
databaseId
}
}
}
}
}

To query both the average queryBatchTimeMs and the 90th percentile queryBatchTimeMs per database:

query {
viewer {
accounts(filter: { accountTag: $accountId }) {
d1AnalyticsAdaptiveGroups(
limit: 10000
filter: {
date_geq: $startDate
date_leq: $endDate
databaseId: $databaseId
}
orderBy: [date_DESC]
) {
quantiles {
queryBatchTimeMsP90
}
dimensions {
date
databaseId
}
}
}
}
}

To query your account-wide readQueries and writeQueries:

query {
viewer {
accounts(filter: { accountTag: $accountId }) {
d1AnalyticsAdaptiveGroups(
limit: 10000
filter: {
date_geq: $startDate
date_leq: $endDate
databaseId: $databaseId
}
) {
sum {
readQueries
writeQueries
}
}
}
}
}

Query insights

D1 provides metrics that let you understand and debug query performance. You can access these via GraphQL's d1QueriesAdaptiveGroups or wrangler d1 insights command.

D1 captures your query strings to make it easier to analyze metrics across query executions. Bound parameters are not captured to remove any sensitive information.

OptionDescription
--timePeriodFetch data from now to the provided time period (default: 1d).
--sort-typeThe operation you want to sort insights by. Select between sum and avg (default: sum).
--sort-byThe field you want to sort insights by. Select between time, reads, writes, and count (default: time).
--sort-directionThe sort direction. Select between ASC and DESC (default: DESC).
--jsonA boolean value to specify whether to return the result as clean JSON (default: false).
--limitThe maximum number of queries to be fetched.

To find top 3 queries by execution count:

Terminal window
npx wrangler d1 insights <database_name> --sort-type=sum --sort-by=count --limit=3
โ›…๏ธ wrangler 3.95.0
-------------------
-------------------
๐Ÿšง `wrangler d1 insights` is an experimental command.
๐Ÿšง Flags for this command, their descriptions, and output may change between wrangler versions.
-------------------
[
{
"query": "SELECT tbl_name as name,\n (SELECT ncol FROM pragma_table_list(tbl_name)) as num_columns\n FROM sqlite_master\n WHERE TYPE = \"table\"\n AND tbl_name NOT LIKE \"sqlite_%\"\n AND tbl_name NOT LIKE \"d1_%\"\n AND tbl_name NOT LIKE \"_cf_%\"\n ORDER BY tbl_name ASC;",
"avgRowsRead": 2,
"totalRowsRead": 4,
"avgRowsWritten": 0,
"totalRowsWritten": 0,
"avgDurationMs": 0.49505,
"totalDurationMs": 0.9901,
"numberOfTimesRun": 2,
"queryEfficiency": 0
},
{
"query": "SELECT * FROM Customers",
"avgRowsRead": 4,
"totalRowsRead": 4,
"avgRowsWritten": 0,
"totalRowsWritten": 0,
"avgDurationMs": 0.1873,
"totalDurationMs": 0.1873,
"numberOfTimesRun": 1,
"queryEfficiency": 1
},
{
"query": "SELECT * From Customers",
"avgRowsRead": 0,
"totalRowsRead": 0,
"avgRowsWritten": 0,
"totalRowsWritten": 0,
"avgDurationMs": 1.0225,
"totalDurationMs": 1.0225,
"numberOfTimesRun": 1,
"queryEfficiency": 0
}
]

To find top 3 queries by average execution time:

Terminal window
npx wrangler d1 insights <database_name> --sort-type=avg --sort-by=time --limit=3
โ›…๏ธ wrangler 3.95.0
-------------------
-------------------
๐Ÿšง `wrangler d1 insights` is an experimental command.
๐Ÿšง Flags for this command, their descriptions, and output may change between wrangler versions.
-------------------
[
{
"query": "SELECT * From Customers",
"avgRowsRead": 0,
"totalRowsRead": 0,
"avgRowsWritten": 0,
"totalRowsWritten": 0,
"avgDurationMs": 1.0225,
"totalDurationMs": 1.0225,
"numberOfTimesRun": 1,
"queryEfficiency": 0
},
{
"query": "SELECT tbl_name as name,\n (SELECT ncol FROM pragma_table_list(tbl_name)) as num_columns\n FROM sqlite_master\n WHERE TYPE = \"table\"\n AND tbl_name NOT LIKE \"sqlite_%\"\n AND tbl_name NOT LIKE \"d1_%\"\n AND tbl_name NOT LIKE \"_cf_%\"\n ORDER BY tbl_name ASC;",
"avgRowsRead": 2,
"totalRowsRead": 4,
"avgRowsWritten": 0,
"totalRowsWritten": 0,
"avgDurationMs": 0.49505,
"totalDurationMs": 0.9901,
"numberOfTimesRun": 2,
"queryEfficiency": 0
},
{
"query": "SELECT * FROM Customers",
"avgRowsRead": 4,
"totalRowsRead": 4,
"avgRowsWritten": 0,
"totalRowsWritten": 0,
"avgDurationMs": 0.1873,
"totalDurationMs": 0.1873,
"numberOfTimesRun": 1,
"queryEfficiency": 1
}
]

To find top 10 queries by rows written in last 7 days:

Terminal window
npx wrangler d1 insights <database_name> --sort-type=sum --sort-by=writes --limit=10 --timePeriod=7d
โ›…๏ธ wrangler 3.95.0
-------------------
-------------------
๐Ÿšง `wrangler d1 insights` is an experimental command.
๐Ÿšง Flags for this command, their descriptions, and output may change between wrangler versions.
-------------------
[
{
"query": "SELECT * FROM Customers",
"avgRowsRead": 4,
"totalRowsRead": 4,
"avgRowsWritten": 0,
"totalRowsWritten": 0,
"avgDurationMs": 0.1873,
"totalDurationMs": 0.1873,
"numberOfTimesRun": 1,
"queryEfficiency": 1
},
{
"query": "SELECT * From Customers",
"avgRowsRead": 0,
"totalRowsRead": 0,
"avgRowsWritten": 0,
"totalRowsWritten": 0,
"avgDurationMs": 1.0225,
"totalDurationMs": 1.0225,
"numberOfTimesRun": 1,
"queryEfficiency": 0
},
{
"query": "SELECT tbl_name as name,\n (SELECT ncol FROM pragma_table_list(tbl_name)) as num_columns\n FROM sqlite_master\n WHERE TYPE = \"table\"\n AND tbl_name NOT LIKE \"sqlite_%\"\n AND tbl_name NOT LIKE \"d1_%\"\n AND tbl_name NOT LIKE \"_cf_%\"\n ORDER BY tbl_name ASC;",
"avgRowsRead": 2,
"totalRowsRead": 4,
"avgRowsWritten": 0,
"totalRowsWritten": 0,
"avgDurationMs": 0.49505,
"totalDurationMs": 0.9901,
"numberOfTimesRun": 2,
"queryEfficiency": 0
}
]