# Benchmark report: is the site faster on Cloudflare than it was on Vercel?

Run 2026-10-16 from one Mac in Kenya. Rule fixed in `PREREGISTRATION.md` before any measurement. Same code on both hosts: Cloudflare = https://kaikhalid.com (static export), Vercel = a Vercel deployment of the same code (plain `next build`; hostname withheld). The Vercel copy is today's code, not the pre-move code.

## Verdict by the pre-registered rule: PARTIALLY SUPPORTED

Faster on Cloudflare: connection setup, time to first byte, and mobile load (simulated 4G) from Kenya. Not faster on the simulated desktop profile, where Vercel led LCP by about 77 ms. The pre-registered ACCEPT bar (Cloudflare better by more than 100 ms in at least 3 of 4 LCP cells) was met in 2 of 4.

## P1: HTML time to first byte, fresh connection, DNS excluded (100 interleaved pairs per page, two rounds an hour apart)

| Round | Page | Vercel median / p95 | Cloudflare median / p95 | median(V-C), 95% CI | CF faster in |
|---|---|---|---|---|---|
| 1 | home | 325 / 561 ms | 56 / 149 ms | 262 [255, 271] | 97% of pairs |
| 1 | post | 328 / 550 | 59 / 183 | 262 [255, 269] | 99% |
| 2 | home | 303 / 459 | 47 / 227 | 248 [229, 254] | 96% |
| 2 | post | 302 / 521 | 50 / 278 | 246 [230, 256] | 95% |

Where the gap comes from (round 1 home medians): TCP connect equal at about 10 ms; TLS handshake 200 ms vs 21 ms; server wait after TLS 111 ms vs 24 ms. Vercel's edge is farther from Kenya (its response header names Cape Town, `cpt1`). Cloudflare answered from Nairobi (`NBO`). Both have a rare 1 s tail from network loss on this Mac. The wallpaper file behaves the same (321 vs 56 ms). All 1,200 requests returned 200 with a cache HIT on both hosts.

## P2: Lighthouse 13.5.0, simulated throttling, 10 runs per cell, hosts interleaved

| Cell | Vercel LCP median | Cloudflare LCP median | median(V-C) [95% CI] | Score V / C |
|---|---|---|---|---|
| home mobile | 2954 ms | 2280 | +675 [142, 735] | 88.5 / 98 |
| post mobile | 3094 | 2563 | +531 [156, 683] | 88 / 97 |
| home desktop | 529 | 607 | -79 [-152, -60] | 100 / 100 |
| post desktop | 519 | 595 | -77 [-148, -47] | 100 / 100 |

Server response (Lighthouse audit) was about 20 ms on Cloudflare and 90 ms on Vercel in all four cells.

## Exploratory (not part of the rule)

- **Control (A/A).** My first Lighthouse script had a bug that sent both labels to Cloudflare. I kept those 80 runs as a same-host control. Noise floor for the median LCP difference: about +/-70 ms on desktop, +/-400 ms on mobile. Vercel's 77-79 ms desktop lead is barely outside that.
- **Beacon blocked.** Cloudflare injects its Web Analytics beacon (`static.cloudflareinsights.com/beacon.min.js`, 10.4 KB, 4 extra requests) into HTML served to browsers. Blocking it in Lighthouse did not close the desktop gap (Vercel still led by 56 to 98 ms), so the beacon does not explain it. The desktop lead is unexplained.
- **No simulated throttling** (`--throttling-method=provided`, what this Mac's real network delivered): desktop LCP home 676 ms Vercel vs 361 Cloudflare, post 810 vs 371. The home gap is significant (CI [163, 509]); the post gap is not (one slow Cloudflare run, CI [-207, 564]). Mobile runs under this method split into early (about 0.2 to 0.6 s) and late (about 2.55 s) LCP modes, and Vercel landed in the late mode in 6 of 10 runs on both pages against 1 and 3 of 10 for Cloudflare. I treat the mobile figures as direction only.
- **Other countries** (public checker, 34 nodes, 3 cold requests each, median): Cloudflare faster in 23 nodes, Vercel in 11, median difference 49 ms in Cloudflare's favour. Vercel was faster in parts of western Europe (for example Germany 49 vs 154 ms) and Hong Kong; Cloudflare was far ahead in Israel, UK, Spain, Japan and India. Single cold requests from data-centre servers are rough.

## What this does not show

- One network and one location. The large gap is partly geography: Vercel's nearest edge to Kenya is Cape Town, Cloudflare's is Nairobi. Elsewhere the gap shrinks or reverses.
- The pre-move Vercel build used `/_next/image`; the Vercel copy tested here uses the build-time WebP images. The 2026-10-15 baseline (3 runs, kaikhalid.com on Vercel) agrees in direction (server response 80 vs 44 to 58 ms) and is not part of the statistics.
- Lighthouse's simulated desktop profile and the unthrottled run disagree on desktop; I have not pinned down why.
- Cache state after long idle, load, and cost were not tested. The Vercel copy is on a different hostname from the former custom domain, so DNS differs; the timings exclude DNS.
- No data from Safari, Firefox or real visitors.

## Note on the Cloudflare Web Analytics beacon

Cloudflare injected its Web Analytics beacon into browser-served HTML during these runs, and `curl` does not see it. The injection was switched off later the same day. Every Cloudflare number above was measured with the beacon present, so Cloudflare's mobile LCP lead may grow slightly now (the beacon-blocked run showed no change on desktop).
