E-commerce and CMS websites (WordPress, Magento, Joomla, etc.) place mixed and often unpredictable loads on web servers: many cached reads (static content, product pages) plus occasional heavy dynamic operations (cart, checkout, search). NGINX is a widely used high-performance web server and reverse proxy that—when correctly tuned and paired with PHP-FPM and caching—can deliver substantial throughput and low latency on modest VPS hardware. This white paper describes a repeatable performance-testing methodology for NGINX on VPS, practical tuning and caching strategies for e-commerce/CMS workloads, representative use cases, and an operational checklist for deployment and capacity planning. Key guidance is grounded in NGINX’s own testing guidance and modern benchmarking tools. (blog.nginx.org)

Performance Testing of NGINX on VPS for e-commerce and CMS Websites

Executive summary

E-commerce and CMS websites (WordPress, Magento, Joomla, etc.) place mixed and often unpredictable loads on web servers: many cached reads (static content, product pages) plus occasional heavy dynamic operations (cart, checkout, search). NGINX is a widely used high-performance web server and reverse proxy that—when correctly tuned and paired with PHP-FPM and caching—can deliver substantial throughput and low latency on modest VPS hardware. This white paper describes a repeatable performance-testing methodology for NGINX on VPS, practical tuning and caching strategies for e-commerce/CMS workloads, representative use cases, and an operational checklist for deployment and capacity planning. Key guidance is grounded in NGINX’s own testing guidance and modern benchmarking tools. (blog.nginx.org)

Background and problem statement

Small and medium-sized e-commerce/CMS sites commonly run on VPS instances to control cost while needing to remain responsive under seasonal spikes (sales, promotions). Misconfiguration, lack of caching, and PHP backend bottlenecks cause degraded page load times, failed checkouts, revenue loss, and bad search engine signals. Performance testing on representative VPS instances answers crucial questions:

  • What throughput (requests/sec) and concurrency can a given VPS handle for static, cached, and dynamic pages?
  • Where are the bottlenecks — NGINX, disk I/O, PHP-FPM, database, or network?
  • What tuning and caching policies produce the best cost-to-performance ratio?

NGINX documentation and engineering blogs recommend a methodical baseline → identify → tune → validate workflow for web server performance testing. (blog.nginx.org)

Goals and success metrics

Primary goals for the test program:

  1. Measure baseline requests per second (RPS), latency (median and p95/p99), and error rate for:
    • Pure static asset serving (HTML/CSS/JS/images).
    • Cached dynamic pages (NGINX FastCGI/Proxy cache).
    • Fully dynamic pages requiring PHP and DB access (cart, checkout).
  2. Identify resource utilization at RPS targets: CPU, RAM, disk I/O, network, and PHP-FPM worker saturation.
  3. Provide actionable tuning and caching recommendations to increase sustainable RPS and reduce latency.

Success metrics:

  • Median time-to-first-byte (TTFB) < 200 ms for cached pages under target concurrency.
  • Error rate < 0.1% during sustained load.
  • Clear headroom (e.g., 20–30% spare CPU) at expected peak traffic.

Test environment and hardware profile (example)

For reproducibility, describe the VPS used and software stack. Use the following as a representative configuration (adjust to your provider):

  • VPS (2 vCPU, 4 GB RAM, 80 GB SSD, 1 Gbps network) — typical small production tier.
  • OS: Ubuntu 24.04 LTS (or equivalent stable Linux).
  • NGINX Open Source (stable or mainline), configured with worker_processes auto; sendfile on, tcp_nopush, tcp_nodelay, keepalive_timeout tuned.
  • PHP: PHP-FPM 8.x with tuned pm mode (dynamic/static/adaptive depending on workload).
  • Database: MySQL/MariaDB on a separate managed instance for repeatability (or local for smaller tests).
  • Caching layers tested:
    • NGINX FastCGI cache / proxy_cache for full-page caching.
    • Upstream caching via Redis or Memcached for fragment caching (application level).
  • Benchmark host: separate machine (or cloud instance) with wrk/wrk2 or rewrk to avoid client saturation.
  • Monitoring: collect CPU, memory, iowait, netstat, NGINX stub_status, PHP-FPM status, and DB metrics.

Document exact kernel and network settings (e.g., sysctl net.core.somaxconn, fs.file-max) and ensure swap is disabled for pure performance runs.

Benchmarking methodology — repeatable and reliable

Use a structured approach that avoids misleading results:

  1. Baseline warm-up: Start with a short warm-up run (2–5 minutes) to populate caches, then reset measurements for the steady-state test. NGINX and PHP caches should be warmed when measuring cached scenarios.
  2. Use appropriate tools: Use multithreaded, high-precision generators like wrk/wrk2, rewrk, or reqstress. wrk2 (or wrk with fixed-rate modes) produces consistent request rates and realistic concurrency; community guidance and benchmark collections recommend these tools for NGINX testing. (GitHub)
  3. Test multiple realistic profiles:
    • Static file serving (small file, large file).
    • Cacheable page (simulate WordPress full-page cache or Magento cached product pages).
    • Dynamic cart/checkout workflows (POST, sessions, DB writes) — these should be tested separately and sparingly because write operations cannot be cached.
    • Combination/real traffic mix: e.g., 70% cached GETs, 20% static assets, 10% dynamic POSTs.
  4. Sustained runs and step tests: Run sustained tests (5–15 minutes) and step load tests increasing concurrency or RPS to map degradation points (latency cliffs, error onset).
  5. Instrumentation & metrics collection: Continuously log NGINX metrics (stub_status), vmstat, iostat, dstat, top, htop and PHP-FPM / DB stats. Capture latencies (median, p95, p99), RPS, and HTTP error responses.
  6. Avoid client bottlenecks: Use a remote client with higher CPU/network capacity than the VPS to ensure the generator isn’t the limiting factor.

Example benchmark commands

Static:
wrk -t12 -c400 -d300s http://example.com/static/large.js

Cached page (fixed rate, wrk2):
wrk2 -t4 -c100 -d300s -R5000 http://example.com/product/123

Dynamic (mixed with Lua script):
wrk -t8 -c200 -d300s -s scripts/shopping.lua http://example.com/

(Use separate machines for client and server; collect nginx_access.log and error.log for correlation.)

Tuning recommendations for NGINX on VPS

Below are practical, battle-tested configuration recommendations. Test each change incrementally and measure impact.

  1. Worker model and file descriptors
    • worker_processes auto; (aligns with CPU cores).
    • worker_connections tuned high: e.g., worker_connections 10240; then ensure ulimit -n and fs.file-max are sufficient. This increases possible concurrent connections per worker. (Gist)
  2. Network and I/O helpers
    • sendfile on; tcp_nopush on; tcp_nodelay on; — improve throughput for static files.
    • Tune kernel: net.core.somaxconn, net.ipv4.tcp_max_syn_backlog, net.ipv4.tcp_tw_reuse where appropriate.
  3. Keepalive and timeouts
    • keepalive_timeout 15; for client keepalives but balance with connection resource limits.
    • Increase keepalive_requests to reduce TCP handshake overhead for browsers and CDNs.
  4. Compression and SSL
    • Enable gzip for text assets; tune gzip_comp_level to balance CPU vs size.
    • Offload TLS when possible (use modern TLS ciphers and allow session resumption); test TLS throughput since HTTPS transactions add CPU cost. NGINX benchmarking guides include HTTPS results as an important axis. (blog.nginx.org)
  5. Buffer sizes
    • Adjust client_body_buffer_size, client_header_buffer_size, and large_client_header_buffers for application needs (especially sites with large cookies).
  6. Caching: FastCGI / proxy_cache
    • Use fastcgi_cache (or proxy_cache) for cacheable WordPress pages and product pages. Cache static HTML and set proper Cache-Control headers for edge cases. Properly purge or use surrogate keys for invalidation. FastCGI cache can dramatically reduce PHP and DB load. Guidance and tutorials for WordPress caching show major improvements when applied correctly. (RunCloud Website)
  7. Upstream and PHP-FPM
    • Use keepalive in upstream definitions to reuse upstream connections to PHP-FPM backends.
    • Configure PHP-FPM pm to dynamic or ondemand with max_children sized to memory and CPU. Monitor slowlog and tune opcache. For Magento/WooCommerce, tuned PHP-FPM is essential to handle peak requests without swapping; hosting providers document Magento-specific PHP-FPM tuning practices. (Liquid Web)
  8. Offload static assets
    • Use a CDN for large assets (images, videos). On VPS, serving everything from the origin reduces available CPU for dynamic work.

Use cases and practical guidance

Use case A — Small WooCommerce store on a 2 vCPU VPS

  • Workload: ~5k monthly visits, occasional sale spikes.
  • Recommended stack:
    • NGINX + PHP-FPM with FastCGI cache for product/category pages (cache rules that exclude cart/checkout).
    • Redis for object caching; MySQL hosted separately.
    • CDN for images.
  • Expected outcome: Cached product pages served with sub-200ms TTFB; checkout remains dynamic but isolated.

Use case B — Medium Magento shop during promotion

  • Workload: bursts up to thousands of concurrent users.
  • Recommended changes:
    • Move DB off VPS to managed DB cluster.
    • Aggressive NGINX caching for catalog pages; careful cache invalidation on product update.
    • Scale to 4+ vCPUs for application layer; use load balancer with multiple app nodes for true high availability.
  • Rationale: Magento is resource hungry and benefits from horizontal scaling and caching. Use provider-specific best practices for PHP-FPM and caching. (Liquid Web)

Use case C — CMS blog with heavy static content

  • Serve through NGINX with sendfile, tcp_nopush, keepalive, and gzip; use OpenGraph image CDN. Static profile enables very high RPS on small VPS.

Interpreting results and common failure modes

When running tests, watch for:

  • CPU saturation — indicates need for more CPU or reduced per-request CPU (enable caching, lower compression level).
  • High iowait — symptomatic of slow disk (use SSD or tmpfs for hot cache metadata).
  • PHP-FPM queueing — slow PHP workers show as queue buildup and increasing p95 latency. Increase workers or optimize PHP code.
  • Network limits — check for dropped packets or NIC saturation on VPS plan; upgrade plan or use multi-region CDN.
  • Client errors (5xx) — often configuration, upstream timeouts, or out-of-file-descriptors.

Document the point at which median latency increases sharply and the error rate rises: that’s your operational capacity limit for the given configuration and workload profile.

Operational checklist for production

  1. Maintain a separate benchmarking environment that mirrors production as much as possible.
  2. Automate tests (CI jobs) to run after config changes and before major launches.
  3. Monitor in production: NGINX stub_status, PHP-FPM status page, DB metrics, system metrics. Set alerts for high p95 latency or error rates.
  4. Keep a runbook for scaling: how to increase worker_processes, add nodes behind a load balancer, enable/disable caching, and purge caches safely.
  5. Plan for Black Friday/seasonal spikes well in advance: scale horizontally, increase caching TTLs for non-critical pages, use pre-warmed caches and CDNs.

Recommendations — summary

  • Measure before you tune. Baselines are essential. NGINX’s own testing guides recommend a baseline → test → tune cycle. (blog.nginx.org)
  • Use appropriate tools. Use wrk/wrk2 or equivalent for high-fidelity benchmarking. (GitHub)
  • Leverage caching. For e-commerce/CMS, NGINX FastCGI/proxy cache reduces PHP and DB load dramatically when applied to cacheable pages; ensure safe invalidation. (RunCloud Website)
  • Tune kernel and NGINX settings incrementally. worker_processes, worker_connections, sendfile, keepalives, and buffer sizes are high-impact settings. (Gist)
  • Optimize PHP-FPM and DB. For dynamic pages (checkout, admin), PHP and DB tuning are often the true bottlenecks; consider managed DB and dedicated app nodes for growth. (Liquid Web)

Limitations and future work

This paper outlines methodology and configuration guidance without presenting new lab numbers from a controlled lab run. Exact RPS and latency depend on VPS provider, CPU generation, kernel tuning, application code quality, and network conditions. The next recommended step for any team is to run the benchmark plan (tools and scripts above) on their target VPS types and iterate using the baseline→tune→validate cycle described.

Conclusion

NGINX on a well-tuned VPS is an excellent platform for small and medium e-commerce and CMS sites. The combination of proper worker tuning, kernel/network tweaks, aggressive but safe caching (FastCGI/proxy cache), tuned PHP-FPM, and offloading static assets to a CDN yields high throughput and low latency at low cost. A structured benchmarking program using wrk/wrk2, careful instrumentation, and staged tuning enables teams to quantify capacity, find bottlenecks, and make cost-effective scaling choices.

References

  1. Testing the Performance of NGINX and NGINX Plus Web Servers, NGINX blog (Aug 24, 2017). — NGINX’s own test methodology and baseline metrics. (blog.nginx.org)
  2. Performance Tuning: Tips & Tricks, NGINX blog (Dec 18, 2017). — Recommended tuning workflow and config guidance. (blog.nginx.org)
  3. Awesome HTTP Benchmark (benchmark tools list) — curated list of modern benchmarking tools including wrk, rewrk, etc. — useful for choosing the right generator. (GitHub)
  4. How To Use NGINX FastCGI Cache to Speed Up WordPress, RunCloud (updated 2025) — practical step-by-step for FastCGI caching for WordPress/WooCommerce. (RunCloud Website)
  5. Optimized PHP-FPM for Faster Magento Stores, LiquidWeb / hosting guides — notes on PHP-FPM tuning for Magento and dynamic e-commerce workloads. (Liquid Web)
  6. DreamHost — Optimizing VPS Resources for E-Commerce Websites (2025 guide) — operational tips for monitoring and VPS sizing. (DreamHost)