The edge is already in Riyadh. Your homepage isn't.
Cloudflare, CloudFront and Fastly all have edges in Dubai and Riyadh. What differs by country is which of your requests ever reaches one.
Last updated
The coverage map stopped being the explanation
Somebody in another country tells you the site is slow. You open it from your desk and it is fine, so you run a test, and that is fine too. The complaint does not go away, and the first answer anyone offers is that you are missing a CDN edge in their city.
Start somewhere else, because the shape of a Gulf business is what makes this particular fault so hard to see. Six countries, six currencies, buyers spread across several of them, and one office holding most of the traffic and all of the testing. Any cost that falls on an out-of-country visitor is a cost nobody in the building experiences, and the people who do experience it are customers rather than colleagues. They do not file tickets.
Then check the coverage claim before acting on it, because for the two cities this argument usually involves, nothing is missing. Cloudflare lists Dubai, Dammam, Jeddah, Riyadh, Doha, Manama, Kuwait City and Muscat, which is all six GCC countries. On CloudFront it is Dubai (4), Jeddah (4), Riyadh (2), Doha (2), Bahrain (5) and Muscat (3). Fastly’s Gulf points of presence are Dubai, Fujairah and Riyadh.
Read the CloudFront line again. Saudi Arabia has six points of presence across two cities and the UAE has four in one, so on that provider Saudi Arabia is the better-served of the two countries. “Fast in Dubai, slow in Riyadh” cannot be a coverage story when both ends are covered and the far end is covered harder.
Where the gap is real it sits in the smaller markets, and it depends which provider you are on. CloudFront has nothing in Kuwait. Fastly has nothing in Kuwait, Bahrain, Qatar or Oman, so a visitor in any of the four is served from further out. If your traffic sits in those markets, start there instead.
Otherwise the lever has already been pulled. Do the lookup once, then go after the four things that genuinely differ by country: what the edge is allowed to hold, where your origin sits, what you redirect, and how you would ever know. The hour you ask in is the fifth, and it matters more than it sounds like it should.
A CDN in Riyadh does nothing for a document it was told not to cache
Here is where the difference actually lives.
Cloudflare’s documentation is blunt about it: “The Cloudflare CDN does not cache HTML
or JSON by default.” It decides what to cache from the file extension, not the content
type, and HTML is not on the list of extensions it caches. A URL ending .html is no
better off than a bare path. So unless somebody wrote a cache rule, the edge in Riyadh
is holding your stylesheets and your logo, and every request for the page itself
travels to your origin server and back before the visitor sees anything.
CloudFront fails in the opposite direction. With no Cache-Control header from your
origin and a minimum TTL of zero, it caches the response for the distribution’s
default TTL, and “if you opt out of using a cache policy, the default TTL (Time to
Live) is 24 hours.” Nobody chose that either. One provider will not serve your
document from the edge at all; the other may serve a copy of it from yesterday.
Both defaults are defensible as engineering and indefensible as a plan, and in a market with buyers in six countries and servers in one the bill is not shared evenly. The same misconfiguration costs a home-market visitor a short hop and a cross-border visitor a long one, which is why it presents as a country problem and gets diagnosed as a CDN problem. The fix is the same either way: decide, per content type, what the edge is allowed to hold and for how long, and send the headers that say so. Static assets get a long life and a fingerprinted filename. HTML gets a short, deliberate one, because even a few seconds of TTL means a repeat request inside that window is answered at the edge instead of travelling to your origin.
Then go and look. Request your own homepage and read the cache status header that comes
back. On Cloudflare it is CF-Cache-Status, and the value to watch for is DYNAMIC:
“Cloudflare determined at request time that the asset is not eligible for cache, so the
request went to the origin web server without a cache lookup.” One request answers a
question a fortnight of procurement cannot.
Where your origin sits decides who pays for it
A CDN has many edges and you have one origin. Every request the edge cannot answer resolves there, which means the distance that matters for those requests is not visitor-to-edge. It is visitor-to-origin. A coverage map has no way of showing you that, and it is the number your Riyadh complaint is made of.
Cache misses are not only a configuration problem, either. CloudFront documents that “if a file in an edge location isn’t frequently requested, CloudFront might evict the file — remove the file before its expiration date — to make room for files that have been requested more recently.” So the edge nearest your smallest market is the one least likely to be holding your files. A trickle of daily traffic does not keep a cache warm; your home market’s volume does. Which has an unpleasant consequence for anyone expanding across the Gulf: the market you are trying to win is the one with the coldest cache, and it stays cold until the traffic you are building arrives. The penalty is heaviest exactly when the expansion most needs the site to perform.
Which puts real weight on one decision that is easy to leave alone: where the origin lives. Gulf traffic used to leave the region to be exchanged in Europe, and the regional exchanges built since then changed the arithmetic. UAE-IX went into operation in 2012 and is managed by DE-CIX, which calls it the largest internet exchange in the Middle East, and Bahrain, Kuwait and Saudi Arabia each run at least one of their own. A Frankfurt origin serving a GCC audience is now a choice with a local alternative, and it used to be the only sensible option.
Hosting location is a legal question too, and the answer is country-level. In the UAE, health, banking and credit data sit outside the federal PDPL under their own regimes, and the health law restricts where that data may be stored at all. Saudi Arabia’s PDPL governs the conditions for moving data out of the Kingdom rather than requiring it to stay in. Settle which perimeter applies before procurement, then treat what is left as the latency decision it is.
The redirect you added to help is the one that costs you the crawl
The second thing that differs by country has nothing to do with speed. A visitor in Riyadh can get a fast page that is the wrong page.
Sending someone to the right country’s version sounds like a courtesy. Done by IP
address, Google says what it costs: “the default IP addresses of the Googlebot crawler
appear to be based in the USA. In addition, the crawler sends HTTP requests without
setting Accept-Language.” So a redirect keyed on the visitor’s country sends Googlebot
to whichever page an American with no stated language preference gets, and the other
versions may never be seen. Google does also crawl “with IP addresses based outside the
USA,” and says to treat it then “like you would treat any other user from that country.”
Good practice, and not a reason to rely on it finding your Saudi pages.
Google’s own recommendation is the whole answer: use “separate locale URL
configurations” and annotate them with rel="alternate" hreflang annotations. Give each
market a stable URL, declare the relationship, and let the reader choose. Whether those
declarations point back at each other correctly is its own piece of work, and hreflang is reciprocal or it is ignored.
Be straight about what this is. Google’s spam policies define cloaking as “presenting different content to users and search engines with the intent to manipulate search rankings and mislead users,” and sneaky redirecting as doing it “maliciously.” Both turn on intent and neither names location as a factor, so a geo-redirect built in good faith is not the thing those policies describe. The cost is simpler than a penalty and about as expensive: pages that do not get crawled do not rank, and a visitor dropped onto a page for a country they are not in has been handed a reason to leave. That shows up in your analytics as a Saudi session that bounced, never as a Saudi session that was shown Emirati pricing.
Two practical notes. First, replace the redirect with a prompt: a non-blocking banner offering the other market, every link on the page still crawlable, the choice remembered so it does not ask twice. Second, the country-targeting setting in Search Console is gone, deprecated along with the International Targeting report in 2022. If the crawl itself is the part that looks wrong, the contradictions between your canonicals, redirects and robots rules are the next place to look.
You can’t test from Riyadh for free, and you don’t need to
The guidance on this subject tells you to test from the country that is complaining.
Look at the tool it names. WebPageTest’s public location list has exactly one agent in
the Gulf: DXB_AE_01, in Dubai. There is nothing in Saudi Arabia, Bahrain, Qatar,
Kuwait or Oman. On the free tier here, that advice cannot be followed at all.
The answer is better than the advice anyway, because you do not need a machine in
Riyadh to find out what Riyadh gets. Chrome’s public field dataset is already
collecting it from real Chrome users on your site. In BigQuery it exposes per-country
tables named chrome-ux-report.country_CC by two-letter country code, plus a
country_summary table giving “aggregated statistics by month, origin, country and
device.” The schema carries effective_connection_type and round_trip_time next to
the Core Web Vitals, so you can put your Saudi visitors’ network round trip beside your
Emirati visitors’ and see the gap as a measured number.
That is the query: your own origin, split by country, month over month, round trip beside the loading metrics. Close round trips with diverging loading metrics put the problem on your side of the connection, which sends you back to what the edge is allowed to hold. A wide round trip is an origin and routing question.
The honest limit: eligibility is a popularity threshold Chrome does not publish, and its own documentation says “an exact number is not disclosed.” Combinations that miss the bar at country level “may still be included at the global level,” so a smaller site can have a global row and no Saudi row at all. When that happens, collect the timings yourself from real sessions and segment them by country. Field data settles the verdict and lab data only supports it, which is also how you work out which of the three metrics you are actually failing.
The hour matters as much as the country
One test at one moment samples a distribution that moves all day, and in this region it moves on a schedule that differs per market.
Ookla measured it across the Gulf in the first quarter of 2026, comparing each hour against an overnight off-peak baseline. Saudi Arabia ran at almost 1.5x that baseline at 9 AM and fell to roughly 0.6x around iftar. Bahrain peaked near 1.4x at 6 AM and hit the same trough at iftar. The UAE’s weak point was the morning commute, 0.5x at 7 AM. Qatar’s was the middle of the afternoon, around the same ratio at 1 PM. Kuwait barely moved, with its weakest hour at about 0.9x. Oman’s low was roughly 0.7x at 8 AM.
Six markets, six different worst hours, and no two of them line up. A cross-border test at 11 AM Gulf time is one reading from six different distributions, which is why two teams in two countries can run the same test on the same site and disagree about the result in good faith. These are ratios against each market’s own baseline rather than absolute speeds, and the baselines here are high: Ookla put the six Gulf markets’ average congestion rating at roughly half the European average on the same methodology. A market losing half its headroom at 1 PM is still quick at 1 PM.
So stop treating a synthetic run as a verdict on a country. Field data already aggregates real visits at every hour, which is what makes it the verdict. Keep the synthetic runs for before-and-after on a change you control, run at the same hour each time. And if you are shipping something that touches the critical path, do not ship it into a market’s peak hour, which during Ramadan means the run-up to iftar in the country you are shipping to rather than the one you are sitting in.
What to do this week
Cheapest and most decisive first.
- Look up your CDN’s edge list and write down which of your visitors’ countries has one. If your provider is one of the three above, this is a lookup, not a project.
- Request your own homepage and read your CDN’s cache status header. Find out whether the document was served from the edge or fetched from your origin.
- Set
Cache-Controldeliberately, per content type. Long and fingerprinted for static assets, short and intentional for HTML. - Write down where your origin is and which of your markets is furthest from it. That distance is what every uncached request pays.
- Replace any IP-based redirect with a non-blocking prompt, and give each market its own URL.
- Pull your own origin’s country split out of Chrome’s field dataset and read the round trip beside the loading metrics.
Our Site Audit will tell you which templates are failing, and it is worth running first because so much of what it finds applies in every market you sell to. What it will not hand you is the split between those markets, which is the question here. That part is a query and a header check, neither of them longer than an afternoon. Geography is one of several things deciding whether a Gulf buyer converts; website performance covers the others.
One last thing, because it catches people out: a link shared into a chat or a feed is fetched by that platform’s crawler, from its own datacentre, in a country that is probably not yours. If your site behaves differently by location, the tags that crawler reads are the ones on whichever version it was served, which is one way a link preview goes wrong when the tags themselves look correct.
Standing offer
The hard part is deciding what to do first
Bring us a URL, an audit report, or a proposal you're not sure about. We'll tell you which problems deserve budget this quarter, and you'll leave with an order of operations you can hand to whoever does the work, whether that's us or not.
Book twenty minutes