Implementation Scheme of WordPress Multi-Active Architecture (Simplified Version) in Personal Blogs
This article was last updated 103 days ago, and the information within it may have evolved or changed. If it is no longer valid, please leave a comment in the comment section.
Article Abstract
To address the issue of blog service interruption caused by home internet outages, a multi-active architecture based on Cloudflare Tunnel is constructed to achieve intelligent traffic distribution and node disaster recovery switching. Combined with rsync for lightweight data synchronization, and adopting a primary-write node strategy with Cloudflare Worker to handle comment write conflicts. This solution effectively avoids the risk of single point of failure in personal blog scenarios. Through distributed node deployment and automated synchronization mechanisms, it achieves high service availability and data consistency, while relying on Cloudflare APO to optimize architectural performance, providing a stable and reliable multi-active disaster recovery solution for personal blogs.
Qwen3-14B · 2026-06-18

1 Introduction

The original spark that inspired me to build a WordPress multi-active solution was actually very simple: that time my home internet was cut off by Telecom for a full 3 days without any warning (see the article for details:Home Data Center Series: Discussing Current Options for Personal Blog Building from This Home Internet Outage). Because at that time, my blog's WordPress had only one node in the home data center, which directly caused the blog to go down completely and become inaccessible. Although I urgently migrated the data to Tencent Cloud's lightweight server and restored access about 2 hours later, the frustration of that period is still deeply engraved in my memory. It was at that exact moment that I made up my mind: I must build a true WordPress active-active architecture (at that time I only thought of active-active), so that even if something goes wrong with the home blog, it can seamlessly switch to the backup node immediately, avoiding the embarrassing situation of “a perfectly fine blog suddenly disappearing.”

However, at that time, I had been building and running the blog for less than a year. Much of my knowledge was still in a fragmented exploration stage, and the system was far from complete. In the end, after much tossing and turning, I had to settle for the next best thing and set up a half-baked disaster recovery solution to prevent similar incidents from happening again (see the article for details:Home Data Center Series: Utilizing Cloudflare Tunnel to Achieve Automatic Takeover by Disaster Recovery Site When WordPress Main Site Fails)。

This disaster recovery solution did seem to solve the urgent problem at the time, but looking back now, it had a very obvious, almost fatal flaw: how could the Tencent Cloud node accurately and reliably determine whether the home macmini (main site) had actually experienced an anomaly? The solutions I could think of back then were quite crude—either running scheduled scripts on Tencent Cloud to directly access https://blog.tangwudi.com a certain uncached liveness probe page to judge whether the home service was normal, or directly accessing the WordPress page on the macmini via Tailscale's intranet IP to see if it loaded normally.

However, both of these methods had obvious shortcomings:

  • The former was easily affected by various external factors, including network routes, and the detection results might not accurately reflect the true availability of the site;
  • While the latter could more intuitively detect the running status of WordPress on the macmini, it relied entirely on Tailscale on both ends. If Tailscale on either end experienced an anomaly, it could lead to a misjudgment by the Tencent Cloud node, causing it to be in the UP state simultaneously with the main node.

In addition, this disaster recovery switching was only “passive takeover,” which could only achieve 1 active and 1 disaster recovery, and could not achieve true multi-active synchronization (at that time, I had no idea how to solve the WordPress database synchronization problem, nor did I understand the working principle of Cloudflare Tunnel's multi-connector at all). This prompted me to continuously explore active-active and even dynamically scalable multi-active architectures suitable for personal blogs, which was only completely overhauled after migrating the VPS from Tencent Cloud to Racknerd (see the article:Home Data Center Series: The Second Reconstruction of Blog Architecture: Service Migration and Active-Active Disaster Recovery Practice Triggered by VPS Migrationand was subsequently optimized (see the article:Home Data Center Series: The Third Optimization of Blog Architecture: WordPress Active-Active Node Adjustment and Database Import Precautions)。

Note: This article focuses on describing the architectural solution. For technical implementation and configuration steps, please refer to the practical article links provided in the text to avoid repetition and maintain a clear structure.

2 Technical Challenges Faced by WordPress Multi-Active Solutions

However, to actually implement a dynamically scalable, true WordPress multi-active architecture is far from as simple as preparing a few more servers for mutual backup and periodically synchronizing the database.

The technical challenges it faces can be summarized from three levels:

image.png

Traffic Scheduling: Nearest Access and Disaster Recovery Switching

First of all, how to intelligently route user traffic to the nearest and healthy node. This involves the most common global traffic scheduling solutions like DNS round-robin, GeoDNS, or F5 GTM, and also requires solving the health check problem: for example, how to avoid allocating user traffic to a node that has actually crashed due to detection latency? And how to achieve rapid switching after a node failure, while automatically restoring it back to the traffic pool once the node recovers? These seemingly normal requirements actually require very solid health monitoring and traffic switching mechanisms behind them.

Data Synchronization: Multi-Node Consistency and File Resources

Then there is the more troublesome issue of multi-node data consistency. WordPress is not just about synchronizing article and comment data at the database level; it also requires considering whether user-uploaded multimedia files should be synchronized to each node locally, or simply mounted on object storage or a distributed file system.

Even if the database uses master-slave, dual-master, or more advanced Galera Cluster, it still needs to solve write conflicts, data latency, and split-brain issues. Even if all of these are done, caches like Redis and Memcached still need to find a way to synchronize across regions; otherwise, different nodes might still read inconsistent page states.

Write Conflicts and Read-Write Separation

Further down is the write issue. In a multi-active scenario, if users initiate writes (such as posting comments, registering, or uploading files) on different nodes, it can easily lead to conflicts or version confusion. In traditional architectures, read-write separation is often used to avoid this: all write requests are routed to the primary node, while other nodes are only responsible for reads, ensuring things don't get too messy through delayed replication or eventual consistency.


It seems natural, but in fact, every step requires many mechanisms to work together. These things look like just a few arrows on an architecture diagram and sound perfectly normal, but to actually implement them one by one at the underlying level, almost every link requires a multiplied cost: whether it is cross-regional multi-active file synchronization, consistency protocols for distributed databases, or global DNS liveness probing and dynamic routing. Because of this, most personal blog webmasters choose at most a single node + CDN approach for peace of mind, and very few people bother with a true multi-active architecture—because it is just too easy to get yourself tangled up.


Fortunately, mine is just a simple personal blog (with registration closed, so there's no need to worry about the trouble caused by user data writes). The vast majority of access requests are reads, and write requests are mostly ”controlled writes” (regularly publishing or modifying articles), with very few ”uncontrolled writes” (just occasional comments). Therefore, on these three seemingly extremely serious multi-active topics, I can actually make some bold compromises:

At the traffic scheduling level

For a personal blog, there is actually no need to pursue enterprise-grade millisecond-level multi-dimensional health checks, automatic removal of failed nodes, and dynamic load weight adjustment. As long as traffic can be reasonably distributed to multiple available nodes, the risk of a single point of failure is already significantly reduced. Even if a node suddenly goes down and occasional requests are routed to the failed node and return errors, it is completely acceptable.

At the data synchronization and consistency level

My site is mainly for reading articles and consists mostly of static content. Even if there is some delay in data synchronization between different nodes, it will not affect the normal access experience of most users. Occasional out-of-sync dynamic data like comments in this scenario won't cause any real issues (and probably no one will even notice~). As for media files, as long as they are kept consistent across nodes beforehand, there is no need for those complex distributed file or object storage solutions.

At the write conflict and read-write separation level

If this were an e-commerce or social network scenario, write conflicts and data consistency would almost certainly have to be treated very seriously, usually relying on single-point writes or distributed consensus solutions to ensure correctness. But my blog has very few write requests, with almost zero pressure from high-concurrency writes. Even with occasional operations in the backend or visitors posting comments, it rarely triggers any real conflict risks, let alone affecting overall data integrity.

Therefore, these seemingly “compromised” practices that lower active-active technical standards are actually rational choices based entirely on the actual usage scenarios of my personal blog: even traffic scheduling, data consistency, and write conflict issues—which must be treated very seriously in professional architectures—can be weakened or delayed to some extent here. As long as I can prevent the blog from going completely offline just because my home internet gets disconnected, that is enough for me.

What's more, by choosing the right combination of technologies, many seemingly missing parts can actually be compensated for to some extent.

3 Multi-Active Traffic Scheduling Based on Cloudflare Tunnel

Compared to the traffic scheduling methods of self-built active-active data centers in traditional commercial environments (such as intelligent DNS resolution and global load balancing systems represented by F5 GTM), it is obviously not suitable to adopt this approach for distributing traffic across active-active nodes for a personal blog.

Not only because these solutions are costly and complex to configure, but also because they often rely on proprietary BGP Anycast, regional health checks, or require cooperation with multiple ISPs to achieve global routing optimization, which is simply out of reach for individual webmasters.

Fortunately,the generous Cloudflare provides Tunnel (formerly known as Argo Tunnel), which naturally comes with multi-node ingress distribution and nearest-node scheduling capabilitiesIt can automatically detect availability across Cloudflare's global edge network and route traffic to the node closest to the visitor with the fastest response. This not only significantly reduces the difficulty of my own investment in DNS, health checks, and routing optimization, but also solves the problem of removing failed nodes along the way.


It should be noted that although Cloudflare Tunnel provides multi-node ingress distribution and nearest-node scheduling capabilities for free, strictly speaking, this is actually just abest effort mechanism, officially described as follows:

image.png

The original official documentation address is as follows:Tunnel availability and failover。

Its active-active implementation simply allows you to run the connector of the same tunnel on multiple servers simultaneously. This way, Cloudflare's edge network can prioritize forwarding requests to the most appropriate node based on the user's geographic location and network conditions. If a node fails or cannot be detected, it will automatically switch to other available nodes (for more explanations on the relationship between physical locations, tunnels, and connectors, see the article:Home Data Center Series Cloudflare Tutorial (9) Introduction to Common Zero Trust Features and Multi-Scenario Usage Tutorial)。

However, it should be made clear that this is not intelligent traffic scheduling in the traditional sense: there is no fine-grained traffic ratio control, nor are there strict round-robin or hash allocation algorithms. Cloudflare's scheduling relies more on health checks and dynamic estimation of network distance between edge nodes and connectors. Most of the time, it achieves reasonably close access, but it is still only “best effort.” For example, even though the Chicago node is several times faster than my home data center in terms of network latency, and theoretically users' requests should all go to the Chicago node first, the reality is that a small number of requests are still occasionally routed back home. For large commercial systems that strictly require millisecond-level optimization, this uncertainty is unacceptable, but it is completely tolerable in my personal blog scenario.

So overall, this model is more suitable as an ingress guarantee in high-availability scenarios to avoid single points of failure, rather than for precise traffic load balancing. For me, as long as other nodes can still take over traffic when my home internet is unplugged, a server goes down, or there is a power outage, and the blog remains available to the outside world, I am satisfied.


Since a single Cloudflare Tunnel supports a maximum of 25 active replicas (official documentation address:https://developers.cloudflare.com/cloudflare-one/account-limits/):

image.png

Therefore, theoretically speaking, this active-active architecture supports scaling up to a maximum of 25 nodes, which does have a limit, but it is already enough for a personal blog~.

4 Additional Discussion: Cloudflare Tunnel and "Fully Closed" Security Architecture

The previous chapters mainly discussed how to use Cloudflare Tunnel to achieve traffic scheduling for an active-active architecture. But in fact, the benefits Cloudflare Tunnel brings me are not just the intelligent distribution of traffic, but also that it fundamentally changes the traditional security boundary concept based on "public IP + port".

In the past, we were used to barely maintaining server security with firewall rules: for example, only opening 80/443 for HTTP(S), only opening 22 for SSH to fixed IP ranges, and dropping everything else. However, as long as these well-known ports are exposed to the internet, they will inevitably be targeted by countless scanners—masscan, zmap, nmap, automated weak password brute-forcing, and various web vulnerability scanning scripts, knocking on your door almost every minute. Even if you configure your firewall and Fail2Ban meticulously, the logs will still grow like a pile of garbage, filled with connection probes, suspicious requests, and even DDoS floods. The scariest part is that this “being seen” itself exposes your existence: as long as attackers detect that port 22 or 443 is alive, they can put you into the next round of more precise attack pools.

Cloudflare Tunnel, on the other hand, almost physically eliminates this problem. Its core mechanism is an encrypted persistent connection initiated actively from the VPS to Cloudflare's edge nodes, with absolutely no need to open any ports to the public internet. This means you can directly drop all inbound traffic (TCP, UDP, ICMP) on the VPS, making your machine completely disappear from the internet. All port scans, vulnerability probes, and automated attacks targeting your IP will fail at the very first step, because to them, this machine simply does not exist (another prerequisite is that there should not be any DNS resolution pointing to the VPS's public IP, otherwise it will still leak—just look at the first step of any penetration test to know why).

As a result, application entry points are all published using the public hostnames configured in the Tunnel, and all security pressure is naturally transferred to Cloudflare—as long as you configure WAF, rate limiting, Bot management, and DDoS protection in the Dashboard, it is already enough to fend off the vast majority of threats (at this point, how to truly make good use of Cloudflare is key; friends who are not familiar can refer to:Cloudflare Learning Map)

image.png

and your VPS becomes a “black hole node” in the truest sense: with no ingress, there is naturally no way to breach it:

Note 1: The ideal is plump, but reality is skinny. Theoretically, such a fully closed strategy could even allow SSH to be operated through Tailscale's private network (since Tailscale is also based on outbound connections, which fits this closed model perfectly; I used to do this on Tencent Cloud Lighthouse servers). However, cross-border Tailscale traffic is severely degraded in my scenario, making it almost unusable. I had to settle for the next best thing: opening a high port for the SSH service (never use port 22 directly), allowing only SSH public key authentication, and disabling password login. This minimizes the exposure as much as possible while still allowing the use of scp, rsync, and other methods that can transfer files based on SSH connections.

Note 2: By default, Cloudflare Tunnel uses QUIC-based outbound connections (UDP 443 + TLS). This has very distinct traffic characteristics and is easily identified and interfered with in domestic network environments. For greater stability, it is recommended to switch it to HTTP/2 mode to reduce the risk of being targeted. For specific operations, please refer to the article:Home Data Center Series: From QUIC to HTTP2: Building a More Covert and Stable Cloudflare Tunnel Solution。

5 Lightweight Data Synchronization and Consistency Practice Based on rsync (Multi-Active Scenario)

1 Selection of Data Synchronization Solutions

To use the multi-node ingress distribution and nearest-routing capabilities provided by Cloudflare Tunnel introduced in the previous chapter to achieve an active-active architecture, a natural prerequisite is:The content provided by each node must be completely consistent. Otherwise, no matter how intelligent the traffic scheduling is, if users access different nodes and see inconsistent data, the active-active architecture loses its meaning.

In typical commercial scenarios, to achieve data consistency across multiple nodes, the following types of solutions are usually adopted:

  • Master-Slave Replication: For example, the most common master-slave structure in MySQL and PostgreSQL, with single-point writing and multi-point reading, relying on binlog or WAL logs for real-time replay on remote nodes.
  • Bidirectional Replication or Multi-Master (Master-Master): Writing is allowed at both locations, requiring the additional introduction of conflict detection and resolution, such as Galera Cluster or MySQL Group Replication.
  • Distributed Databases (NewSQL/NoSQL): Such as CockroachDB, TiDB, and Cassandra, which ensure cross-node data consistency through distributed protocols like Paxos/Raft, at the cost of more complex maintenance and higher network quality requirements.
  • File-level Distributed Storage: Such as CephFS and GlusterFS, which disperse files and metadata across multiple nodes through multi-replica and consistency protocols.

These are very common in large companies and multinational internet projects, ensuring very strict consistency for reads and writes across multiple nodes in different geographical locations, but they also have very significant prerequisites:Requiring reliable network quality and extremely low latency, otherwise it will lead to a sharp increase in latency, lock timeouts, and even serious problems like split-brain.

Unfortunately, looking back at my scenario—my home data center is in China, and the other node is on a Racknerd Chicago VPS, relying entirely on cross-border lines in between, with high network latency, large jitter, and frequent packet loss. Using the enterprise-grade distributed synchronization solutions mentioned above is simply unrealistic; even TCP connections might be reset constantly, let alone relying on database clusters with stable heartbeats and strict consistency.

So in the end, I could only choose a morelightweight, loosely consistentapproach: deploy an independent WordPress instance in both the home data center and the Chicago node, then export the WordPress database from the home data center node, sync the database file to the Chicago node, and import it. This keeps the content consistent most of the time (in fact, as long as I haven't published new articles, modified articles, or received new comments, it is consistent). This way, even if the cross-border line is terrible, it won't block normal read and write operations on the local node.

Note: Currently, because there are very few comments (sometimes not even one a week), I am temporarily still using a manual trigger method to export the WordPress database files. If the number of comments really increases, I will need to upgrade to a regular export and synchronization method.

2 Why Choose rsync as the Synchronization Tool?

As for the specific method of synchronizing database files, I have actually tried quite a few solutions.

In the beginning, I tried to use Syncthing between my home data center and the Chicago VPS (for specific configuration details, please refer to another article:Docker Series: Detailed Tutorial on Implementing Multi-Point Folder Synchronization Based on Syncthing Using Docker) combined with Tailscale's private IP to achieve peer-to-peer automatic synchronization. This solution works quite well in local area networks or within China, with almost zero latency (this is how I used to synchronize database files with Tencent Cloud servers). However, once it crosses borders, it becomes unbearable: Tailscale's traffic is severely degraded on transnational links, making even SSH or web page access extremely slow, let alone using it to transfer database files of tens or hundreds of megabytes.

And because I had already designed a “fully closed” security architecture before, I was reluctant to expose another synchronization port for Syncthing on the public network, so I had to regretfully give up this idea.

Later, because I had already opened a high-port SSH for operations on the Chicago VPS, I turned to the most primitive and worry-free solution: directly using SCP to transfer database files. Under normal circumstances, this method is actually simple and easy to use, with almost zero configuration when combined with SSH public key authentication (for the specific configuration of SSH public key authentication, please refer to the article:Debian Series: Configuring SSH Public Key Login). However, once the cross-border line acts up, SCP's full single-transmission characteristic becomes a fatal shortcoming, often getting stuck at a certain progress percentage and directly timing out and failing, requiring a restart from the beginning, even if it is only a few MBs short.

Ultimately, I returned to rsync, which is more professional and better suited for unstable link environments: it not only naturally supports resuming broken transfers, but can also optimize resuming behavior through parameters like --partial and --append-verify, minimizing transmission costs to the greatest extent possible. Combined with a simple shell loop script for automatic retries upon failure, even if the line quality occasionally fluctuates, it can quietly move the data bit by bit, eventually becoming my best choice for active-active database synchronization (for specific details, please refer to the article:Home Data Center Series: Elegantly Solving the Chronic Illness of Transnational VPS File Synchronization with rsync)。

6 Primary-Write Node and Write Conflict Avoidance under Multi-Active Architecture

In the previous chapter, since we are exporting database files from the WordPress of the home data center node and synchronizing them to the WordPress of the Chicago node, it has already been determined that the WordPress of the home data center node must serve as the primary write node. This is also the most suitable way for my daily management. After all, I usually manage WordPress on the Mac mini directly through the intranet IP to publish and modify articles, and even approve and reply to comments.


To explain this primary write node mode more clearly, let me insert a detail from the operations level.

The Chicago node only has one high-port SSH open and only allows public key authentication, so it is impossible to directly log into the admin dashboard using a public IP like at home (of course, SSH port forwarding is also an option, but I am too lazy to open a tunnel every time).

Although the Chicago node's WordPress can be accessed through Tailscale, the cross-border speed is unfortunately too slow, so it can only be used as an emergency measure and is not suitable for daily management.

Therefore, letting the home data center's WordPress act as the sole primary write node and then pushing the modified data to other nodes is the most hassle-free and convenient way. Most importantly, even if more nodes are added in the future, it is just a matter of adding a few more commands to the script; the script still only needs to be executed once to complete the synchronization, without significantly increasing the operational burden.


If it were only these ”write” actions, there would be no such thing as write conflicts at all, because these are all controllable writes. The most critical part is another ”write” action that, although low in frequency, is uncontrollable: comments. If we rely solely on Cloudflare Tunnel's built-in active-active traffic scheduling capability, the result would be a high probability of writing to the Chicago node's WordPress and a low probability of writing to the home data center node's WordPress. This is unacceptable for me, who treats the home data center node as the primary write node. So, how do we ensure that comments can be written to the home data center node?

In the early days, the most direct approach wasto force all user comment requests to be routed to the primary node's database for writing, ensuring data source consistency and centralized management. To achieve this goal, common approaches include:

  1. Cross-domain writing solution: Configure CORS headers in the primary node's WordPress to allow other read-only nodes to submit comments directly to the primary node (e.g., comment.tangwudi.com) via JavaScript AJAX requests. This method is relatively simple to implement, but involves browser cross-domain restrictions, requiring proper configuration of response headers such as Access-Control-Allow-Origin and handling Cookie scope issues.

  2. Reverse proxy write-back solution: In the Web Server of each read-only node, reverse proxy the user's POST requests to admin-ajax.php or wp-comments-post.php to the primary node. This method is transparent to users, requires no modification of front-end code, and has no cross-domain issues. However, in practice, attention must be paid to details such as session persistence and cache penetration; otherwise, issues like lost authentication or CSRF validation failure can easily occur.

I have tried both methods, and both were too troublesome and extremely easy to run into pitfalls, giving me a real headache.

Ultimately, I chose a solution that is both lightweight and best fits the current state of my distributed network—with the help of Cloudflare Worker as an intelligent transit layer for comment writing.

By deploying Workers on Cloudflare's global edge nodes, comment submission requests can be intercepted at the location closest to the visitor, and then actively forwarded by the Worker to my backend nodes for actual writing.

Doing so has several obvious advantages:

  • No need to modify any front-end code (unlike CORS, which requires rewriting Ajax submission logic),
  • Naturally bypasses browser cross-domain security restrictions,
  • While also allowing for an extra layer of protection, auditing, and rate limiting at the edge.

In the Worker-based writing solution, it can be further divided into two different strategies:

Write only to the primary node (home data center)

This is the most “classic” single-point writing approach, which ensures that all comment data is concentrated in the home node's database, completely avoiding conflicts or data forks that multi-point writing might cause. However, the disadvantages are equally obvious: first, if the home node briefly loses connection, the comment submission will fail directly, resulting in a very poor user experience; second, before synchronizing to other nodes, if a visitor is assigned to the Chicago node by Cloudflare, they will not be able to immediately see the comment they just submitted.

Write to all nodes simultaneously

That is, after receiving a comment request, the Worker directly sends concurrent POSTs of the same comment to both the home node and the Chicago node, achieving simultaneous writing to multiple databases. This way, no matter which node subsequent visitors are scheduled to, they can see their comments immediately, significantly reducing visibility differences caused by synchronization cycles.

However, it should be noted that this “crude” method of multi-point writing gives up the strict consistency of a single data source. In very rare cases (for example, after configuring cache, different nodes generate different auto-increment IDs for comments, causing the cached ID seen by visitors to mismatch the actual reply node's ID), it may cause nested comment failures. But for a very low-concurrency scenario like my personal blog, this occasional inconsistency is completely acceptable, in exchange for better instant visibility (and I can also control the timing of replying to comments, unless a few visitors are chatting in the comment section themselves~). Even if duplicates or reply anomalies occasionally occur, it is far better than having the comment function go down completely when the home network is disconnected.

Under such trade-offs, I ultimately chose the second solution:Let Cloudflare Worker write comments to all nodes simultaneouslyFor a personal blog where almost no one has “real-time conversations” in the comment section, this is instead the simplest and most direct high-availability solution (for specific technical details of this part, please refer to the article:Home Data Center Series: Solving the Comment Synchronization Problem in WordPress Active-Active Architecture with Cloudflare Worker)。

7 Cloudflare APO: Giving the Multi-Active Architecture a True Makeover

1 Limitations of the Existing Multi-Active Architecture

Speaking of which, you might find a rather interesting question: although the entire set of active-active traffic scheduling based on Cloudflare Tunnel, combined with rsync synchronization and primary write node controlled writing, has achieved true multi-node availability.But in essence, it does not actually break away from the traditional WordPress operational paradigm—every time a user visits, it still has to go back to a certain node to execute PHP + MySQL, dynamically generate the page, and return it to the user.

So it still relies on:

  • The PHP / Nginx / MySQL performance of each node itself.
  • Relying on Redis or Memcached for object caching.
  • Relying on various classic local optimization plugins like WP Rocket, Autoptimize, and Query Monitor.
  • Even relying on nodes not failing, not suddenly having hard drive damage, database crashes, php-fpm memory exhaustion...

Most importantly, under this architecture,there is no real “buffer zone”:

  • Once a certain node experiences a PHP error, database downtime, or even just a brief network fluctuation, Cloudflare Tunnel will still distribute user requests to this node, and users will directly hit 502, 504, or 500 errors.
  • If there is a small issue with the Chicago node, users in the eastern US are the first to hit it; if the home data center's network cable is unplugged, domestic users are the first to feel it.

Under such a model, although the active-active architecture improves availability and reduces the risk of single points of failure, the user experience is still easily exposed directly at the node level, without any buffer.

2 Cloudflare APO

2.1 What is Cloudflare APO?

When it comes to improving WordPress performance, most people first think of installing various caching plugins, such as W3 Total Cache, WP Super Cache, or using Redis/Memcached for object caching. These solutions indeed allow a single server to handle more user requests, but they still run locally on the node and still rely on the node's CPU, memory, and IO performance to process requests.

Cloudflare APO fundamentally changes this approach, turning the local access model of WordPress into a cloud-cached access model. So, what exactly is Cloudflare APO?

Cloudflare APO (Automatic Platform Optimization), is a “smart edge whole-site caching” solution launched by Cloudflare for WordPress (and multiple platforms gradually supported later). Its core concept is very simple: instead of letting users visit your server every time, having PHP+MySQL dynamically generate HTML and then return it to the user, it is better to cache the complete page (HTML) directly on the Cloudflare node closest to the user.

The result of doing this is:

  • The vast majority of user requests are hit directly at Cloudflare's 300+ global data centers, without triggering any origin pull at all.
  • Only upon the first visit or after the cache expires will Cloudflare pull the page from your origin server.
  • What users get is a “complete page already generated at the edge,” which is not only fast, but also drastically reduces the load on your server.

2.2 Differences Between Cloudflare APO and Traditional CDNs

Many people might say at first glance: What's the difference between this and a regular CDN? Haven't we been able to cache static assets all over the world for a long time?

Actually, there is a big difference:

  • Traditional CDN usually only caches files that have appropriate Cache-Control or Expires headers set, whereas most websites by default only add these headers to JS, CSS, and images, and HTML pages are often not cached. To make a CDN cache HTML, you usually have to configure additional rules on the server or in the CDN. Dynamic sites like WordPress do not generate cacheable response headers for HTML pages by default. To make it work well with traditional CDNs, you need to manually install a bunch of caching plugins, write purge hook scripts, and go through a lot of hassle.
  • Cloudflare APO's is specifically tailored for WordPress. It actively communicates with your WordPress via WP's REST API or XML-RPC, sensing in real-time whether a new post is published, a comment is approved, or a menu is modified... As long as there is a change, it can immediately trigger cache invalidation across all Cloudflare edge nodes globally, automatically refreshing the HTML page cache, truly achieving "whole-site edge caching of dynamic content."

In other words, APO provides a dynamic whole-site caching solution for WordPress, allowing your blog to deliver complete pages directly at the edge almost globally, without worrying about out-of-sync updates or needing complex custom purges.

To put it more clearly, after enabling APO, Cloudflare will: cache complete HTML pages across the entire site, not just images and scripts; monitor whether your site publishes/updates posts, receives comments, or has menu structure changes; once site data updates are detected, it actively calls the invalidation API in the background to notify Cloudflare's global edge nodes to clear the cache of the relevant pages.

This is far superior to a typical Nginx FastCGI Cache or a general CDN because: you don't have to manually write any purge scripts; you don't need to install a bunch of plugins in WordPress just to work with caching (such as W3TC's page caching + cache invalidation hooks); for comments and new posts, APO can update all edge nodes almost in real-time. Therefore, at $5/month, APO is, in my opinion, one of the most high-value and no-brainer investments for WordPress users.

Of course, you can also use Cloudflare Workers to manually implement a free ”budget version of APO” (for details, you can refer to my previous article:Home Data Center Series Cloudflare Tutorial (7): Introduction to CF Worker Features and Practical Operation, Verification, and Related Technical Principles of Implementing ”Budget Version of APO for WordPress” Based on Workers to Accelerate Website Access), but the dynamic content caching and version management of this solution rely on a plugin called “Cloudflare Page Cache”, which hasn't been updated for many years and is no longer available on Cloudflare's official GitHub page, so I don't even know if it still works properly. On the other hand, this solution relies on Cloudflare's KV, and the free tier KV space always makes me a bit uneasy—even with very little usage, it's easy to receive a warning email from Cloudflare saying "50% used", which is just annoying to see.

So, this kind of free DIY hassle is really not necessary: since you already have WordPress up and running, you might as well spend $5 to let Cloudflare officially handle cache hosting, active purging, and global acceleration for you, which is much more worry-free and effortless. And if you have already subscribed to Cloudflare Pro, APO is included for free, meaning you don't even have to pay this $5, which is an absolute steal for WordPress users.

Note: For a comparison of the feature differences between Free and Pro users, you can refer to this article:Home Data Center Series: In-depth Experience with Cloudflare Pro: From Free to Pro, Is It Really Worth the Upgrade?。

However, APO may also fail during use due to some unexpected factors (such as cookies). I encountered this once before, and troubleshooting took me quite a lot of time. Interested friends can refer to the article:Home Data Center Series: Analysis of Cloudflare APO Cache Invalidation: Causes and Solutions for Cf-Cache-Status BYPASS。


Actually, it's not that many bloggers don't know that publishing a WordPress site directly using a VPS public IP is neither secure nor guarantees high availability, but they end up doing it anyway. Why? Because once CDN caching is involved, the complexity immediately increases tenfold, and you have to constantly run into issues and debug them yourself. Compared to this, running it bare, although risky, wins on being simple and direct.

This is precisely why WordPress (and indeed most dynamic CMSs) has long been criticized for poor performance and fragile security:

  • Under high concurrency, PHP + MySQL cannot hold up and easily crash.
  • Once the VPS is attacked (such as the common XML-RPC amplification attacks in older WordPress versions, or brute-force enumeration of the WP-JSON interface), it easily returns a 502 error.
  • Without a cache buffering layer, users will perceive any minor failure immediately.

In reality, small websites and low-traffic websites (personal blogs, portfolios) usually just go with public IP + Nginx + PHP-FPM directly, not bothering with such complexity. But once you pursue global acceleration, high concurrency resistance, and active-active setups, you will fall into the deep pit of complex cache management. APO actually solves these common pitfalls all at once with “WordPress awareness + automatic purge + comprehensive HTML caching.” Because of this, only those who have personally maintained WordPress CDN caching can truly appreciate how much operations and maintenance effort APO can save.


2.3 Providing a True "Buffer Zone" for Multi-Active Architecture

For scenarios like mine that already have a WordPress active-active architecture, APO turns the ”multi-point origin pull” of regular requests under the active-active architecture into a response model that is ”dominated by Cloudflare's edge network, supplemented by WordPress node origin pulls”:

  • In an active-active architecture without APO, user visits are distributed to different WordPress nodes via Cloudflare Tunnel, and the nodes directly bear the task of generating pages with PHP + MySQL.
  • With APO, users don't access specific nodes at all; 99% of requests are handled by Cloudflare at the edge, and nodes are only pulled to generate pages after the cache expires.

This not only significantly improves performance but also greatly enhances availability—even if a node experiences brief network fluctuations, PHP errors, or even temporary database unavailability, users will hardly notice because Cloudflare has already cached the complete HTML pages in its global edge network, truly making the active-active architecture not just “multi-node available,” but also adding a strong layer of isolation and protection at the user experience level.。

In other words, even if one of your nodes is literally on fire in the background, visitors can still get the complete page directly from the nearest Cloudflare node without noticing any backend anomalies. This is the true value provided by APO under an active-active architecture: even if a node fails, there are other nodes to handle origin fetch, continuing to provide fresh blood for the global edge cache.

Of course, if you only have a single-node architecture, the situation is different—once the origin site fails completely, although Cloudflare can continue to serve users with stale cache for a short time, it will soon display an “Origin Unavailable” prompt, and the cache cannot be updated further, which is equivalent to losing subsequent protection.

Note 1: Such an architecture also brings some new troubles. For example, the inconsistent comment ID issue mentioned earlier: since origin fetch has now shifted to multiple independent WordPress nodes, visitors submitting comments at different times or locations might write to databases of different nodes, resulting in different auto-increment IDs. This kind of problem would never exist in a single-node architecture, but it is the norm in today's distributed origin-fetch active-active environment. It is not caused by APO; rather, while APO accelerates access and shields node failures, it makes these multi-node differences more easily exposed, requiring backend data synchronization to balance them out.

Note 2: Under an active-active architecture with APO enabled, the number of nodes actually doesn't need to be "the more, the better" as in traditional setups. Because the vast majority of user requests are already hit and returned directly at Cloudflare's edge network, and the server only bears the responsibility of origin fetch when there is a cache miss. Therefore, the significance of the active-active architecture has also shifted from sharing pressure and improving concurrency in the past to a more pure guarantee of availability—as long as there is one node in each different geographical location, like my current setup: one at home and one overseas, it is enough to cope with the vast majority of risks, as it is almost impossible for both to fail at the same time. Even if one of the nodes goes down or suffers a network outage, Cloudflare can still automatically route origin fetch requests to the other node, and users will not perceive any issues with the backend at all. Compared to the past era of having to add machines, tune PHP, install Redis, and plug in cache plugins everywhere just to handle more traffic, this architecture is much more relaxed, completely shifting the focus of O&M to keeping nodes online rather than obsessing over how to push single-machine limits.

8 WordPress Optimization Ideas under Multi-Active Architecture

1 Ramblings

In the previous chapters, the most core technical structure has actually been built: multi-node + Cloudflare Tunnel's nearest routing, rsync's lightweight synchronization, plus APO directly pushing HTML to the edge, making this WordPress active-active architecture both distributed and high-performance.

However, from a technical perspective, this is actually just ”usable.” If you want to operate and maintain it more elegantly in the long run, you can completely build upon this architecture to further reduce weight, cloudify, and automate for active-active scenarios.

2 Weight Reduction: No Longer Needing the Burden of Traditional Local Optimization

In the single-node era, WordPress optimization was almost a cliché:

  • Installing Redis / Memcached locally for object caching
  • Layering various caching plugins like W3TC, WP Rocket, and Autoptimize
  • And being careful not to over-cache, which could cause issues with comments, pagination, and sessions

Under the current architecture, however, almost all traffic is taken over by APO, with HTML pages returned directly at the edge, and only a small number of comments written to the origin-fetch nodes. This means you can completely uninstall Redis and various local caching plugins, and there is no need to perform special tuning for PHP and Nginx to handle pressure. You only need to ensure that php-fpm does not crash. WordPress goes back to being the purest publishing system, with low machine load and easier maintenance.

3 Cloudification: What Can Be Handled by Cloudflare Should Not Be Kept Locally

Since the site has already been multi-node enabled, many functions that previously relied heavily on local environments can also be cloudified as well, such as:

In short, moving as many functions as possible to the Cloudflare layer makes the backend cleaner.

4 Automation and Observability: Less Worry for O&M

Multi-node sounds beautiful, but daily maintenance is obviously more troublesome than a single node: Which node died? Which synchronization failed? Are comment writes normal?

If manually staring at logs is obviously unrealistic, here I mainly utilize the Health Checks and Notifications features provided by Cloudflare, combined with a self-built webhook (pushed to mobile via Bark, technical details can refer to the article:Docker Series: Building a Message Push Server Based on Bark Server) to make multi-node monitoring more automated.

  • Cloudflare Health Checks: This feature allows you to configure HTTP checks directly on Cloudflare, such as periodically visiting specific pages on your bloghttps://blog.tangwudi.com/xxx, and if consecutive probes fail, it will trigger an alarm.
  • Cloudflare Notifications: On the dashboard, you can configure health checks and various security events (WAF triggered, IP blocked, etc.) as event sources, supporting alerts sent via email, Slack, Webhook, etc.
  • Webhook + Bark: I wrote a lightweight transit script myself to receive webhook notifications from Cloudflare Worker and forward them to Bark for iPhone notifications; some Cloudflare Notifications events can be directly notified to the phone via Bark.
  • Shell + Email / Bark: The local rsync synchronization script also has simple error catching, such as automatically retrying a few times if synchronization fails, and alerting me via email or Bark if it fails consecutively.

Doing this, even though the multi-node architecture adds complexity behind the scenes, there is almost no need to keep an eye on it during daily maintenance, and I can receive push notifications on my phone immediately if something goes wrong.

For the specific practice of this part of the functionality, please refer to the article:Home Data Center Series Cloudflare Monitoring and Alerting Combination in Action: Lightweight O&M Experience Brought by Health Checks + Event Alerts, which is also covered in some of the previous articles, though a bit scattered, as O&M needs are everywhere.

9 The Ultimate Insurance of Multi-Active Architecture: Static Site Fallback

Honestly, for a small blog with little traffic, setting up a Cloudflare Tunnel active-active architecture and APO global edge caching is already “self-indulgent” enough. To then add another layer of a purely static site as a fallback sounds almost like ensuring the continuous availability of some “core financial business system,” which is somewhat chuunibyou (over-dramatic).

But this is actually just my personal little obsession—having spent over half a year gradually perfecting this architecture, since I can take one more step, why not just cover even the most extreme accidents?

So came this step: using Simply Static plugin to generate purely static pages for the entire WordPress site and deploy them to Cloudflare Pages, thereby having an ultimate life-saving solution that still provides normal reading access even if the database completely crashes, PHP cannot run, and all Cloudflare Tunnels lose connection.

If one day in the future all dynamic nodes unfortunately have problems, visitors can still be caught by the static version of the blog deployed on Cloudflare Pages:https://staticblog.tangwudi.comeven if they can't see the latest comments or post comments, it's still better than a direct 502.

As for the specific usage of the Simply Static plugin, I have already recorded it in detail in another article:Home Data Center Series: Making WordPress Sites Static via the Simply Static Plugin, so I won't repeat it here.

10 Summary

Writing up to this point, I have basically sorted out all my tinkering around the WordPress active-active architecture over the past half year: from initially running WordPress on a single node on a Mac mini at home, to being forced to set up a disaster recovery node on a Tencent Cloud Lighthouse server after telecom inexplicably blocked my network; and then, after the Tencent Cloud server expired, due to the expensive renewal price, simply migrating to Racknerd's Chicago VPS node to officially start tinkering with active-active. Along this journey, I gradually developed this complete architecture based on Cloudflare Tunnel for global nearest distribution, redundant origin nodes, using rsync to ensure data consistency, using Worker to coordinate multi-point writes, and finally relying on APO to “remove” PHP from the user access path:

image.png

Its essence is actually turning WordPress—the core combat unit that once had to be online at all times—into a redundant origin node that can be replaced at any time and is not afraid of being offline for a while: even if PHP hangs, users can still read the complete pages from Cloudflare's edge nodes, barely noticing any backend anomalies; if a node's database crashes or a VPS is temporarily down for maintenance, it's just a matter of syncing and fixing it later; even if comments occasionally fail to write, it's just a minor episode for a few users, far more relaxed than the heart-stopping panic when the server went down under the old single-node model.

Friends who want to try building it themselves can directly refer to the solution architecture and related deployment scripts I have compiled. The repository address is:https://github.com/tangwudi1979/multiwp-tunnel。


This article is just a milestone summary of my continuous pit-falling, correcting, tinkering, and exploring over the past half year, a way of giving myself closure. But precisely because of this “idealized goal,” I was able to tirelessly tear things down and start over again and again, gradually clarifying those originally vague details, and in the process, learning more about underlying networking, cache consistency, and active-active availability concepts. Perhaps these solutions have no direct reference value for the vast majority of people, but for me, it is a real personal network exploration notebook, and a small milestone worth recording during this period.


View Related Categories · 3 Matches
📌 Content Structure Prompt:
This content is part of the following knowledge map, where you can view the complete content path: Cloudflare Learning Map · WordPress Learning Roadmap。
📎 Related Articles
Share this article
The blog content is original, please indicate the source when reposting! The RSS address of the blog is:https://blog.tangwudi.com/feed, welcome to subscribe; if needed, you can join theTelegram Groupto discuss questions together.
No Comments

Send Comment Edit Comment


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗ
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
Kaomoji
Emoji
Little Dinosaur
Flower!
Previous
Next
       

👋 Welcome to “Wudi's Personal Blog”

Here, long-term exploration is mainly carried out around the following directions:

🧱 Personal Digital Infrastructure and Blog System Construction
☁️ Cloudflare and Network Architecture Practice
🧠 AI and Knowledge System Exploration
🛡️ Network Security and Access Optimization
🎵 Music and Sound Cognition
👁️ Cognitive Perspectives and Worldviews