没有不值得去解决的问题,也没有不值得去学习的技术!

Is Cloudflare Free Suitable for a Mainland China WordPress Site? A Real-World Test from Cache HIT to Gray-Cloud Direct Aliyun ECS

【图9:boce 测试 cn-test,灰云直连阿里云 ECS,平均响应 0.478s】

作者:

在

1. Background: This Does Not Overturn the Previous Conclusion, but Narrows Its Scope

A few days ago, I published another article:

CDN Performance Before and After Deployment: Correcting a WordPress Cache Misdiagnosis and Verifying the Real Acceleration Effect

That article mainly addressed a different problem:

WordPress performance optimization is not just about whether a CDN is enabled. You also need to verify whether W3 Total Cache, Cloudflare Cache Rule, response headers, and HTML caching actually form a complete caching loop.

At that time, I confirmed several things:

  • After re-enabling Page Cache in W3 Total Cache, page caching was working;
  • Cloudflare HTML Cache Rule could make the homepage HTML hit the cache;
  • cf-cache-status: HIT and age are useful indicators for judging whether Cloudflare cache is being hit;
  • My earlier belief that W3TC Page Cache was not working under Nginx turned out to be a misdiagnosis.

Those conclusions still hold.

However, as traffic continued to decline over the past few days, I started investigating a new problem. The finding was:

A cache HIT does not necessarily mean fast access from mainland China.

This article is a further refinement of the previous conclusion:

Cloudflare Free can make WordPress HTML hit the cache, but if your main users are in mainland China, especially on China Mobile or China Unicom networks, access through Cloudflare’s standard global network can still fluctuate noticeably.

[Figure 1: Screenshot of the previous article, “CDN Performance Before and After Deployment”, used as the background for this correction]
[Figure 1: Screenshot of the previous article, “CDN Performance Before and After Deployment”, used as the background for this correction]

2. The Problem: boce Tests Showed Very Slow China Mobile and China Unicom Routes

Over the past few days, I have been monitoring the decline in website traffic. Today I tested the homepage again using boce.com:

Plaintext
https://www.shuijingwanwq.com/

The first test result was not encouraging.

The averages were:

NetworkAverage response time
Overall average5.245s
China Telecom average0.967s
China Mobile average7.286s
China Unicom average7.341s

Based on this result, the China Telecom route was acceptable, but China Mobile and China Unicom were very slow.

[Figure 2: boce homepage test result, with China Mobile and China Unicom average response times exceeding 7 seconds]
[Figure 2: boce homepage test result, with China Mobile and China Unicom average response times exceeding 7 seconds]

If I only looked at this screenshot, it would be easy to suspect that:

  • WordPress had become slow;
  • W3TC was not working;
  • There was an issue with the Nginx configuration;
  • PHP or MySQL was slowing down the homepage;
  • Cloudflare HTML cache was not being hit.

But that judgment would not be rigorous enough.

Because the previous article had already shown that the caching loop could be working correctly, my first step was not to keep changing WordPress. Instead, I checked the response headers.


3. Confirming the Cache State: Cloudflare Was Indeed Returning HIT

I ran the following locally:

Bash
curl -I https://www.shuijingwanwq.com/

Several lines in the response were especially important:

Plaintext
age: 908
cache-control: max-age=14400
cf-cache-status: HIT
cf-ray: a165b9c22fc3eb28-SJC
server: cloudflare

This shows that:

  • The homepage HTML was not being generated by WordPress in real time;
  • Cloudflare cache was already being hit;
  • age had a value, meaning the cached object had existed for some time;
  • cf-cache-status: HIT means this request was served from Cloudflare cache.

In other words, this slowdown was not caused by WordPress generating the homepage too slowly in real time.

But another detail stood out:

Plaintext
cf-ray: ...-SJC

SJC usually refers to Cloudflare’s San Jose node. In other words, when I accessed the Chinese main site from a China Mobile network in Chengdu, the request was likely routed by Cloudflare to San Jose in the United States.

[Figure 3: curl test from China Mobile in Chengdu with VPN disabled, showing cf-cache-status: HIT but cf-ray ending in SJC]
[Figure 3: curl test from China Mobile in Chengdu with VPN disabled, showing cf-cache-status: HIT but cf-ray ending in SJC]

I then tested with a full timing command:

Bash
curl -o /dev/null -s -w \
"DNS: %{time_namelookup}s\nConnect: %{time_connect}s\nTLS: %{time_appconnect}s\nTTFB: %{time_starttransfer}s\nTotal: %{time_total}s\nRemote IP: %{remote_ip}\n" \
https://www.shuijingwanwq.com/

Result:

Plaintext
DNS: 0.001029s
Connect: 1.278439s
TLS: 2.267914s
TTFB: 3.082981s
Total: 6.072956s
Remote IP: 172.67.216.242

This result shows that:

  • DNS lookup was fast;
  • TCP connection was slow;
  • TLS handshake was slow;
  • TTFB was slow;
  • Total time exceeded 6 seconds;
  • The remote IP was a Cloudflare IP.

So the issue can basically be characterized as follows:

When accessing Cloudflare Free directly from China Mobile in Chengdu, the route can still be slow even when the cache is already HIT.


4. Cloudflare China Network: Standard Cloudflare Free Is Not the Same as Mainland China Acceleration

I later checked Cloudflare’s official documentation and found that this is not an isolated issue.

Cloudflare’s official documentation clearly states that fast and reliable content delivery to users in mainland China requires infrastructure within mainland China. If traffic is routed to servers outside China, latency and reliability issues may occur. Cloudflare China Network is designed to address this problem by running selected Cloudflare performance and security products in mainland China data centers through a partnership between Cloudflare and JD Cloud.

Reference:
Cloudflare China Network official documentation

However, Cloudflare China Network is not included by default in the regular Free, Pro, or Business plans. The official onboarding process requires an ICP filing or license, displaying the ICP number in the website footer, and having the domain content reviewed by JD Cloud.

Reference:
Cloudflare China Network Get started

For me, ICP filing is not the biggest obstacle. My domain was already filed back in 2013.

The real issue is:

Cloudflare China Network feels more like an enterprise-grade solution than a normal CDN option that an individual technical blog can easily adopt at this stage.

[Figure 4: Screenshot of Cloudflare China Network official documentation, covering mainland China acceleration, JD Cloud, ICP, and content review requirements]
[Figure 4: Screenshot of Cloudflare China Network official documentation, covering mainland China acceleration, JD Cloud, ICP, and content review requirements]

5. The Second boce Test Became Fast Again: This Points to Fluctuation, Not a One-Off Failure

A while later, I tested the homepage again with boce.

This time, the result was much better:

NetworkAverage response time
Overall average1.256s
China Telecom average1.033s
China Mobile average1.799s
China Unicom average0.895s
[Figure 5: Second boce homepage test, with average response time back to a little over 1 second]
[Figure 5: Second boce homepage test, with average response time back to a little over 1 second]

If I only looked at the second test, it would seem reasonable to say that Cloudflare Free was performing fairly well.

But considering the first boce test, the local curl test from China Mobile in Chengdu, and cf-ray: SJC, the more reasonable conclusion is not that “the problem disappeared”, but rather:

Cloudflare Free is not consistently slow for mainland China access, but it can fluctuate significantly.

Sometimes it is acceptable; at other times, China Mobile and China Unicom can suddenly become very slow.

For casual browsing, this may only feel like an occasional slowdown. But for a WordPress blog that depends on search traffic, ad impressions, and affiliate conversion, this kind of fluctuation matters.


6. Creating a Gray-Cloud Test Domain: cn-test.shuijingwanwq.com

To avoid further guessing, I decided to run the simplest and cleanest comparison test possible.

The goal of the test was:

Use the same static HTML file, access one copy through Cloudflare Free and another copy by bypassing Cloudflare and connecting directly to Aliyun ECS, then see which one is faster from mainland China.

I created a test subdomain:

Plaintext
cn-test.shuijingwanwq.com

In Cloudflare DNS, I set it to:

Plaintext
DNS only / 灰云

In other words, this subdomain does not go through Cloudflare CDN. It resolves directly to my Aliyun Hangzhou ECS server.

Cloudflare’s official documentation also explains that the proxy status of a DNS record determines whether HTTP/HTTPS traffic passes through Cloudflare’s network. When the record is gray-cloud DNS only, requests go directly to the origin server.

Reference:
Cloudflare DNS Proxy status official documentation

The server runs OneinStack, so I used OneinStack’s vhost.sh directly to add a new Nginx virtual host:

Bash
~/oneinstack/vhost.sh

I selected Let’s Encrypt to request a certificate and entered the domain:

Plaintext
cn-test.shuijingwanwq.com

The final output generated:

Plaintext
Virtualhost conf: /usr/local/nginx/conf/vhost/cn-test.shuijingwanwq.com.conf
Directory of: /data/wwwroot/cn-test.shuijingwanwq.com
Let's Encrypt SSL Certificate: /usr/local/nginx/conf/ssl/cn-test.shuijingwanwq.com.crt
SSL Private Key: /usr/local/nginx/conf/ssl/cn-test.shuijingwanwq.com.key
[Figure 6: Adding the cn-test.shuijingwanwq.com virtual host in OneinStack and requesting an SSL certificate]
[Figure 6: Adding the cn-test.shuijingwanwq.com virtual host in OneinStack and requesting an SSL certificate]

7. Creating a Static Test Page to Avoid WordPress Interference

To keep the test as clean as possible, I did not test the WordPress homepage directly. Instead, I created a static file:

Plaintext
/data/wwwroot/cn-test.shuijingwanwq.com/cdn-test.html

The content was:

HTML
<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="robots" content="noindex,nofollow">
  <title>CN Test</title>
</head>
<body>
  <h1>CN Test</h1>
  <p>This is a direct origin test page for cn-test.shuijingwanwq.com.</p>
</body>
</html>

To prevent search engines from indexing the test domain, I also created:

Plaintext
robots.txt

Content:

Plaintext
User-agent: *
Disallow: /

Local server test:

Bash
curl -k -I --resolve cn-test.shuijingwanwq.com:443:127.0.0.1 https://cn-test.shuijingwanwq.com/cdn-test.html

Response:

Plaintext
HTTP/2 200
server: nginx

Public network test:

Bash
curl -I https://cn-test.shuijingwanwq.com/cdn-test.html

Response:

Plaintext
HTTP/2 200
server: nginx

The following did not appear:

Plaintext
server: cloudflare
cf-cache-status
cf-ray

This means cn-test was already gray-cloud direct access to Aliyun ECS.

[Figure 7: cn-test response headers showing server: nginx, with no Cloudflare headers]
[Figure 7: cn-test response headers showing server: nginx, with no Cloudflare headers]

8. Copying the Same Static File to the Main Site for a Fair Comparison

To keep the comparison fair, I copied the same cdn-test.html file to the main site directory:

Bash
cp /data/wwwroot/cn-test.shuijingwanwq.com/cdn-test.html /data/wwwroot/www.shuijingwanwq.com/cdn-test.html
chown www:www /data/wwwroot/www.shuijingwanwq.com/cdn-test.html

This gave me two test URLs:

Plaintext
https://cn-test.shuijingwanwq.com/cdn-test.html
https://www.shuijingwanwq.com/cdn-test.html

There was only one difference between them:

Plaintext
cn-test:灰云,直连阿里云 ECS
www:橙云,经过 Cloudflare 免费版

This is more reliable than testing the WordPress homepage directly, because it excludes:

  • PHP execution;
  • MySQL queries;
  • WordPress plugins;
  • theme rendering;
  • page cache state;
  • differences in homepage content size.

9. Local China Mobile Test in Chengdu: Direct Aliyun Access Was Clearly Faster

On a China Mobile home network in Chengdu, with VPN disabled, I ran:

Bash
for url in \
https://cn-test.shuijingwanwq.com/cdn-test.html \
https://www.shuijingwanwq.com/cdn-test.html
do
  echo "===== $url ====="
  for i in {1..5}; do
    curl -o /dev/null -s -w \
    "Test $i | DNS:%{time_namelookup}s Connect:%{time_connect}s TLS:%{time_appconnect}s TTFB:%{time_starttransfer}s Total:%{time_total}s IP:%{remote_ip}\n" \
    "$url"
    sleep 2
  done
done

Gray-cloud direct Aliyun ECS result:

Plaintext
Test 1 | DNS:0.646942s Connect:0.691377s TLS:0.747487s TTFB:0.790079s Total:0.790187s IP:121.40.248.29
Test 2 | DNS:0.010986s Connect:0.055257s TLS:0.111520s TTFB:0.153581s Total:0.153780s IP:121.40.248.29
Test 3 | DNS:0.194935s Connect:0.239629s TLS:0.294280s TTFB:0.336752s Total:0.336899s IP:121.40.248.29
Test 4 | DNS:0.013646s Connect:0.052931s TLS:0.106207s TTFB:0.143662s Total:0.143917s IP:121.40.248.29
Test 5 | DNS:0.013102s Connect:0.057821s TLS:0.113634s TTFB:0.156147s Total:0.156304s IP:121.40.248.29

Cloudflare Free result:

Plaintext
Test 1 | DNS:0.856172s Connect:1.494555s TLS:1.836330s TTFB:2.189768s Total:2.715783s IP:104.21.78.52
Test 2 | DNS:0.013359s Connect:0.348307s TLS:2.060387s TTFB:2.316640s Total:2.316704s IP:104.21.78.52
Test 3 | DNS:0.002189s Connect:0.237458s TLS:0.659885s TTFB:1.596999s Total:1.597418s IP:172.67.216.242
Test 4 | DNS:0.003584s Connect:0.289218s TLS:0.864385s TTFB:1.799406s Total:1.799621s IP:104.21.78.52
Test 5 | DNS:0.002377s Connect:0.241457s TLS:0.696943s TTFB:1.519057s Total:1.519200s IP:104.21.78.52

The result was very clear.

For gray-cloud direct Aliyun ECS, except for the first DNS cold start, the results were basically around:

Plaintext
0.14s - 0.34s

Cloudflare Free was basically around:

Plaintext
1.5s - 2.7s

And the Cloudflare version had already been confirmed as a cache HIT:

Plaintext
cf-cache-status: HIT
cf-ray: ...-SJC

This shows that the issue was not slow origin fetch. The slow part was the access route from mainland China to Cloudflare’s standard network.

[Figure 8: Local curl comparison from China Mobile in Chengdu, showing cn-test clearly faster than www through Cloudflare]
[Figure 8: Local curl comparison from China Mobile in Chengdu, showing cn-test clearly faster than www through Cloudflare]

10. boce Comparison: Gray-Cloud Direct Access Averaged 0.478s, Cloudflare Averaged 1.755s

I then tested both URLs separately on boce.com.

1. Gray-Cloud Direct Access to Aliyun ECS

Test URL:

Plaintext
https://cn-test.shuijingwanwq.com/cdn-test.html

Result:

NetworkAverage response time
Overall average0.478s
China Telecom average0.36s
China Mobile average0.675s
China Unicom average0.391s
[Figure 9: boce test for cn-test, gray-cloud direct access to Aliyun ECS, average response time 0.478s]
[Figure 9: boce test for cn-test, gray-cloud direct access to Aliyun ECS, average response time 0.478s]

2. Cloudflare Free

Test URL:

Plaintext
https://www.shuijingwanwq.com/cdn-test.html

Result:

NetworkAverage response time
Overall average1.755s
China Telecom average2.297s
China Mobile average1.862s
China Unicom average1.104s
[Figure 10: boce test for www, the same static file through Cloudflare, average response time 1.755s]
[Figure 10: boce test for www, the same static file through Cloudflare, average response time 1.755s]

Comparison:

Test targetAverage response time
Aliyun ECS gray-cloud direct access0.478s
Cloudflare Free1.755s

Cloudflare Free was about 3.6 times slower.

This test had very few variables:

  • the same server;
  • the same static HTML file;
  • the same HTTPS protocol;
  • one path went directly to Aliyun ECS;
  • the other went through Cloudflare Free.

So this result is more convincing than directly testing the WordPress homepage.


11. Correcting the Conclusion of the Previous Article

Going back to the previous article:

CDN Performance Before and After Deployment: Correcting a WordPress Cache Misdiagnosis and Verifying the Real Acceleration Effect

The conclusion of that article can still stand, but it needs a clearer scope.

The old conclusion can be summarized as:

After Cloudflare CDN and W3TC Page Cache were both hitting, site performance improved significantly.

A more accurate conclusion now would be:

After Cloudflare CDN and W3TC Page Cache are both hitting, overseas access and the overall caching loop perform better. But whether mainland China access becomes faster depends on the routing quality of Cloudflare’s standard network across local carrier routes. For my Chinese main site, Aliyun ECS gray-cloud direct access was clearly faster than Cloudflare Free in this test.

This does not mean W3TC is bad, nor does it mean Cloudflare is bad.

What really needs to be corrected is this:

A CDN is not “the more, the better” in an abstract sense. You need to look at where users are, how the route is actually taken, whether the cache is hit, and whether the edge node is truly closer to the user.


12. Why I Do Not Recommend Splitting CDN by Language Directory

At first, I considered this architecture:

Plaintext
www.shuijingwanwq.com        中文主站 → 国内 CDN
www.shuijingwanwq.com/en/    英文站 → Cloudflare

But after looking at it more carefully, this structure is not clean.

The reason is that DNS and CDN routing usually apply first at the hostname level, not at the URL directory level.

When the browser visits:

Plaintext
https://www.shuijingwanwq.com/en/

The first thing it resolves is:

Plaintext
www.shuijingwanwq.com

The DNS layer does not know about the path that follows:

Plaintext
/en/

Cloudflare’s proxy status also applies to DNS records. It determines whether HTTP/HTTPS traffic for a hostname passes through Cloudflare.

Reference:
Cloudflare DNS Proxy status official documentation

So the conventional, clean, low-risk way cannot achieve this:

Plaintext
www/       → 国内 CDN
www/en/    → Cloudflare

In theory, you could work around it with multi-layer CDN, path-based origin routing, reverse proxying, and similar approaches. But the route could become:

Plaintext
用户 → 国内 CDN → Cloudflare → 源站

That is not only messy, but also brings many problems:

  • a longer request path;
  • more complex caching;
  • SSL, Host, and SNI are more likely to break;
  • WordPress login, cookies, and redirects may behave abnormally;
  • Polylang canonical URLs and sitemaps may become messy;
  • troubleshooting becomes painful.

So if I split by language, the truly clean structure would be:

Plaintext
www.shuijingwanwq.com        中文站
en.shuijingwanwq.com         英文站

But that introduces a new SEO migration cost.


13. Why Region-Based Routing May Be More Reasonable Long Term Than Language-Based Splitting

Thinking further, I realized that “splitting CDN by language” may not match the real access pattern either.

The real situation of my site is not:

Plaintext
中文用户只访问 /
海外用户只访问 /en/

It is more likely:

Plaintext
中国大陆用户:可能访问中文页面,也可能访问 /en/ 英文页面
海外用户:可能访问 /en/ 英文页面,也可能访问中文页面

So the more reasonable long-term direction is not:

Plaintext
中文目录 → 国内 CDN
英文目录 → Cloudflare

but rather:

Plaintext
中国大陆用户访问 www → 国内 CDN
海外用户访问 www     → Cloudflare

In other words:

Plaintext
同一个 URL:
https://www.shuijingwanwq.com/
https://www.shuijingwanwq.com/en/

根据访问者所在地区,走不同 CDN。

The benefits of this approach are:

  • No need to migrate /en/ to en.shuijingwanwq.com;
  • The Polylang URL structure remains unchanged;
  • canonical URLs, sitemap, GSC, and internal links do not need major changes;
  • mainland China users use a domestic CDN whether they visit Chinese or English content;
  • overseas users use an overseas CDN whether they visit Chinese or English content;
  • it better matches the reality that network quality differs greatly by region.

Cloudflare Load Balancing’s Geo steering follows a similar idea: it directs traffic to different pools based on country, region, or data center. Cloudflare documentation also explains that Geo steering can send visitors to an endpoint closer to them to improve page load performance.

Reference:
Cloudflare Geo steering official documentation

However, this kind of setup cannot be completed by simply adding one DNS record. It requires:

  • smart DNS;
  • GeoDNS;
  • global traffic steering;
  • multi-CDN configuration;
  • domestic CDN CNAME;
  • overseas CDN CNAME;
  • unified SSL certificates;
  • origin fetch strategy;
  • cache purge strategy;
  • failover strategy.

Alibaba Cloud DNS documentation also notes that CNAME records are commonly used for CDN, enterprise email, global traffic management, and similar scenarios.

Reference:
Alibaba Cloud DNS documentation on adding DNS records

So my judgment is:

Region-based routing is likely more suitable than language-based CDN splitting as a long-term solution. But it belongs in future architecture planning, not as something to rush into during a traffic fluctuation period.


14. Three Options at the Current Stage

Based on this test, I currently see three broad options.

Option 1: Continue Using Cloudflare Free

Pros:

  • No need to keep changing things;
  • the current setup is already working;
  • HTML cache is already HIT;
  • better for overseas access and the English site;
  • DNS, SSL, cache rules, and security protection are all managed in one system.

Cons:

  • mainland China access fluctuates significantly;
  • China Mobile and China Unicom routes may detour;
  • not friendly enough for my current traffic mix, where nearly 80% comes from mainland China;
  • may affect user experience, ad impressions, and affiliate conversion.

Option 2: Purchase Cloudflare China Network

Pros:

  • Keep the unified Cloudflare system;
  • mainland China access can use infrastructure inside mainland China;
  • theoretically better for a unified “global site + China access” architecture.

Cons:

  • more enterprise-oriented;
  • requires ICP filing and content review;
  • may involve higher costs;
  • may not be cost-effective for an individual technical blog at this stage.

My domain was already filed in 2013, so ICP is not the main obstacle. What really needs evaluation is commercial feasibility.

Option 3: Build Region-Based Routing Long Term

The long-term target could be:

Plaintext
中国大陆用户 → 国内 CDN
海外用户     → Cloudflare

instead of:

Plaintext
中文站 → 国内 CDN
英文站 → Cloudflare

This approach is more reasonable for my site because mainland China users may also visit /en/, while overseas users may also visit Chinese content.

But this requires smart DNS, GeoDNS, and global traffic steering, so it is not suitable for immediate changes.


15. My Current Decision: Stop Changing the CDN for Now, but Keep the Test Result

After this test, I have a clearer view of where Cloudflare Free fits.

It is suitable for:

  • overseas access;
  • the English site;
  • globalization experiments;
  • DNS management;
  • SSL;
  • security protection;
  • static asset caching;
  • a low-cost entry point into CDN usage.

But it is not necessarily suitable for:

  • a Chinese WordPress main site whose users are mainly in mainland China;
  • sites that require stable China Mobile and China Unicom access;
  • scenarios that require consistently low domestic latency over the long term.

For now, I do not want to make major CDN changes. In the short term, I will keep the current setup, while retaining cn-test.shuijingwanwq.com as a gray-cloud test domain for future comparison.

If domestic access continues to affect traffic and conversion later, I will consider:

Plaintext
短期:中文主站整体切回国内 CDN
长期:研究同一 www 域名按地区分流

16. Final Conclusion

The biggest reminder from this investigation is:

A cache HIT is only the first step of CDN optimization. Route quality is what determines the real user experience.

For my WordPress blog:

Plaintext
W3TC Page Cache 是必要条件;
Cloudflare HTML Cache Rule 是有效的;
cf-cache-status: HIT 说明缓存闭环没问题;
但中国大陆访问 Cloudflare 免费版仍然可能绕路;
灰云直连阿里云 ECS 在本次中国大陆测试中明显更快;
长期最合理的方向,可能不是按语言拆 CDN,而是按访问地区分流。

Therefore, the conclusion of the previous article should be upgraded to:

WordPress performance optimization should not only look at whether cache is hit. It also needs to consider where the target users are, which carrier routes they use, how CDN nodes are assigned, and what the actual access path looks like.

In one sentence:

Cloudflare Free is not a “mainland China accelerator” in an absolute sense. It is more like a low-cost gateway to global delivery. If most of your current users are still in mainland China, you must evaluate domestic route quality separately instead of only looking at cf-cache-status: HIT.

系列导航

关于作者 · 持续学习与技术实践

我是一名拥有 15 年以上开发经验的技术从业者,自 2013 年起持续运营个人技术博客,记录工作与个人项目中遇到的真实问题,以及解决问题过程中的探索、实践和思考。

除了技术写作,我也在持续开发和维护自己的独立项目,探索新技术和新工具在实际场景中的应用。我始终相信,没有不值得去解决的问题,也没有不值得去学习的技术。

如果这篇文章对你有所帮助,欢迎浏览博客中的其他文章,也欢迎交流技术经验与想法。

关于我  ·  GitHub  ·  邮件联系