R2 exposes analytics for requests, storage, and bandwidth usage across your buckets.
The metrics displayed for a bucket in the Cloudflare dashboard ↗︎ are queried from Cloudflare's GraphQL Analytics API. You can access the metrics programmatically via GraphQL or HTTP client.
R2 has three datasets:
| Dataset | GraphQL Dataset Name | Description |
|---|---|---|
| Operations | r2OperationsAdaptiveGroups |
This dataset consists of the operations taken on a bucket within an account. |
| Storage | r2StorageAdaptiveGroups |
This dataset consists of the storage of a bucket within an account. |
| Bandwidth | r2BandwidthUsageAdaptiveGroups |
Dataset contains uploaded and downloaded bytes for buckets within an account. |
Metrics can be queried for a maximum range of 31 days. These datasets require an accountTag filter with your Cloudflare account ID.
| Field | Description |
|---|---|
| actionType | The name of the operation performed. |
| actionStatus | The status of the operation. Can be success, userError, or internalError. |
| bucketName | The bucket this operation was performed on if applicable. For buckets with a jurisdiction specified, you must include the jurisdiction followed by an underscore before the bucket name. For example: eu_your-bucket-name |
| objectName | The object this operation was performed on if applicable. |
| responseStatusCode | The http status code returned by this operation. |
| datetime | The time of the request. |
| Field | Description |
|---|---|
| bucketName | The bucket this storage value is for. For buckets with a jurisdiction specified, you must include the jurisdiction ↗︎ followed by an underscore before the bucket name. For example: eu_your-bucket-name |
| payloadSize | The size of the objects in the bucket. |
| metadataSize | The size of the metadata of the objects in the bucket. |
| objectCount | The number of objects in the bucket. |
| uploadCount | The number of pending multipart uploads in the bucket. |
| datetime | The time that this storage value represents. |
The dataset excludes bandwidth transfers smaller than 100 KiB. This threshold applies to transfer size, not object size.
You can filter by the following fields:
| Field | Description |
|---|---|
bucketName |
The R2 bucket identifier, including the jurisdiction prefix if applicable. |
date |
The transfer timestamp truncated to the start of the day. |
datetimeHour |
The transfer timestamp truncated to the start of the hour. |
datetimeFifteenMinutes |
The transfer timestamp rounded down to the nearest quarter hour. |
datetimeFiveMinutes |
The transfer timestamp truncated to the start of the five-minute interval. |
datetimeMinute |
The transfer timestamp truncated to the start of the minute. |
datetime |
The raw transfer timestamp. |
The following fields can be summed:
| Field | Description |
|---|---|
bytesDownload |
Downloaded bytes. |
bytesUpload |
Uploaded bytes. |
Per-bucket analytics for R2 are available in the Cloudflare dashboard. To view current and historical metrics for a bucket:
-
In the Cloudflare dashboard, go to the R2 object storage page.
Go to Overview ↗ -
Select your bucket.
-
Select the Metrics tab.
You can optionally select a time window to query. This defaults to the last 24 hours.
You can programmatically query analytics for your R2 buckets via the GraphQL Analytics API. This API queries the same dataset as the Cloudflare dashboard, and supports GraphQL introspection.
To query the volume of each operation type on a bucket for a given time period you can run a query as such
query R2VolumeExample(
$accountTag: string!
$startDate: Time
$endDate: Time
$bucketName: string
) {
viewer {
accounts(filter: { accountTag: $accountTag }) {
r2OperationsAdaptiveGroups(
limit: 10000
filter: {
datetime_geq: $startDate
datetime_leq: $endDate
bucketName: $bucketName
}
) {
sum {
requests
}
dimensions {
actionType
}
}
}
}
}The bucketName field can be removed to get an account level overview of operations. The volume of operations can be broken down even further by adding more dimensions to the query.
To query the storage of a bucket over a given time period you can run a query as such.
query R2StorageExample(
$accountTag: string!
$startDate: Time
$endDate: Time
$bucketName: string
) {
viewer {
accounts(filter: { accountTag: $accountTag }) {
r2StorageAdaptiveGroups(
limit: 10000
filter: {
datetime_geq: $startDate
datetime_leq: $endDate
bucketName: $bucketName
}
orderBy: [datetime_DESC]
) {
max {
objectCount
uploadCount
payloadSize
metadataSize
}
dimensions {
datetime
}
}
}
}
}To query hourly uploads and downloads for a bucket. Results contain byte totals, not transfer rates, and excluded transfers smaller than 100 KiB.
query R2BandwidthExample(
$accountTag: string!
$startDate: Time!
$endDate: Time!
$bucketName: string!
) {
viewer {
accounts(filter: { accountTag: $accountTag }) {
r2BandwidthUsageAdaptiveGroups(
limit: 1000
filter: {
datetime_geq: $startDate
datetime_lt: $endDate
bucketName: $bucketName
}
orderBy: [datetimeHour_ASC]
) {
sum {
bytesUpload
bytesDownload
}
dimensions {
datetimeHour
}
}
}
}
}