--- title: "Cloudflare Server-Timing (Help Center / Settings / Server-timing)" ai_context: "Use this article for questions about Cloudflare Server-Timing, CDN performance diagnostics, cache behavior, edge processing, origin latency and Cloudflare Worker timing in RUMvision. It covers adding a dynamic `Server-Timing` response header with Cloudflare Response Header Transform Rules, recommended fields such as `cfCacheStatus`, `cfEdge`, `cfOrigin`, `cfWorker`, `cdn-pop` and `http_status_code`, and how RUMvision can automatically collect them when Cloudflare is configured in the tech stack. Relevant for questions about Cloudflare cache HIT/MISS/DYNAMIC/BYPASS/EXPIRED status, edge latency, origin TTFB, Worker execution time, PoP location, HTTP status codes, TTFB investigation, Transform Rules, DevTools validation, `PerformanceServerTiming`, Cloudflare APO, the `concat` limit, staging validation and avoiding overwriting existing origin `Server-Timing` headers." canonical: "https://www.rumvision.com/help-center/settings/server-timing/cloudflare/" --- Breadcrumbs: [Home](https://www.rumvision.com/?format=md) > [Help Center](https://www.rumvision.com/help-center/?format=md) > [Settings](https://www.rumvision.com/help-center/settings/?format=md) > [Server-timing](https://www.rumvision.com/help-center/settings/server-timing/?format=md) > Cloudflare # Cloudflare Server-Timing RUMvision can collect Cloudflare timing data when your website exposes it through the [`Server-Timing` response header](https://www.rumvision.com/help-center/monitoring/settings/custom-performance-timing/?format=md#server-timing). This helps you understand whether slow server response times are caused by Cloudflare edge processing, your origin server, or cache behavior. If your site is not exposing these headers yet, you can add them in Cloudflare with a [Response Header Transform Rule](https://developers.cloudflare.com/rules/transform/response-header-modification/). ## Add Server-Timing via Cloudflare ### Recommended fields Below are the recommended fields to expose. Once these fields are exposed and Cloudflare is selected as the CDN in your [tech stack settings](https://www.rumvision.com/help-center/monitoring/settings/domain-settings/?format=md#tech-stack) and enabled the Cloudflare checkbox, we will automatically collect them. However, as [Cloudflare offers more fields](http://developers.cloudflare.com/rules/transform/response-header-modification/reference/fields-functions/) you're free to add more and collect them individually. Value Type/source Meaning `cfCacheStatus` **Filter** [`CF-Cache-Status`](https://developers.cloudflare.com/cache/concepts/cache-responses/) Shows Cloudflare cache behavior For example `HIT`, `MISS`, `DYNAMIC`, `BYPASS`, or `EXPIRED`. `cfEdge` **Metric** [`cf.timings.edge_msec`](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/cf.timings.edge_msec/) Time spent processing the request inside Cloudflare’s global network. This does not include origin time or network transfer time to the visitor. `cfOrigin` **Metric** [`cf.timings.origin_ttfb_msec`](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/cf.timings.origin_ttfb_msec/) Origin TTFB from Cloudflare’s perspective. This includes the network round trip between Cloudflare and the origin, plus the time the origin spent handling the request. `cfWorker` **Metric** [`cf.timings.worker_msec`](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/cf.timings.worker_msec/) Measures how long a Cloudflare Worker spends handling the request. High values can delay the response and increase TTFB. `cdn-pop` **Filter** [`cf-ray`](https://developers.cloudflare.com/fundamentals/reference/http-headers/#cf-ray) Shows the Cloudflare colocation/PoP that handled the request, using a three-letter airport-style code such as AMS, FRA, LHR, or DFW. Useful for spotting regional differences in CDN behavior, latency, routing, or cache performance. `http_status_code` **Filter** [`http.response.code`](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/http.response.code/) The HTTP status code returned to the client, either set by a Cloudflare product or returned by the origin server. For example 200 if a page was found or 404 when a page does not exist. ### Where to implement When logged into Cloudflare, you can [follow this direct link](https://dash.cloudflare.com/?to=/:account/:zone/rules/transform-rules/modify-response-header/new) to end up at the right configuration page. Alternatively, follow the steps below to configure this for a specific website: - `Go to Rules -> Overview` - `Click "Create Rule" ` - `select "Response Header Transform Rules" in the dropdown` See this [screenshot for visual support](https://www.rumvision.com/file/upload/img/help-center/server-timing/cloudflare-rules-overview-create-rule.png) as to where to find these steps. A new page with a form will appear. ### Rule to implement On that form, fill in the following information: - **Rule name (required)** Server-Timing for RUM - **If incoming requests match…** select "All incoming requests" (2nd select box) Then, add the following response header: Setting Value Operation `Set dynamic` Header name `Server-Timing` Header value ``` concat( "cfCacheStatus;desc=", http.response.headers["cf-cache-status"][0], ",cfEdge;dur=", to_string(cf.timings.edge_msec), ",cfOrigin;dur=", to_string(cf.timings.origin_ttfb_msec), ",cfWorker;dur=", to_string(cf.timings.worker_msec), ",cdn-pop;desc=", substring(cf.ray_id, -3), ",http_status_code;desc=", to_string(http.response.code) ) ``` You can also add other headers like [`Cf-Apo-Via`](https://developers.cloudflare.com/automatic-platform-optimization/get-started/verify-apo-works/) when using Cloudflare's APO solution. > Do note that the `concat` function accepts a maximum of 16 arguments. Don't forget to add this rule by clicking the blue "Deploy" button. If you're not using [Cloudflare workers](https://developers.cloudflare.com/workers/), you can omit that line from the list before pasting it into your Cloudflare HTTP Response Header Value form field. See the following screenshot for a visual representation of these steps: [![cloudflare-rules-create-new-response-header.png](https://www.rumvision.com/file/upload/img/help-center/server-timing/cloudflare-rules-create-new-response-header.png)](https://www.rumvision.com/file/upload/img/help-center/server-timing/cloudflare-rules-create-new-response-header.png) Once created, you should see it listed in your Rules Overview, as [illustrated in this example screenshot](https://www.rumvision.com/file/upload/img/help-center/server-timing/cloudflare-rules-overview.png). ## Testing the outcome Next step is testing the outcome. You could either wait for data to arrive in your RUMvision dashboard, or proactively test the outcome using the DevTools of your preferred browser. ### Expected outcome After deploying the rule, your HTML document should return a `Server-Timing` header similar to this: ``` Server-Timing: cfCacheStatus;desc=MISS, cfEdge;dur=12, cfOrigin;dur=248 ``` For a cached response, `cfOrigin` may be `0`, because Cloudflare did not need to contact the origin server. ``` Server-Timing: cfCacheStatus;desc=HIT, cfEdge;dur=8, cfOrigin;dur=0 ``` ### Check the response headers To verify the setup: 1. Open your website in Chrome or Edge. 2. Open DevTools. 3. Go to the Network tab. 4. Reload the page. 5. Click the main HTML document request. 6. Check the [Response Headers section](https://developer.chrome.com/docs/devtools/network#search). 7. Look for `server-timing`. [![cloudflare-server-timing-network-panel-response-header.png](https://www.rumvision.com/file/upload/img/help-center/server-timing/cloudflare-server-timing-network-panel-response-header.png)](https://www.rumvision.com/file/upload/img/help-center/server-timing/cloudflare-server-timing-network-panel-response-header.png) ### Test in DevTools Console As the browser exposes `Server-Timing` values through the [`PerformanceServerTiming` interface](https://developer.mozilla.org/en-US/docs/Web/API/PerformanceServerTiming), you can also test it in the [browser console by running the following JavaScript](https://developer.chrome.com/docs/devtools/console#javascript): ``` const navEntries = window.performance.getEntriesByType('navigation'); console.table( navEntries[0].serverTiming ); ``` > You can [save snippets like these directly in DevTools](https://developer.chrome.com/docs/devtools/javascript/snippets#create) (under the Sources panel) to easily reuse them later. After running this in your DevTools Console, you should see a table similar to the one below: [![cloudflare-server-timing-js-console.png](https://www.rumvision.com/file/upload/img/help-center/server-timing/cloudflare-server-timing-js-console.png)](https://www.rumvision.com/file/upload/img/help-center/server-timing/cloudflare-server-timing-js-console.png) ## Important In general, be sure to: - Always test on staging environment before deploying these steps to a production environment. - Avoid exposing sensitive internal details. `Server-Timing` data is visible in the browser, so only expose metrics that are safe to share with visitors and third-party scripts. ### Cloudflare notes If your origin already sends a `Server-Timing` header, using Cloudflare’s `Set dynamic` operation may overwrite it. In that case, either combine the values at your origin or configure Cloudflare carefully so you do not remove useful existing metrics.