Today I continued working on CDN caching issues for my WordPress sites.
While previously troubleshooting server CPU and PHP-FPM pressure, I found a scenario worth addressing:
https://www.shuijingwanwq.com/2026/07/27/20341/?abc=123
https://www.shuijingwanwq.com/2026/07/27/20341/?abc=456
The article content is actually identical, but the Query String after the URL differs. If the CDN treats these requests as different cache objects, it may continuously generate new MISSes and keep forwarding requests to the WordPress origin.
For standard article detail pages, these random parameters mostly have no practical meaning.
However, I cannot simply ignore Query Strings across the entire site, because WordPress itself has many requests that genuinely depend on parameters, such as:
/?s=wordpress
/?p=123
/?page_id=123
Therefore, the goal this time is not to “ignore parameters site-wide”, but rather:
Only normalize Query Strings for standard WordPress article detail pages.
My Chinese site uses Tencent Cloud EdgeOne, and my English site uses Cloudflare, so I completed two separate configurations and verified them through actual requests and Nginx logs.
1. Finalized Rule Boundaries
My article permalink structure is:
/YYYY/MM/DD/文章ID/
For example:
/2026/07/27/20341/
Initially, I considered handling both:
/2026/07/27/20341/
/2026/07/27/20341
Later, during actual testing, I found that this would make the rules increasingly complex.
In fact, a URL without a trailing slash is never the final canonical URL for an article anyway.
WordPress / Polylang handles:
/2026/07/27/20341
↓ 301
/2026/07/27/20341/
Therefore, I finally decided:
The CDN only applies special optimization to canonical article detail pages ending with
/.
Meaning:
/YYYY/MM/DD/ID/
As for:
/YYYY/MM/DD/ID
WordPress / Polylang continues to handle the normal canonical 301.
This allows the Chinese and English sites to maintain the exact same design principles, and when I review the CDN configuration six months later, it will be easy to understand.
2. Chinese Site EdgeOne Configuration
Chinese site:
https://www.shuijingwanwq.com/
Currently accelerated via Tencent Cloud EdgeOne.
1. Matching Article Detail Pages
Create a rule in the EdgeOne Rule Engine.
Host:
www.shuijingwanwq.com
URL Path uses regex matching:
^/[0-9]{4}/[0-9]{2}/[0-9]{2}/[0-9]+/$
For example:
/2026/07/27/20341/
will match.
While:
/2026/07/27/20341
will not match.
It also will not affect:
/
/?s=wordpress
/category/php/
/tag/wordpress/
/2026/07/27/20341/feed/

/YYYY/MM/DD/ID/ format2. Custom Cache Key
First operation:
Custom Cache Key
→ Query String
→ Ignore All
The goal is to make:
/2026/07/27/20341/
/2026/07/27/20341/?abc=111
/2026/07/27/20341/?abc=222
use the same cache object.
3. Delete Query String in Origin Pull Request
Second operation:
Origin Request Parameter Setting
→ Query String
→ Ignore All
This way, even on an EdgeOne MISS, when a client accesses:
/2026/07/27/20341/?abc=123
EdgeOne only requests the following during origin pull:
/2026/07/27/20341/
The random parameters will not proceed to the origin server.

3. EdgeOne Cache Key Actual Verification
After configuration, I first tested the same article.
Normal URL:
https://www.shuijingwanwq.com/2026/07/27/20341/
And different random parameters:
?swq_eo_final=111
?swq_eo_final=222
Test results:
With /, no parameters
HTTP/2 200
age: 4326
eo-cache-status: HIT
With /, random parameter 111
HTTP/2 200
age: 4334
eo-cache-status: HIT
With /, random parameter 222
HTTP/2 200
eo-cache-status: HIT
The most obvious part is:
No parameters age: 4326
Parameter 111 age: 4334
Age continues to increase.
Moreover, a new Query String that has never been accessed before results in the following on the very first access:
HIT
This indicates that:
/20341/
/20341/?111
/20341/?222
have been normalized to the existing article cache.

4. EdgeOne Origin Pull Parameters Also Verified
Just seeing HIT is not enough.
I also need to prove:
When EdgeOne misses, the request received by the origin server has indeed had its Query String removed.
So I switched to a different article:
https://www.shuijingwanwq.com/2026/07/24/20084/
The client actually requested:
/2026/07/24/20084/?swq_eo_final_origin_1785162581209501862=1
EdgeOne returned:
HTTP/2 200
eo-cache-status: MISS
This indicates a real origin pull occurred this time.
Subsequently, I checked the server’s Nginx access log:
219.144.89.29 - - [27/Jul/2026:22:29:43 +0800]
"GET /2026/07/24/20084/ HTTP/1.1"
200 472412 "-"
"swq_eo_final_origin_1785162581209501862"
The client sent:
/20084/?swq_eo_final_origin_...=1
But Nginx actually received:
/20084/
Therefore, it can be confirmed that:
Client random Query String
↓
EdgeOne MISS
↓
Delete Query String
↓
Origin server receives canonical URL
This part was not inferred from the console configuration, but actually verified through the origin server’s logs.

5. Why I Stopped Handling URLs Without a Trailing Slash
During testing, I also tested:
https://www.shuijingwanwq.com/2026/07/27/20341
Result:
HTTP/2 301
x-redirect-by: Polylang
location: https://www.shuijingwanwq.com/2026/07/27/20341/
eo-cache-status: MISS
With random parameters:
/20341?swq_eo_noslash=...
Also redirected by Polylang 301.
Initially, I considered adding an EdgeOne rule to have the edge node directly append / to this type of URL.
But after further consideration, I felt it was unnecessary.
The normal flow can perfectly be:
/20341?abc=123
↓
WordPress / Polylang 301
↓
/20341/?abc=123
↓
EdgeOne canonical article rule
↓
Hits /20341/ cache
The only cost is that the first request without a trailing slash requires WordPress to generate a 301.
Currently, there is no evidence that such requests are numerous enough to cause noticeable server pressure.
Adding extra CDN redirect rules just to eliminate a single 301 would increase long-term maintenance costs.
So the final principle is:
Only protect the true canonical URL, and do not keep piling up CDN rules for extremely low-probability scenarios.
6. English Site Cloudflare Configuration
English site:
https://en.shuijingwanwq.com/
Uses Cloudflare.
Here I achieve the same goal:
/YYYY/MM/DD/ID/?random_parameters
Ultimately shares the cache with:
/YYYY/MM/DD/ID/
.
1. Using URL Rewrite Rule
The Cloudflare Free plan rules interface does not directly provide the regex matching capabilities I need, so I ultimately used the Rules Language string functions to restrict the article path.
The final condition is roughly:
(
http.host eq "en.shuijingwanwq.com"
and starts_with(http.request.uri.path, "/20")
and substring(http.request.uri.path, 5, 6) eq "/"
and substring(http.request.uri.path, 8, 9) eq "/"
and substring(http.request.uri.path, 11, 12) eq "/"
and ends_with(http.request.uri.path, "/")
and substring(http.request.uri.path, 12, -1) ne ""
and not (substring(http.request.uri.path, 12, -1) contains "/")
and http.request.uri.query ne ""
)
The target is still only:
/2026/07/14/19522/
And not:
/2026/07/14/19522
/2026/07/14/19522/feed/
/2026/07/14/19522/embed/

2. Do Not Modify Path, Only Delete Query
Action configuration:
Path:
Preserve
Query:
Rewrite to
Static
Empty value
Meaning:
/2026/07/14/19522/?abc=123
is processed internally by Cloudflare as:
/2026/07/14/19522/
The path itself remains unchanged.

7. Cloudflare Origin Pull Query String Deletion Verification
First test with random parameters:
/2026/07/14/19522/?swq_cf_slash=...
Cloudflare returned:
HTTP/2 200
cf-cache-status: MISS
Subsequently, I found the following in the server’s Nginx access log:
162.158.110.160 - - [27/Jul/2026:22:09:39 +0800]
"GET /2026/07/14/19522/ HTTP/2.0"
200 50901 "-" "curl/8.18.0"
Proving once again that:
Client:
/19522/?random_parameters
↓ Cloudflare
Origin server:
/19522/
The Query String did not reach WordPress.

8. Does Cloudflare Really Share the Cache?
Just proving “the origin pull has no parameters” is not enough.
The more critical question is:
/19522/
and:
/19522/?abc=123
Do they really use the same Cloudflare CDN cache entry?
So I conducted consecutive tests.
Results:
Standard URL first time
MISS
Standard URL second time
HIT
age: 5
Parameter 111
HIT
age: 8
Parameter 222
HIT
age: 11
Parameter 333
HIT
age: 16
Standard URL again
HIT
age: 19
And all these requests landed on:
AMS
the same Cloudflare node.
This result is already very clear:
/19522/
/19522/?111
/19522/?222
/19522/?333
All hit the same existing cache entry.
Particularly:
111
222
333
These are all new parameters that had not been accessed before, yet the very first request directly yielded:
CF-Cache-Status: HIT
And:
Age: 5 → 8 → 11 → 16 → 19
continuously increased.
Therefore, there is no need to create an additional Cloudflare Cache Rule.
A single URL Rewrite Rule has already fulfilled the current requirement.

9. Cloudflare Trailing Slash End-to-End Verification
Finally, I also tested:
/2026/07/14/19522?random_parameters
Letting curl automatically follow the 301.
Result of the first hop:
HTTP/2 301
location:
https://en.shuijingwanwq.com/2026/07/14/19522/?swq_cf_e2e_1785162314320989211=1
x-redirect-by: Polylang
cf-cache-status: MISS
Meaning:
/19522?random_parameters
↓
Polylang
↓
/19522/?random_parameters
Second hop:
HTTP/2 200
age: 524
cf-cache-status: HIT
The complete path becomes:
/19522?random=1
↓
Polylang 301
↓
/19522/?random=1
↓
Cloudflare URL Rewrite
↓
Query String normalized
↓
Hits existing /19522/ cache
Therefore, even without specifically optimizing URLs without a trailing slash, the request will ultimately return to the already optimized canonical CDN cache path.

10. Chinese and English Sites Finally Unified into the Same Design
After completing this round of adjustments, although the implementation methods of the two CDNs differ, their design philosophy is completely identical.
Chinese site EdgeOne:
www.shuijingwanwq.com
/YYYY/MM/DD/ID/
↓
Query String does not participate in Cache Key
↓
Different parameters share cache
↓ MISS
Origin pull deletes Query String
English site Cloudflare:
en.shuijingwanwq.com
/YYYY/MM/DD/ID/?parameters
↓
URL Rewrite deletes Query String
↓
Shares cache with canonical URL
↓ MISS
Origin server receives parameterless URL
And for those without a trailing slash:
/YYYY/MM/DD/ID
Both sides maintain the original canonical behavior of WordPress / Polylang:
/ID
↓ 301
/ID/
No longer adding special CDN logic for this layer.
11. In This Configuration, I Ultimately Valued “Simplicity” More
During this configuration process, there were actually many opportunities to continue optimizing.
For example:
- EdgeOne could additionally perform an edge 301 for missing trailing slashes;
- Cloudflare could add more Cache Rules;
- Various
/feed/,/embed/, and special parameter combinations could be further split and handled individually.
But when it comes to CDN configuration, more is not always better.
As rules continue to increase, another problem arises:
Six months later, even I would have trouble confirming exactly which rule a request hit.
So this time I ultimately chose a very clear boundary:
The CDN is only responsible for Query String cache normalization of canonical article URLs.
Issues that WordPress itself can handle normally, such as canonical 301s for missing trailing slashes, are left for WordPress to continue handling.
This design may not be theoretically “perfectly optimized”, but it is easier to maintain and better fits the actual needs of my current personal WordPress site.
12. Cloudflare 522 / 525 Still Occurred During Testing
While testing the English site, I also encountered:
522
525
multiple times. And I had noticed similar phenomena previously when publishing articles:
The first access might result in a Cloudflare 522 / 525, but requesting it again returns to normal.
A similar situation occurred during this test as well.
For example, when accessing from my home computer, some requests landed on:
LAX
LAS
and resulted in 522 / 525.
Later, when requesting directly from the server terminal, the requests landed on:
AMS
The complete:
301 → HIT
path was able to complete normally.
Currently, the server reports:
load average: 0.98, 0.90, 1.15
Memory:
Total: 1.9 GiB
Available: 889 MiB
And port 443 is normally listened to by Nginx.
Therefore, at this stage, it is not possible to conclude solely based on 522 / 525 that the ECS hardware is definitely insufficient.
Of course, I still believe that server performance might be one of the factors, and I may eventually need to upgrade the ECS.
But for now, I will not continue troubleshooting this issue.
This time, I first complete:
WordPress article Query String cache normalization for EdgeOne + Cloudflare.
The 522 / 525 issue will be left for later analysis as a separate problem, to avoid mixing CDN cache rules with origin server stability.
13. Final Result
At this point, the article detail pages for both frontend domains have achieved:
Random Query String
↓
Will not continuously create new article cache objects
↓
Canonical URL shares CDN cache
And when an actual origin pull is truly needed:
Request with random parameters
↓
CDN
↓
Origin server receives parameterless canonical URL
Most importantly, these conclusions were not judged solely based on the CDN console configuration, but were verified step by step through:
HIT / MISS
Age
301
Location
CF-Ray
Nginx access log
.
The final rules have also converged from the initial “cover all scenarios as much as possible” into a very easy-to-understand model:
Only /YYYY/MM/DD/ID/
falls under the CDN article detail page special optimization scope.
For my current website, I prefer this outcome.
Because it not only solves the cache penetration issue caused by random Query Strings, but also avoids turning the CDN configuration into another complex system that is difficult to maintain.
As for the occasional Cloudflare 522 / 525, that will be left for the next phase to decide separately: whether to continue optimizing the server configuration or directly upgrade the ECS hardware.
需要长期技术维护或远程问题排查?
我是拥有 15+ 年经验的 PHP / Go 后端工程师,长期关注已有系统维护、Bug 修复、性能优化、服务器排查、WordPress 网站维护和小功能迭代。
如果你的项目遇到以下情况,可以先从一次小问题排查开始合作:
- ✅ PHP / Laravel / Yii2 老项目无人维护
- ✅ Go / Gin 后端接口需要排查或优化
- ✅ WordPress 网站访问慢、报错或插件冲突
- ✅ Nginx / MySQL / Redis / Linux 服务器异常
- ✅ CDN / Cloudflare / DNS / HTTPS 配置问题
- ✅ 需要长期远程技术支持或兼职维护
更多介绍请查看:关于我 & 合作
微信:13980074657
邮箱:shuijingwanwq@gmail.com
Telegram:@shuijingwan
GitHub:https://github.com/shuijingwan
