Why TTFB still deserves attention
Time to First Byte (TTFB) measures the interval between a client sending a request and receiving the first byte of the response. While it’s often dismissed as a poor indicator of user experience—especially compared with Web Vitals like LCP—there are two scenarios where it becomes indispensable:
- Non-browser clients: Over half of Cloudflare’s traffic is API calls. When you don’t control the calling environment, TTFB may be the only metric you can monitor or improve.
- Root-cause analysis: Even for websites, a slow TTFB can be the underlying reason for poor LCP. When that happens, you need to know why TTFB is slow.
That’s where Timing Insights comes in—a new set of performance metrics available through the GraphQL Analytics API. It provides server-side visibility into what contributes to TTFB, helping you identify and address bottlenecks.
What Timing Insights measures
Customers on Pro, Business, and Enterprise plans can query three new fields in the httpRequestsAdaptiveGroups dataset:
edgeTimeToFirstByteMs— time from when Cloudflare starts processing the first byte of the request to when it begins sending a response.edgeDnsResponseTimeMs— time taken by Cloudflare to resolve a CNAME to reach your origin.originResponseDurationMs— time to reach and receive a response from your origin.
Each metric is exposed as average, median (P50), 95th (P95), and 99th (P99) percentiles. Because this dataset underpins the Traffic analytics page in the dashboard, you can filter and group by any HTTP request attribute.
Pinpointing slow requests
To see how this works in practice, consider a typical diagnostic flow. Start by querying overall TTFB percentiles to gauge the scale of the problem:
query TTFBQuantiles($zoneTag: string) {
viewer {
zones(filter: {zoneTag: $zoneTag}) {
httpRequestsAdaptiveGroups(limit: 1) {
quantiles {
edgeTimeToFirstByteMsP50
edgeTimeToFirstByteMsP95
edgeTimeToFirstByteMsP99
}
}
}
}
}
Response:
{
"data": {
"viewer": {
"zones": [
{
"httpRequestsAdaptiveGroups": [
{
"quantiles": {
"edgeTimeToFirstByteMsP50": 32,
"edgeTimeToFirstByteMsP95": 1392,
"edgeTimeToFirstByteMsP99": 3063,
}
}
]
}
]
}
}
}
If P95 TTFB exceeds 1.3 seconds—a significant share of the 2.5-second LCP budget—you’ll want to drill down. The next step is identifying which URLs contribute most to the slowest 5% of loads:
query slowestURLs($zoneTag: string, $filter:filter) {
viewer {
zones(filter: {zoneTag: $zoneTag}) {
httpRequestsAdaptiveGroups(limit: 3, filter: {edgeTimeToFirstByteMs_gt: 1392}, orderBy: [sum_edgeTimeToFirstByteMs_DESC]) {
sum {
edgeTimeToFirstByteMs
}
dimensions {
clientRequestPath
}
}
}
}
}
Response:
{
"data": {
"viewer": {
"zones": [
{
"httpRequestsAdaptiveGroups": [
{
"dimensions": {
"clientRequestPath": "/api/v2"
},
"sum": {
"edgeTimeToFirstByteMs": 1655952
}
},
{
"dimensions": {
"clientRequestPath": "/blog"
},
"sum": {
"edgeTimeToFirstByteMs": 167397
}
},
{
"dimensions": {
"clientRequestPath": "/"
},
"sum": {
"edgeTimeToFirstByteMs": 118542
}
}
]
}
]
}
}
}
Suppose /api/v2 appears most frequently. To determine whether the issue is DNS resolution or origin response time, query the average DNS and origin durations for those paths where TTFB is above the P95 threshold:
query originAndDnsTiming($zoneTag: string, $filter:filter) {
viewer {
zones(filter: {zoneTag: $zoneTag}) {
httpRequestsAdaptiveGroups(filter: {edgeTimeToFirstByteMs_gt: 1392, clientRequestPath_in: [$paths]}) {
avg {
originResponseDurationMs
edgeDnsResponseTimeMs
}
}
}
}
Response:
{
"data": {
"viewer": {
"zones": [
{
"httpRequestsAdaptiveGroups": [
{
"average": {
"originResponseDurationMs": 4955,
"edgeDnsResponseTimeMs": 742,
}
}
]
}
]
}
}
}
In this case, DNS resolution dominates the slow TTFB. That’s actionable: adjusting TTL settings at your DNS provider can directly reduce the delay.
What’s next
Timing Insights will soon be integrated into Cloudflare Observatory in the dashboard, allowing UI-based exploration of these metrics. Future plans include finer-grained breakdowns—separating origin connection time (TCP/TLS establishment) from application response time (HTTP server processing)—and more flexible GraphQL queries, such as support for arbitrary percentiles beyond P50, P95, and P99.
Developers can already begin using these metrics through the GraphQL API or join the discussion on Discord.



