Cloudflare's Free plan serves Mexico from Dallas: I measured it from 20 probes
Table of Contents
On October 4, 2026 I tested a domain on Cloudflare’s Free plan from 20 probes in Mexico. All 19 that answered were served from Dallas (DFW), with a median TCP connect time of 32 ms. The same zone, pinned to a different Cloudflare IP, was served from Querétaro 13 times, with a median of 7 ms.
This isn’t a misconfiguration or a fluke. Cloudflare says in writing that when a data center runs short on capacity, Free customers are the first to be moved elsewhere. What rarely gets said is that in Mexico you can see it, and you can check it yourself in two minutes. If you have users in Mexico, or you build for clients who do, here’s how to measure it, why it happens, what it costs in milliseconds and when it’s worth caring about.
What I measured
I used Globalping, jsDelivr’s public probe network, on Sunday, October 4, 2026 at 23:55 UTC (17:55 in Mexico City). I asked for 20 probes in Mexico and sent each one a HEAD /cdn-cgi/trace against a test domain on the Free plan. The probes landed in Querétaro (10), Mexico City (5), Morelia (2), and one each in Puebla, Guadalajara and Ciudad Juárez.
Then I ran exactly the same test again, but forced the probes to connect to a different Cloudflare IP, 104.18.12.15, from a range that is announced from Mexico. Same zone, same certificate, same content. The only thing that changes is which address the client connects to.
| Test (Oct 4, 2026, 20 probes in Mexico) | Colo that answered | Median TCP connect | Range |
|---|---|---|---|
| Free zone, normal DNS | DFW (Dallas), 19 of 19 (1 probe failed) | 32 ms | 24–39 ms |
Same zone, pinned to 104.18.12.15 | QRO (Querétaro) 13, DFW 7 | 7 ms | 1–36 ms |
It wasn’t a one-off. On September 22 I ran the same test against a Free domain from 19 probes and got the same answer: 19 of 19 through Dallas. That time, pinning the zone to an IP in that range got an answer from MEX, Mexico City. Two weeks apart, same result.
A caveat on the numbers: almost all of Globalping’s probes in Mexico sit in data centers (many in Querétaro, which hosts several cloud regions), and the only residential network with probes I found was Telmex. A data center in Querétaro is better connected than your customer’s home line, so treat these figures as the best case, not the typical one.
How to see which city Cloudflare serves you from
Cloudflare tells you on every response; you just need to know where to look.
The quick way, from your terminal. Any domain behind Cloudflare answers on /cdn-cgi/trace:
curl -s https://your-domain.com/cdn-cgi/trace | grep colo
# colo=DFW
colo is the airport code (IATA) of the data center that answered: DFW is Dallas, QRO Querétaro, MEX Mexico City. The same code is the suffix of the cf-ray header on any response:
curl -sI https://your-domain.com/ | grep -i cf-ray
# cf-ray: 9a1b2c3d4e5f6789-DFW
That tells you where you are being served from, on your connection. To know what your visitors elsewhere get, you have to measure from there.
The thorough way, with Globalping. The API is public and needs no sign-up (without a key you get 250 tests an hour, and each probe counts as one). This asks for 20 probes in Mexico:
curl -s -X POST https://api.globalping.io/v1/measurements \
-H 'Content-Type: application/json' \
-d '{
"type": "http",
"target": "your-domain.com",
"locations": [{ "country": "MX", "limit": 20 }],
"measurementOptions": {
"protocol": "HTTPS",
"request": { "method": "HEAD", "path": "/cdn-cgi/trace" }
}
}'
# {"id":"<id>","probesCount":20}
You get an id back. Give it a few seconds and fetch the result; jq pulls out each probe’s city, the colo that served it and the TCP connect time:
curl -s https://api.globalping.io/v1/measurements/<id> \
| jq -r '.results[] | [.probe.city, (.result.headers["cf-ray"] // "failed"), .result.timings.tcp] | @tsv'
# Queretaro 9a1b2c3d4e5f6789-DFW 31
# Mexico City 9a1b2c3d4e5f6790-DFW 33
# ...
If status still says in-progress, ask again. Swap "country": "MX" for whatever market you care about; it also takes cities ({"city": "Monterrey"}) or networks ({"asn": 8151} is Telmex).
How to read tcp: it’s roughly one round trip. From Mexico, under 10 ms means a local node; around 30 ms means Dallas.
The test that explains it: pin a different IP
This is the interesting part. Cloudflare doesn’t pick the data center by distance to the visitor. To a large extent it’s decided by the IP your domain resolves to. Cloudflare uses anycast: the same address is announced from many data centers, and the internet routes each visitor to the nearest one that announces that address. If the range your zone was given isn’t announced from Mexico, a Mexican visitor ends up at the nearest place that does announce it, which in my tests was Dallas.
You can check this without touching your DNS. First, see what your domain resolves to:
dig +short your-domain.com
Then compare the colo on normal DNS against the same domain pinned to an IP in the 104.18.x range:
curl -s https://your-domain.com/cdn-cgi/trace | grep colo
# colo=DFW
curl -s --resolve your-domain.com:443:104.18.12.15 \
https://your-domain.com/cdn-cgi/trace | grep colo
# colo=QRO
--resolve tells curl “for this hostname, connect to this IP” and changes nothing else: the certificate and content are still your zone’s, because Cloudflare routes by hostname, not by IP. In Globalping you do the same by making the IP the target and putting your domain in request.host:
curl -s -X POST https://api.globalping.io/v1/measurements \
-H 'Content-Type: application/json' \
-d '{
"type": "http",
"target": "104.18.12.15",
"locations": [{ "country": "MX", "limit": 20 }],
"measurementOptions": {
"protocol": "HTTPS",
"request": { "method": "HEAD", "host": "your-domain.com", "path": "/cdn-cgi/trace" }
}
}'
This is a diagnostic, not a fix. On the Free plan you don’t choose which IPs your zone gets, and hand-pointing your DNS at a Cloudflare IP you weren’t assigned relies on behavior Cloudflare neither documents nor guarantees. It could stop working tomorrow with no notice.
Why it happens: Free is first to be moved
Cloudflare doesn’t hide it. In the post introducing Traffic Manager, the system that shifts traffic when a data center runs short, it says:
“We move Free customers first, and if there are no more Free customers in a data center, we’ll move Pro, and then Business customers if needed.”
And in November 2024 someone in central Mexico asked on Hacker News why their Workers were running in Dallas. Kenton Varda, a Cloudflare engineer and the tech lead of Workers, replied:
“Some of our colos don’t have enough capacity to serve all traffic in their local region, so we selectively serve a subset of sites from that colo and reroute others to a bigger colo further away. […] generally sites on the free plan or lower plan levels are more likely to be rerouted.”
In the same reply he made clear that the routing has nothing to do with whether you use Workers.
Put both quotes next to the measurement and it adds up: Cloudflare does have data centers in Mexico (I saw QRO in the cf-ray and MEX in September’s test), but they don’t have room for everyone, and the Free plan is the first to be sent to Texas.
What I don’t know, because I didn’t measure it: whether upgrading the zone to Pro brings it back to Mexico. Plan-based priority is documented by Cloudflare, but that doesn’t guarantee your particular zone changes colo. The only way to find out is to pay for a month and rerun the curl above.
What it costs in milliseconds, and when it matters
The measured gap is about 25 ms per round trip (32 ms vs. 7 ms median). A cold page load, with no connection open yet, pays several round trips before the first byte: the TCP handshake, the TLS handshake and the request itself. At three or four round trips, that’s on the order of 100 ms extra on the first load. Later requests reuse the connection and pay one round trip each.
Is that a lot? It depends on what else is going on:
- If your HTML isn’t cached and goes back to your server on every visit, that hop outweighs Dallas. In September’s measurement, a page that went to the origin waited 75 ms for the first byte; a file already cached in the same Dallas colo, 43 ms. Cloudflare doesn’t cache HTML by default, on free or paid plans; I go through the fix in my guide to keeping an online store up during Mexico’s Buen Fin. Do that first: it’s free and it wins more.
- If your server is far from your users, the colo-to-origin leg adds up, and Dallas may even sit on the way.
- If your site is static or mostly served from cache, 100 ms on the first load rarely pushes your Core Web Vitals from “good” to “poor”. It’s a second-order improvement.
- Where it does matter: apps that make many sequential requests (a dashboard that calls the API ten times to draw one screen, a multi-step checkout) or APIs consumed from Mexico with lots of short calls. That’s where 25 ms gets multiplied.
For comparison, here’s what the September 22 run showed from the same probes:
| Provider (Sep 22, 2026, probes in Mexico) | Where it answered from | What I measured |
|---|---|---|
| Cloudflare, Free zone | Dallas | ~30 ms per round trip |
| Bunny CDN | Mexico City | ~4 ms wait for first byte |
| AWS CloudFront | Querétaro on 15 of 19 probes | local connection |
| Vercel and Netlify | TCP terminates nearby, but TLS and cache in the US | ~110 ms for the TLS handshake alone |
Watch out with Vercel and Netlify: tcp looks low because the connection is accepted nearby, but encryption and caching happen in a US region. When you measure them, look at tls, not tcp.
Did Birthday Week 2026 change this? No
Cloudflare wrapped up its anniversary week on October 2 with a network performance post saying it’s the fastest provider in 74% of the world’s 1,000 largest networks, up from 60% in April. Read quickly, that seems to contradict everything above. It doesn’t, because it measures something else:
- It measures TCP connect time (as a trimean) from the user’s browser to endpoints of several providers, run from Cloudflare’s error pages and Challenge Pages.
- It doesn’t break results down by plan. It measures Cloudflare’s endpoints, not your Free zone.
- It doesn’t mention Mexico. And none of that week’s posts I read touch plan-based routing or capacity in the region.
Both can be true at once: Cloudflare can be the fastest to its own endpoints from a Mexican network while your Free-plan domain is still served from Dallas. Today’s measurement came after all of those announcements and matched September’s.
What Birthday Week did bring to the Free plan
Of that week’s announcements, these are the ones that apply to a free account:
-
Protected Quick Tunnels.
cloudflaredquick tunnels (version 2026.9.3 and later) now take a list of email addresses: only those people can open the link, using a one-time PIN sent by email. Neither you nor your client needs a Cloudflare account. Handy for showing a client work in progress without deploying it or leaving a tunnel open to anyone (announcement):cloudflared tunnel --url http://localhost:8080 --allowed-mail [email protected] -
Unified Observability, with new pricing from December 1, 2026. On Free you get 0.5 GB of log ingestion a day and 7 days of retention. Domain analytics also go to 30 days, and Logpush opens up to self-serve plans (announcement). If you rely on Workers logs today, check how much you generate before that date.
-
AI Search went GA on October 1 and starts billing on November 1. If you built on the preview assuming it was free, read the pricing page before then.
None of this changes where your site is served from, but they’re dated changes that reach you even if you don’t pay.
What I’d do
- Measure before deciding. Run the Globalping command against your domain, with probes in the cities where your users are. If you get
DFWat ~30 ms, now you know what you’re paying; if you getQROorMEX, this post isn’t about you (yet: routing is dynamic and can change without notice). - Remove the origin hop first. Cache whatever HTML you can at the edge. That gain is bigger than Dallas-to-Querétaro and costs nothing.
- Decide on numbers. If after that you’re in one of the cases where it matters (lots of sequential requests, users mostly in Mexico), there are CDNs that answered from inside Mexico in my tests. Test them the same way and compare milliseconds, not marketing claims. And if you want to try a paid Cloudflare plan, measure before and after: it’s the only way to know whether your zone gets a different colo.
- Re-measure now and then. What I measured today may not hold in three months. The command takes a minute.
Frequently asked questions
Does Cloudflare have servers in Mexico?
Yes. In my measurements I saw Cloudflare data centers in Querétaro (QRO, in the cf-ray header, on October 4, 2026) and Mexico City (MEX, on September 22, 2026) answer requests. Having them doesn't mean they serve your site: when they run short on capacity, Cloudflare sends part of the traffic to bigger data centers further away, and Free-plan sites are moved first.
Is Cloudflare's Free plan slower in Mexico?
In my October 4, 2026 test, a Free-plan test domain was served from Dallas to all 19 Mexican probes that answered, with a median TCP connect time of 32 ms; the same zone pinned to an IP announced from Mexico answered in 7 ms. That is about 25 ms per round trip and on the order of 100 ms on a cold load. Cloudflare documents that Free customers are moved first when a data center runs out of capacity. I did not test whether a paid plan changes it.
How do I find out which city Cloudflare serves my site from?
Run curl -s https://your-domain.com/cdn-cgi/trace | grep colo and read the code: DFW is Dallas, QRO Querétaro, MEX Mexico City. The same code is the suffix of the cf-ray header. That tells you where you are served from; to measure from other cities, use the public Globalping API with probes in the country you care about, no sign-up required.
Does using Cloudflare Workers change which data center serves my site?
No. Kenton Varda of Cloudflare said so on Hacker News, replying to a user in central Mexico whose Workers ran in Dallas: routing depends on each data center's capacity and on the plan, and has nothing to do with whether you use Workers.
Found it useful? Get the next one by email
Once a week: what breaks when you upgrade, AI for developers and what I'm building, with sources. No spam.
By subscribing you accept our privacy policy.