Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
title: L4 transport telemetry fields now available in Rules
description: Use new fields to build rules based on QUIC RTT and connection delivery rate.
date: 2026-03-20
---

Three new fields are now available in the Ruleset Engine that expose layer 4 transport telemetry from the connection between the client and Cloudflare. These fields let you build rules that respond to connection quality and protocol type.

---

### New fields

| Field | Type | Description |
| --------------------------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| `cf.edge.client_quic` | Boolean | Indicates whether the request was made over QUIC (HTTP/3). |

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this one is planned but does not exist yet

| `cf.edge.l4.delivery_rate` | Integer | The most recent data delivery rate estimate for the client connection, in bytes per second. Returns `0` when L4 statistics are not available. |
| `cf.timings.client_quic_rtt_msec` | Integer | The smoothed QUIC round-trip time between the client and Cloudflare in milliseconds. Returns `0` for non-QUIC connections. |

### Example expressions

Serve different content based on connection quality:

```
cf.edge.l4.delivery_rate < 100000
```

Identify high-latency QUIC connections:

```
cf.edge.client_quic and cf.timings.client_quic_rtt_msec > 200
```

For more information, refer to the [Fields reference](/ruleset-engine/rules-language/fields/reference/).
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
title: L4 transport telemetry available in the request.cf object
description: New properties on request.cf expose connection delivery rate and QUIC RTT.
date: 2026-03-20
---

The `request.cf` object now includes layer 4 transport telemetry from the connection between the client and Cloudflare. Two new properties are available:

- **`edgeL4`** — An object containing transport statistics. Currently exposes `deliveryRate`, the most recent data delivery rate estimate for the connection in bytes per second.
- **`clientQuicRtt`** — The smoothed round-trip time for QUIC (HTTP/3) connections in milliseconds. Only present when the client connected over QUIC.

These properties let you make routing, caching, or content decisions based on connection quality. For example, you can serve lower-quality assets to clients on slow connections.

```js
export default {
async fetch(request) {
const deliveryRate = request.cf?.edgeL4?.deliveryRate ?? 0;
const quicRtt = request.cf?.clientQuicRtt;

if (deliveryRate > 0 && deliveryRate < 100_000) {
return fetch("https://example.com/low-bandwidth-page");
}

return fetch(request);
},
};
```

For more information, refer to the [`request.cf` properties documentation](/workers/runtime-apis/request/#incomingrequestcfproperties).
16 changes: 15 additions & 1 deletion src/content/docs/workers/runtime-apis/request.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,14 @@ All plans have access to:

* If Cloudflare replaces the value of the `Accept-Encoding` header, the original value is stored in the `clientAcceptEncoding` property, for example, `"gzip, deflate, br"`.

* `clientQuicRtt` number | undefined

* The smoothed round-trip time (RTT) between the client and Cloudflare for QUIC connections, in milliseconds. Only present when the client connected over QUIC (HTTP/3). For TCP connections this property is absent. For example, `42`.

* `clientTcpRtt` number | undefined

* The smoothed round-trip time (RTT) between the client and Cloudflare for TCP connections, in milliseconds. Only present when the client connected over TCP (HTTP/1 and HTTP/2). For example, `22`.

* `colo` string

* The three-letter [`IATA`](https://en.wikipedia.org/wiki/IATA_airport_code) airport code of the data center that the request hit, for example, `"DFW"`.
Expand All @@ -235,6 +243,12 @@ All plans have access to:

* Country of the incoming request. The two-letter country code in the request. This is the same value as that provided in the `CF-IPCountry` header, for example, `"US"`.

* `edgeL4` Object | undefined

* Layer 4 transport statistics for the connection between the client and Cloudflare. Contains the following property:
* `deliveryRate` number - The most recent data delivery rate estimate for the connection, in bytes per second. For example, `123456`.


* `isEUCountry` string | null

* If the country of the incoming request is in the EU, this will return `"1"`. Otherwise, this property is either omitted or `false`.
Expand Down Expand Up @@ -454,4 +468,4 @@ Incoming `Request` objects passed to the [`fetch()` handler](/workers/runtime-ap
* [Examples: Modify request property](/workers/examples/modify-request-property/)
* [Examples: Accessing the `cf` object](/workers/examples/accessing-the-cloudflare-object/)
* [Reference: `Response`](/workers/runtime-apis/response/)
* Write your Worker code in [ES modules syntax](/workers/reference/migrate-to-module-workers/) for an optimized experience.
* Write your Worker code in [ES modules syntax](/workers/reference/migrate-to-module-workers/) for an optimized experience.
41 changes: 41 additions & 0 deletions src/content/fields/index.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -804,7 +804,7 @@
description: |-
This field is only filled in if the request includes a client certificate for [mTLS authentication](/ssl/client-certificates/enable-mtls/).
example_value: |-
"Mar 21 13:35:00 2022 GMT"

Check warning on line 807 in src/content/fields/index.yaml

View workflow job for this annotation

GitHub Actions / Semgrep

semgrep.style-guide-potential-date-year

Potential year found. Documentation should strive to represent universal truth, not something time-bound. (add [skip style guide checks] to commit message to skip)

Check warning on line 807 in src/content/fields/index.yaml

View workflow job for this annotation

GitHub Actions / Semgrep

semgrep.style-guide-potential-date-month

Potential month found. Documentation should strive to represent universal truth, not something time-bound. (add [skip style guide checks] to commit message to skip)

- name: cf.tls_client_auth.cert_not_after
data_type: String
Expand All @@ -814,7 +814,7 @@
description: |-
This field is only filled in if the request includes a client certificate for [mTLS authentication](/ssl/client-certificates/enable-mtls/).
example_value: |-
"Mar 21 13:35:00 2023 GMT"

Check warning on line 817 in src/content/fields/index.yaml

View workflow job for this annotation

GitHub Actions / Semgrep

semgrep.style-guide-potential-date-year

Potential year found. Documentation should strive to represent universal truth, not something time-bound. (add [skip style guide checks] to commit message to skip)

Check warning on line 817 in src/content/fields/index.yaml

View workflow job for this annotation

GitHub Actions / Semgrep

semgrep.style-guide-potential-date-month

Potential month found. Documentation should strive to represent universal truth, not something time-bound. (add [skip style guide checks] to commit message to skip)

- name: cf.tls_client_auth.cert_ski
data_type: String
Expand All @@ -834,7 +834,7 @@
description: |-
This field is only filled in if the request includes a client certificate for [mTLS authentication](/ssl/client-certificates/enable-mtls/).
example_value: |-
"8204924CF49D471E855862706D889F58F6B784D3"

Check warning on line 837 in src/content/fields/index.yaml

View workflow job for this annotation

GitHub Actions / Semgrep

semgrep.style-guide-potential-date-year

Potential year found. Documentation should strive to represent universal truth, not something time-bound. (add [skip style guide checks] to commit message to skip)

- name: cf.tls_client_extensions_sha1
data_type: String
Expand Down Expand Up @@ -898,6 +898,32 @@
example_value: |-
true

- name: cf.edge.client_quic
data_type: Boolean
categories: [Request]
keywords: [request, quic, network, client, http3]
summary: Indicates if the request was made over QUIC.
example_value: |-
true

- name: cf.edge.l4.delivery_rate
data_type: Integer
categories: [Request]
keywords:
[request, l4, delivery rate, bandwidth, network, performance, transport]
summary: The most recent data delivery rate estimate for the client connection, in bytes per second.
description: |-
Reports the transport layer delivery rate estimate measured by Cloudflare for the connection between the client and Cloudflare, in bytes per second.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The final description in the field reference page will also include the summary as the first paragraph, so we may want to rephrase this description so that doesn't repeat what's in the summary.


This metric reflects the rate at which data is being successfully delivered over the connection. It can be used to build rules that respond to connection quality, such as serving lower-quality content to clients on slow connections.

Returns `0` when L4 statistics are not available for the request.
example_value: |-
123456
example_block: |-
# Match requests where the delivery rate is below 100 KB/s
cf.edge.l4.delivery_rate < 100000

- name: cf.timings.client_tcp_rtt_msec
data_type: Number
categories: [Request]
Expand All @@ -906,6 +932,21 @@
example_value: |-
20

- name: cf.timings.client_quic_rtt_msec
data_type: Integer
categories: [Request]
keywords: [request, timing, quic, rtt, performance, latency, http3]
summary: The smoothed QUIC round-trip time (RTT) from client to Cloudflare in milliseconds.
description: |-
Reports the smoothed round-trip time for the QUIC connection between the client and Cloudflare, in milliseconds.

This field is only populated for QUIC (HTTP/3) connections. For TCP connections, the value is `0`. Use [`cf.edge.client_quic`](/ruleset-engine/rules-language/fields/reference/cf.edge.client_quic/) to check if the connection used QUIC before evaluating this field.
example_value: |-
42
example_block: |-
# Match QUIC requests where the RTT exceeds 200 ms
cf.edge.client_quic and cf.timings.client_quic_rtt_msec > 200

- name: cf.timings.edge_msec
data_type: Integer
categories: [Request]
Expand Down Expand Up @@ -938,7 +979,7 @@
150
example_block: |-
# Matches requests where the origin response time (TTFB) was greater than 2 seconds:
cf.timings.origin_ttfb_msec > 2000

Check warning on line 982 in src/content/fields/index.yaml

View workflow job for this annotation

GitHub Actions / Semgrep

semgrep.style-guide-potential-date-year

Potential year found. Documentation should strive to represent universal truth, not something time-bound. (add [skip style guide checks] to commit message to skip)

- name: cf.timings.worker_msec
data_type: Integer
Expand Down Expand Up @@ -1072,7 +1113,7 @@
Requires a Cloudflare Enterprise plan with [malicious uploads detection](/waf/detections/malicious-uploads/).
example_block: |-
# Check if requests to a specific endpoint contain any content objects larger than 500 KB (512,000 bytes)
any(cf.waf.content_scan.obj_sizes[*] > 512000) and http.request.uri.path eq "/upload"

Check warning on line 1116 in src/content/fields/index.yaml

View workflow job for this annotation

GitHub Actions / Semgrep

semgrep.style-guide-potential-date-year

Potential year found. Documentation should strive to represent universal truth, not something time-bound. (add [skip style guide checks] to commit message to skip)

- name: cf.waf.content_scan.obj_types
data_type: Array<String>
Expand Down
Loading