WordPress Performance FAQ


Mike

My WooCommerce store performs well on cached static pages through Cloudflare, but during discount campaigns it collapses when many customers reach cart and checkout at the same time. CPU usage spikes heavily even though the public pages are cached.

Why does Cloudflare not solve this part of the load problem, and is the bottleneck mainly that cart and checkout are dynamic requests where WordPress, WooCommerce, plugins, sessions, shipping, taxes, payment logic, and database work still have to execute for every customer?

Sam

Yes. In most WooCommerce stores, that is exactly the reason.

Cloudflare can dramatically reduce load on anonymous, cacheable pages (home page, category pages, product pages, blog posts), but it usually cannot eliminate the expensive work that happens during cart and checkout.

Why Cloudflare helps product pages but not checkout

For a cached product page:

  1. Visitor requests page.
  2. Cloudflare serves HTML from its edge cache.
  3. PHP never runs.
  4. WordPress never loads.
  5. WooCommerce never loads.
  6. Database is not queried (or is queried far less often).

Your origin server does almost no work.

For cart and checkout:

  1. Visitor requests cart/checkout.
  2. Page is personalized to that customer.
  3. Cloudflare forwards request to origin.
  4. PHP executes.
  5. WordPress boots.
  6. WooCommerce loads.
  7. Session/cart data is read.
  8. Shipping rates may be calculated.
  9. Tax rules may be calculated.
  10. Coupons and discounts are evaluated.
  11. Inventory may be checked.
  12. Payment gateway logic runs.
  13. Multiple database queries occur.

This entire stack executes for every active shopper.

Why discount campaigns expose the problem

A flash sale creates a very different workload from normal browsing.

Imagine:

  • 10,000 visitors browsing products
  • 500 simultaneously adding items to carts
  • 200 simultaneously checking out

Cloudflare may absorb almost all of the 10,000 browsing visitors.

But the 500 cart users and 200 checkout users still hit the origin directly because those requests are personalized.

In practice, those few hundred checkout users often generate more server work than thousands of cached page views.

Why CPU spikes so hard

WooCommerce checkout is one of the most expensive operations in a WordPress stack.

Common CPU consumers include:

  • WooCommerce session handling
  • Cart recalculation on every change
  • Complex discount/coupon rules
  • Dynamic pricing plugins
  • Shipping calculators
  • Tax engines
  • Inventory validation
  • Payment gateway API interactions
  • Fraud detection plugins
  • Heavy WordPress hooks and filters
  • Excessive database queries

Many plugins hook into checkout events, so one checkout request may trigger dozens or hundreds of additional function calls.

Database pressure is often the real bottleneck

CPU spikes are frequently a symptom of database contention.

During a sale:

  • Many customers update carts simultaneously.
  • Session tables receive heavy writes.
  • Order tables receive inserts.
  • Inventory stock gets updated.
  • Transient caches are written and invalidated.

The database can become saturated even before PHP reaches 100% CPU.

Common symptoms:

  • Slow cart updates
  • Checkout timeouts
  • High MySQL CPU
  • Lock waits
  • Growing PHP worker queues

PHP workers become a limiting factor

A typical WooCommerce store might have:

  • 10–50 PHP workers

If checkout requests take 2–5 seconds each, workers become exhausted quickly.

Example:

  • 30 PHP workers
  • Checkout request takes 3 seconds

Maximum theoretical throughput:

  • ~10 checkout requests per second

Beyond that, requests queue up and response times explode.

This is often the first thing that collapses during promotions.

Why "Cloudflare caching everything" doesn't work

Cart and checkout pages contain customer-specific information:

  • Cart contents
  • Customer identity
  • Shipping address
  • Shipping methods
  • Taxes
  • Discounts
  • Payment tokens

Serving a cached checkout page would risk showing one customer's information to another customer.

Because of that, WooCommerce intentionally marks these pages as non-cacheable.

What usually improves sale-event performance

The biggest gains typically come from:

  1. Increasing PHP worker capacity.
  2. Using a dedicated database server or managed database.
  3. Optimizing slow WooCommerce plugins.
  4. Reducing checkout hooks and custom logic.
  5. Object caching (Redis).
  6. Fast persistent database storage.
  7. WooCommerce HPOS (High-Performance Order Storage) if not already enabled.
  8. Offloading search, analytics, and background jobs.
  9. Load testing before campaigns.
  10. Moving to infrastructure sized for concurrent checkouts rather than page views.

A useful mental model

Cloudflare protects the read-heavy, anonymous browsing layer of your store.

The bottleneck during a sale is usually the transaction-processing layer:

  • carts,
  • sessions,
  • checkout,
  • orders,
  • inventory,
  • taxes,
  • shipping,
  • payments,
  • database writes.

Those operations are inherently dynamic and personalized, so they still require your WooCommerce application and database to execute work for every customer. As a result, even a store that serves millions of cached page views efficiently can still struggle if its origin infrastructure cannot handle a surge of simultaneous cart and checkout activity.

Mike

That makes sense. But if the sale-event bottleneck is that hundreds of cart and checkout requests all hit the origin and each one executes WordPress, WooCommerce, sessions, plugins, hooks, shipping, taxes, payments, and database work, then adding more PHP workers or database capacity only increases how much of that workload the server can tolerate.

Shouldn't the deeper question also be how much unnecessary application work each checkout request is carrying?

In other words: if checkout truly needs WooCommerce, payment, tax, shipping, session, and security logic, but does not need unrelated gallery, form, SEO analysis, marketing, page-builder, or content features, would reducing the execution scope of every dynamic checkout request lower CPU pressure more directly than only scaling the infrastructure that executes the full stack?

Sam

Yes. In many WooCommerce environments, that is the more important question once basic infrastructure is no longer obviously undersized.

There are really two different strategies:

  1. Scale the amount of work you can process (more PHP workers, CPUs, database capacity).
  2. Reduce the amount of work each request performs.

The second strategy often produces larger gains because every optimization benefits every checkout request.

The hidden problem: WordPress boots the entire application

A checkout request doesn't load only WooCommerce.

Typically the request lifecycle looks more like:

  • PHP starts.
  • WordPress core loads.
  • Active plugins load.
  • Theme loads.
  • Hooks and filters register.
  • WooCommerce initializes.
  • Sessions load.
  • Cart loads.
  • Checkout logic executes.
  • Third-party integrations execute.
  • Database queries occur.

Even if a plugin has nothing to do with checkout, it may still:

  • initialize classes,
  • register hooks,
  • load configuration,
  • perform queries,
  • enqueue logic,
  • inspect requests.

One plugin might only add a few milliseconds. Twenty plugins can add hundreds.

Why "irrelevant" plugins matter

Consider a store with:

  • SEO plugin
  • form plugin
  • popup plugin
  • analytics plugin
  • affiliate plugin
  • page builder
  • review plugin
  • marketing automation plugin
  • search plugin
  • image optimization plugin

None of these are needed to charge a credit card.

Yet many still execute code during checkout because WordPress loads them globally.

This is one reason WooCommerce stores often become inefficient at scale: the checkout request is carrying the weight of the entire website.

A useful way to think about it

Suppose:

  • Current checkout request consumes 500 ms CPU time.
  • 200 concurrent customers arrive.

That's 100 CPU-seconds of work.

Now suppose infrastructure is doubled.

You can process more requests, but each request still costs 500 ms.

Alternatively, if optimization reduces checkout CPU cost to 250 ms:

  • Every server instantly handles roughly twice the checkout volume.

The effect is similar to doubling infrastructure, but without doubling infrastructure.

Where the biggest wins usually come from

1. Plugin auditing

This is often the highest ROI activity.

Ask:

  • Does this plugin need to run during checkout?
  • Does it execute queries on every request?
  • Does it hook into WooCommerce actions unnecessarily?

Many stores discover that marketing and reporting plugins consume more resources than WooCommerce itself.

2. Checkout-specific execution control

Some developers selectively disable plugins on:

  • cart
  • checkout
  • account
  • AJAX checkout endpoints

when those plugins provide no checkout functionality.

Examples:

  • page builders
  • popup systems
  • form builders
  • visual effects
  • content enhancements

This can noticeably reduce memory and CPU consumption.

3. Database query reduction

Often the real issue is not PHP execution but query volume.

A checkout request might generate:

  • cart queries,
  • session queries,
  • shipping queries,
  • tax queries,
  • plugin queries,
  • analytics queries,
  • recommendation queries.

Reducing queries from 100 to 40 can matter more than adding CPU.

4. External API calls

Many checkout slowdowns come from:

  • tax services,
  • fraud services,
  • shipping APIs,
  • CRM integrations,
  • ERP integrations.

If checkout waits on multiple external systems, PHP workers remain occupied while doing little actual computation.

Reducing synchronous API dependencies can dramatically improve throughput.

5. WooCommerce-specific optimization

Examples include:

  • High-Performance Order Storage (HPOS)
  • Redis object caching
  • optimized session storage
  • reducing autoloaded options
  • reducing cart recalculations
  • simplifying coupon logic
  • simplifying shipping rules

These reduce work that is directly related to commerce operations.

The architectural perspective

What you're describing is essentially the distinction between:

Capacity scaling

"How many checkout requests can the system process?"

and

Efficiency optimization

"How expensive is each checkout request?"

At moderate traffic levels, capacity upgrades are often enough.

At large sale-event volumes, efficiency becomes increasingly important because every unnecessary millisecond is multiplied by hundreds or thousands of simultaneous users.

A highly optimized WooCommerce checkout might execute only the logic necessary for:

  • cart state,
  • customer session,
  • inventory,
  • shipping,
  • tax,
  • payment,
  • order creation,

while minimizing everything else.

That's why large-scale e-commerce teams don't focus solely on adding servers. They also profile the checkout path aggressively and ask exactly the question you're asking: "What code is running here that doesn't need to be?"

For many WooCommerce stores, the fastest way to survive a major promotion is not just increasing PHP workers from 20 to 40; it's reducing the checkout workload enough that each worker can complete requests substantially faster. That improves throughput, lowers queueing, reduces database pressure, and often delays or eliminates the need for larger infrastructure.

Mike

That makes sense. But when you say "What code is running here that doesn't need to be?", shouldn't we distinguish between two different stages?

One stage is optimizing code after it has already joined the checkout request: reducing hooks, queries, API calls, recalculations, or custom logic.

The earlier stage is preventing unrelated code from joining the checkout request in the first place: not loading irrelevant plugins, services, hooks, and PHP runtime for that request at all.

During a discount campaign, every unnecessary millisecond is multiplied by hundreds of simultaneous checkout users. So wouldn't the strongest strategy be not only to make the checkout path cheaper, but to reduce the runtime that enters each checkout request before the expensive work begins?

Sam

Yes. That's an important distinction, and in many systems the second approach is more powerful than the first.

There are really three layers of optimization, not one:

Layer 1: Make loaded code run faster

This is the traditional optimization approach.

A plugin is already loaded, so you:

  • reduce database queries,
  • cache results,
  • remove slow hooks,
  • optimize algorithms,
  • reduce API calls.

The code still participates in the request, but does less work.

Layer 2: Prevent code from executing

A plugin or service is loaded, but much of its logic is bypassed.

For example:

  • skip analytics tracking during checkout,
  • disable recommendation engines,
  • avoid expensive reporting calculations,
  • bypass marketing automations.

This is better because the runtime avoids significant work, but the software still had to initialize.

Layer 3: Prevent code from loading at all

This is the architectural optimization you're describing.

The question becomes:

Why should checkout even know this plugin exists?

If a component contributes nothing to:

  • cart management,
  • checkout rendering,
  • taxes,
  • shipping,
  • inventory,
  • payment processing,
  • fraud/security,

then ideally it never enters the request lifecycle.

This removes:

  • plugin bootstrap time,
  • service container construction,
  • hook registration,
  • autoloading,
  • configuration loading,
  • object creation,
  • memory allocation.

before any business logic is reached.


Why this matters under concurrency

The effect is multiplicative.

Suppose an unrelated plugin adds:

  • 15 ms initialization time
  • 5 MB memory
  • a handful of hooks

On a normal day that seems insignificant.

During a flash sale:

  • 300 simultaneous checkout users
  • thousands of checkout requests per minute

That "small" cost becomes:

  • millions of extra function calls,
  • gigabytes of additional memory allocation,
  • significant CPU time.

The problem isn't the single request.

The problem is the aggregate effect across all concurrent requests.


The web-server analogy

Imagine a restaurant kitchen.

Optimization approach:

The dessert chef works faster.

Isolation approach:

Why is the dessert chef in the kitchen during breakfast service?

The second question often produces a larger gain.

If breakfast doesn't require dessert preparation, removing that entire workload from the breakfast workflow is more effective than making dessert preparation 20% faster.

Checkout optimization often follows the same principle.


Why WordPress can struggle here

WordPress was designed around a global plugin architecture.

Historically:

  1. Request arrives.
  2. WordPress loads.
  3. Active plugins load.
  4. Theme loads.
  5. Hooks register.
  6. Application decides what page is being requested.

This is flexible, but it means the system often discovers late that the request is a checkout request.

By the time checkout logic runs:

  • much of the application has already been initialized.

That differs from systems that build highly specialized request pipelines where only required components are loaded for a given route.


What large-scale commerce systems often optimize

At scale, teams increasingly ask:

What is the minimum runtime required to complete a purchase?

Not:

How can we make our full runtime slightly faster?

The ideal checkout execution path becomes something close to:

  • request handling,
  • authentication/session,
  • cart state,
  • inventory,
  • shipping,
  • tax,
  • payment,
  • order creation.

Everything else becomes optional.

Examples of things frequently excluded or minimized:

  • visual builders,
  • content management features,
  • SEO tooling,
  • analytics dashboards,
  • form systems,
  • marketing automation,
  • recommendation engines,
  • editorial functionality.

Not because they're bad, but because they don't contribute directly to converting a cart into an order.


Why this often beats pure scaling

Scaling infrastructure increases capacity linearly.

Reducing runtime scope often improves multiple bottlenecks simultaneously:

  • lower CPU consumption,
  • lower memory usage,
  • fewer database queries,
  • fewer lock conflicts,
  • fewer PHP workers occupied,
  • lower latency,
  • higher throughput.

As a result, removing 30–40% of unnecessary request initialization can sometimes provide benefits comparable to a substantial infrastructure upgrade.

So yes: for a WooCommerce store that already understands that cart and checkout are the bottleneck, one of the most valuable questions is not merely "How can we optimize the checkout code?" but "What parts of the application should never have entered the checkout request in the first place?"

That shifts the focus from tuning individual operations to reducing the size of the execution environment itself, which is often where the largest efficiency gains are found during high-concurrency sales events.

Mike

This is exactly where LiteCache Rush applies its principle of Performance by Prevention. During a discount campaign, the problem is not only that many customers reach checkout at the same time, but that every dynamic checkout request may carry unnecessary parts of the WordPress and plugin runtime with it. Traditional scaling adds more capacity for the same workload; traditional optimization makes parts of that workload cheaper. Rush targets the earlier layer: it identifies the request context before the full plugin stack is loaded and prevents unrelated PHP and plugin execution from entering the checkout path in the first place. Under high concurrency, this matters disproportionately because every avoided millisecond, hook, query opportunity, service initialization, and plugin bootstrap is multiplied across all simultaneous checkout users.