Optimization

Sizing a VPS for a WooCommerce store by concurrent checkout load

Every WooCommerce store owner feels the pain: the site loads fine when you browse products, but at checkout, when a customer enters billing details and clicks "Place order", the page stalls, spins, and sometimes fails. That is not a cache problem. Product pages, category listings, and even the cart page can be cached aggressively. The checkout is page-dynamic by design: it needs to validate coupons, calculate shipping, check stock, process payment gateway callbacks, and write the order to the database. None of that can be served from cache. So if your VPS is undersized for the concurrent checkout load you actually get, you are losing orders.

结账页面无法缓存,容量要按并发结账数来估算。

Checkout pages cannot be cached, so size the server by concurrent checkouts.

This article maps every concurrent checkout session to its server resource cost, RAM, CPU, disk IO, and PHP worker, so you can pick the exact VPS tier that matches your traffic, no more no less. We will use a WooCommerce VPS requirements table that you can apply directly to any provider, including the infrastructure offered by thueVPS (a Vietnam-based provider that runs its own Tier 3 datacenters co-located with VNPT, Viettel, and FPT Telecom, you do not need a Vietnamese entity to buy their services).

Why checkout is the bottleneck, and caching will not fix it

A typical WooCommerce store uses a stack of Nginx (or LiteSpeed), PHP-FPM with a PHP opcode cache, MariaDB/MySQL, and Redis for object caching. For product pages, you can layer on a full-page cache (LiteSpeed Cache, WP Rocket, or Nginx FastCGI cache) and serve 95% of visitors from static HTML. But the checkout page is explicitly excluded from every caching plugin, because caching a form that contains session-specific data would leak one customer's information to another.

Every time a customer hits /checkout/ and clicks "Place order", the server goes through:

  • A PHP worker fetches the session, cart, and customer data from the database or Redis.
  • WooCommerce recalculates tax and shipping.
  • Coupon discount rules are evaluated.
  • Stock is checked and reserved.
  • The payment gateway sends a request (often over cURL) to Stripe, PayPal, or a local gateway.
  • The order is written to wp_posts and wp_postmeta.
  • A confirmation email is queued.

This entire chain runs synchronously on one PHP-FPM worker. While the worker is busy (often 2-5 seconds per checkout), it blocks other PHP-FPM child processes from serving the same checkout page. If you have 10 concurrent customers all checking out, you need at least 10 PHP workers free and enough CPU to not stall them all at once. That is the core of WooCommerce VPS requirements: concurrent checkout sessions translate directly to RAM and vCPU demand.

The sizing table: map concurrent checkouts to VPS resources

The numbers below are derived from profiling a moderate WooCommerce store (300 SKUs, 2-3 shipping zones, 5 coupon rules, no heavy custom plugins). Results will vary with store complexity, but the ratios hold. Memory usage is measured as RSS (Resident Set Size) of the PHP-FPM child process during the checkout wp_ajax_checkout call.

Peak concurrent checkoutsRAM recommendationvCPU recommendationPHP workersIOPS-sensitive?
1-32 GB1-2 vCPU4-8Low
4-104 GB2-4 vCPU8-16Medium
11-258 GB4-6 vCPU16-32High
26-6016 GB6-8 vCPU32-64High
60+32 GB+8+ vCPU64+Very high

Why IOPS matters: At 25+ concurrent checkouts, MySQL becomes the bottleneck. The checkout writes to multiple tables in a transaction, and if your disk cannot handle the write queue depth, transactions wait. An NVMe SSD (like thueVPS uses on all plans) has 100x the IOPS of a spinning disk and handles this easily. But even a budget VPS with a shared NVMe can saturate at high concurrency, that is when you want a dedicated VPS or a plan with more dedicated resources.

Step 1, Measure your actual concurrent checkout peak

Before buying a VPS, you need data. Install a real-time analytics tool (or use server logs) to find the maximum number of simultaneous "Place order" hits during a 24-hour window. The simplest method: tail your Nginx access log for the /checkout/ endpoint and count requests within a 1-second sliding window using a command like:

tail -f /var/log/nginx/access.log | grep "/checkout/" | awk '{print $4}' | cut -d: -f2-4 | sort | uniq -c | sort -rn | head -20

If you see a count of 12 in one second, that means 12 concurrent checkouts at peak, place yourself in the 11-25 row of the table. If you do not have access logs, use the WooCommerce analytics reports under WooCommerce → Reports → Orders and look at the busiest hour, then divide by 3600 to get approximate concurrency. It will be lower than the real peak, but it gives you a starting point.

Step 2, Map the peak to a VPS tier (with real provider examples)

Using the table, pick the RAM and vCPU that cover 150% of your observed peak to leave headroom. A store with 10 concurrent checkouts at peak should aim for 4 GB RAM and 2-4 vCPUs, not the 2 GB that might serve product cache traffic just fine.

Here is how that maps to thueVPS plans (which you can order as a WordPress VPS with pre-optimized PHP-FPM and Redis):

  • 1-3 concurrent checkouts: VNLite (1 vCPU, 2 GB RAM, 20 GB NVMe). Enough for a small store with 1-3 employees testing orders.
  • 4-10 concurrent checkouts: VNx1 (1 vCPU, 4 GB RAM, 50 GB NVMe) or VNx2 (2 vCPU, 4 GB RAM, 50 GB NVMe). This is the sweet spot for most growing stores.
  • 11-25 concurrent checkouts: VNx4 (4 vCPU, 8 GB RAM, 80 GB NVMe). Runs about 16 PHP workers comfortably.
  • 26-60 concurrent checkouts: VNx8 (8 vCPU, 16 GB RAM, 100 GB NVMe). This handles a flash sale or a promotion day.

All thueVPS plans include a dedicated Vietnam IPv4, NVMe storage, full root/Administrator access, daily snapshots, and monthly billing. If you need more isolation, for example, your store hits 60+ concurrent checkouts during a Cyber Monday event, their dedicated server tier gives you the entire server, IPKVM for out-of-band access, and unlimited bandwidth.

Step 3, Tune PHP-FPM and MySQL for the chosen tier

Once your VPS is provisioned, configure PHP-FPM to match. A common mistake is to run the default pm.max_children setting (usually 5). For a 4 GB VPS with 10 concurrent checkouts, a safe starting config is:

pm = dynamic
pm.max_children = 16
pm.start_servers = 4
pm.min_spare_servers = 2
pm.max_spare_servers = 8
php_admin_value[memory_limit] = 256M

Each PHP worker can use up to 256 MB. 16 workers × 256 MB = 4 GB, which fills the VPS. Leave 500 MB for MySQL and the OS.

MySQL (or MariaDB) should have its InnoDB buffer pool set to about 60% of available RAM after the PHP allocation. For a 4 GB VPS with 3 GB free after OS and PHP, set:

[mysqld]
innodb_buffer_pool_size = 1.8G
innodb_log_file_size = 512M
innodb_flush_log_at_trx_commit = 2

innodb_flush_log_at_trx_commit = 2 trades a tiny bit of durability safety for 2-3x faster write throughput, acceptable for WooCommerce because the order is also held in PHP session until confirmed by the gateway.

Step 4, Test under load

Do not trust a sizing table blindly. Use a load testing tool like k6 or wrk2 to simulate your checkout peak. A basic k6 script that hits the checkout endpoint with 10 virtual users for 60 seconds will reveal whether PHP-FPM maxes out, or MySQL connections pool up. Run:

k6 run --vus 10 --duration 60s checkout-test.js

Watch htop on the server. If any vCPU stays at 100% while others are idle, you need a faster single-thread performance (clock speed) rather than more vCPUs. If all vCPUs are 100% and RAM is below 80%, you need more CPU cores. If RAM reaches 90%+ and swap starts to fill, you need more RAM.

Checkout load and network: does the VPS location matter?

The checkout experience also depends on latency between the customer and your server. A few hundred milliseconds of extra round-trip time on the checkout page can feel like a hang because the page makes multiple AJAX calls (cart update, shipping calculator, coupon validation). If your customers are in Vietnam, or if your payment gateway needs a local IPv4 (some Vietnamese banks require a Vietnam IP for callback security), a Vietnam VPS is the right choice. That is exactly what thueVPS offers: their datacenters are inside Viettel IDC and VNPT IDC, both Tier 3 facilities with domestic peering that keeps latency under 5-10 ms for Vietnamese ISPs.

For customers outside Vietnam, a Vietnam VPS is not a magic fast pipe. The connection hops through international transit and the result depends on the user's own domestic network. In that case, choose a VPS located close to your customer base, or put a CDN in front of product pages while keeping the checkout API on a server with a local IP for your payment providers.

Common mistakes in WooCommerce VPS sizing

  • Buying too much CPU, not enough RAM: WooCommerce-checkout PHP workers consume RAM, not just CPU. A 2 vCPU / 1 GB VPS will run out of memory before it runs out of CPU cycles.
  • Enabling the default WooCommerce queue without Redis: Outgoing emails and stock syncs are queued by default. Small VPS without Redis backend for the queue can spawn too many MySQL queries and stall checkout.
  • Not setting a PHP-FPM status page: Without pm.status_path, you cannot tell how many workers are active. Add pm.status_path = /status to your pool config to check live worker count.
  • Sharing a VPS with other sites: If the VPS runs multiple WordPress installations, another site's traffic spike can steal PHP workers from your WooCommerce checkout. Get a dedicated VPS for the store.

FAQ

How much RAM does one WooCommerce checkout session use?

Approximately 150-200 MB of RSS (Resident Set Size) on the PHP-FPM worker for a typical store. That number can go to 300 MB if you run heavy plugins like conditional shipping logic, multi-currency, or subscription cart calculations.

Do I need more RAM for the database?

Yes. MariaDB uses memory for the InnoDB buffer pool and query cache. For a 2 GB VPS, set the buffer pool to no more than 512 MB. For a 4 GB VPS, 1-1.5 GB. The rest goes to PHP and the OS.

Can I use object caching to reduce MySQL load during checkout?

Only partially. WooCommerce stores session and cart in the database or an object cache. If you use Redis for object caching, these lookups are faster. But the order write itself must hit the database, caching does not eliminate that. Redis reduces the read load but not the write load.

What happens if my VPS runs out of memory during a checkout rush?

The OOM killer kills the largest RAM consumer, usually a PHP worker, which cancels a checkout mid-way. The customer sees a 500 error and does not complete the order. Monitor dmesg | grep oom or configure a swap file, but swap is slow and a sudden peak can still exhaust it.

Should I use LiteSpeed on a VPS for WooCommerce checkout?

LiteSpeed helps with cached pages but the checkout is uncacheable, so the main gain from LiteSpeed is its PHP-FPM replacement (LSAPI) which can be slightly more efficient. For the same VPS tier, LiteSpeed gives a 5-10% edge on PHP throughput, measurable but not a tier shift. Nginx + PHP-FPM is fine for most stores.

Does thueVPS offer a VPS pre-optimized for WooCommerce?

Yes, their WordPress VPS plans come with LiteSpeed or Nginx pre-configured, Redis, and PHP-FPM tuned for WooCommerce. The control panel also includes one-click staging and staging-to-production sync, which helps when testing checkout changes.

Related articles

Note: This guide is for general reference. Every system and infrastructure has its own specifics, so test each step in a safe environment and consult a qualified engineer before applying it in production.

按并发结账量为WooCommerce选型

结账页面无法缓存,容量必须按并发结账数来估算。文中把并发量映射到CPU和内存需求,并给出压测方法。促销期的峰值应单独计算。