惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

GbyAI
GbyAI
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
IT之家
IT之家
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
N
News | PayPal Newsroom
Cloudbric
Cloudbric
Webroot Blog
Webroot Blog
www.infosecurity-magazine.com
www.infosecurity-magazine.com
Simon Willison's Weblog
Simon Willison's Weblog
Spread Privacy
Spread Privacy
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
V
Vulnerabilities – Threatpost
Attack and Defense Labs
Attack and Defense Labs
C
Cyber Attacks, Cyber Crime and Cyber Security
Cisco Talos Blog
Cisco Talos Blog
C
Cybersecurity and Infrastructure Security Agency CISA
H
Hackread – Cybersecurity News, Data Breaches, AI and More
P
Proofpoint News Feed
阮一峰的网络日志
阮一峰的网络日志
S
Secure Thoughts
T
Tor Project blog
Latest news
Latest news
aimingoo的专栏
aimingoo的专栏
V2EX - 技术
V2EX - 技术
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
S
Securelist
T
Tenable Blog
N
Netflix TechBlog - Medium
Google Online Security Blog
Google Online Security Blog
博客园 - Franky
T
Troy Hunt's Blog
量子位
大猫的无限游戏
大猫的无限游戏
T
Threat Research - Cisco Blogs
T
The Exploit Database - CXSecurity.com
MongoDB | Blog
MongoDB | Blog
H
Heimdal Security Blog
D
Docker
W
WeLiveSecurity
Stack Overflow Blog
Stack Overflow Blog
G
Google Developers Blog
博客园 - 叶小钗
腾讯CDC
The Hacker News
The Hacker News
WordPress大学
WordPress大学
人人都是产品经理
人人都是产品经理
Project Zero
Project Zero
Martin Fowler
Martin Fowler

Pressable

Pressable Achieves Secure Hosting Alliance Certification | Pressable How Pressable MCP Is Changing The Game For WordPress Agencies: A Live Breakdown With Matt Medeiros And Phill Clapham | Pressable April Product Update: Navigation, Organization, And Efficiency | Pressable White-Label WordPress Hosting For Profitable Agencies | Pressable A Guide To Client Onboarding For WordPress Agencies| Pressable WordPress Plugin Management for Agencies WordPress Maintenance Contracts For Agencies: A Complete Guide | Pressable 6 Essential SOPs For WordPress Agencies | Pressable Pressable MCP: Control Your WordPress Hosting With AI. | Pressable How Much Does WordPress Hosting Cost? WordPress Performance Budgets: Setting And Monitoring Goals | Pressable WordPress Automation With No Code Automation Tools | Pressable Implement Single Sign-On (SSO) In WordPress | Pressable How To Build A Real Estate Site On WordPress | Pressable Headless WordPress Showdown: Next.js Vs Gatsby | Pressable How To Automate White-Label WordPress Hosting With WHMCS | Pressable Developer Toolkit Update: Automation & UI Enhancements | Pressable How To Build A DXP Platform With WordPress How To Boost WordPress Agency Client Retention: 4 Strategies White Label WordPress Admin For Agency Clients Performance Testing For WordPress Agency Client Sites Performance Testing For WordPress: A Framework For Agency Client Sites How To Upload A Video To WordPress | Pressable How To Mitigate The Impact Of AI Scraper Bots On WordPress Sites WooCommerce ERP Integration: Automate Your Back Office WordPress Personalization: How To Display Tailored Content To Visitors | Pressable WooCommerce Conversion Rate Optimization: A Data-Driven Approach How To Price Your Online Course: WordPress Monetization Guide 7 Ecommerce KPIs You Should Be Measuring (and How to Optimize Them) WooCommerce Vs. BigCommerce: Which Is Best For Your Business Needs? | Pressable WooCommerce Performance Troubleshooting: Diagnosing Speed Issues Step-by-Step | Pressable AI Content Moderation Tools for WordPress: Fighting Back Against AI Spam WordPress Vs. Craft CMS: Which Is Right For Your Business Site? | Pressable Questions To Ask Before Migrating From Shopify To WooCommerce Outgrowing Squarespace? WooCommerce Can Help WordPress Automation: Google Docs To WordPress Workflow WooCommerce Subscription Strategies: How to Build Recurring Revenue for Your Store Is WordPress Easy To Learn? A Beginner’s Guide WooCommerce Database Optimization With Query Monitor | Pressable WPForms Vs Gravity Forms: Which WordPress Plugin Works Best For Growing Businesses? WooCommerce Vs. Shopify: Choosing The Right Platform The Best AI Chatbots for WordPress Rank Math Vs Yoast: Best WordPress SEO Plugin? 5 Ways AI For Ecommerce Boosts WooCommerce Sales | Pressable WordPress Cookie Consent: What Site Owners Need To Know | Pressable How To Optimize Your WooCommerce Store For AI Search | Pressable WordPress Local SEO: A Guide To Local Search For SMBs | Pressable How to Improve Your WordPress Site’s Search Experience WordPress vs. Substack: Find the Best Platform for Your Newsletter WordPress vs. Ghost: Comparing Open-Source Blog and Newsletter Solutions A Comprehensive Migration SEO Checklist For WordPress Drupal vs. WordPress: Comparing Open Source Content Management Systems How To Add Enterprise-Level Search Capabilities To WordPress Sites What Are WordPress Nonces And How To Use Them | Pressable How To Customize WordPress Without Breaking Your Theme | Pressable WooCommerce vs. Magento (Adobe Commerce): Which is Better for Your Online Store? Prepare Your WooCommerce Store For A High-Traffic Product Drop Tips On Building A Successful WordPress Sales Funnel | Pressable Best WordPress Integrations For Workflow Automation | Pressable WooCommerce Vs. Wix: WooCommerce Explained For Wix Users | Pressable How To Choose WordPress Lead Generation Plugins | Pressable GA4 For WordPress: Understanding Your Data | Pressable WordPress Accessibility for Visually Impaired Users WordPress Information Architecture For Businesses | Pressable How To Use WordPress As A Headless CMS | Pressable How To Use Composer For Modern WordPress Development | Pressable WordPress GitHub Workflows: Version Control Best Practices How To Evaluate A WordPress Plugin Before Installing It | Pressable Billing Clients For WordPress Hosting | Pressable Advanced WooCommerce Cart Abandonment Strategies | Pressable How To Perform A WordPress Security Audit | Pressable How Managed WordPress Hosting Reduces Ops Workload | Pressable The Ultimate Ecommerce CRO Guide | Pressable How to Set Up a Business Continuity Plan for Your WordPress Website How to Hire the Best WordPress Developer for Your Site Common Mistakes When Choosing A WordPress Host | Pressable Beaver Builder Vs. Elementor: Which Page Builder Is Better Streamlining Website Handoff With Managed WordPress Hosting How WordPress Agencies Build Recurring Revenue | Pressable How To Customize WooCommerce Product Pages | Pressable SEO Tip For Migrating Your WordPress Domain | Pressable When To Switch To Enterprise WordPress Hosting | Pressable WooCommerce PIM Tools For Growing Ecommerce Stores | Pressable Automating WordPress Security: Tips To Prevent Cyberattacks Integrating POS With WooCommerce | Pressable Scale Your WordPress: Automation Tips For Growth, Efficiency, And Reliability | Pressable How To Edit Your WordPress Database Safely | Pressable Boosting Conversions, Not Load Times: Performance-Focused A/B Testing of Landing Pages in WordPress WooCommerce Migration: Avoid Downtime and Data Loss With These Essential Tips How To Improve Core Web Vitals on Your WordPress Site How To Run Successful SEO Experiments On WordPress | Pressable Automated WordPress Website Backups | Pressable Grow Ecommerce Sales With WooCommerce Dynamic Pricing LearnDash vs LifterLMS: Which WordPress LMS is Right for You? What Is High Availability Hosting For WordPress? | Pressable Tips On Managing WooCommerce Traffic Spikes | Pressable What To Do When A WordPress Plugin Breaks Your Site Automating Agency Workflows With WordPress Webhooks How To Automate Tasks In WooCommerce With Action Scheduler Why WordPress Downtime Costs And Uptime Guarantees Matters WordPress Cleanup: How to Uninstall WordPress Plugins Without Breaking Your Site
How To Perform WordPress Benchmark Testing | Pressable
Kevin MacGillivray · 2023-09-29 · via Pressable

picture of a stopwatch

Ask Your Favorite AI

Copy the link to a markdown format of this article for ChatGPT, Claude, Gemini, or your favorite AI.

With such a robust ecosystem, bursting at the seams with 3rd-party solutions, there’s no wonder why WordPress has held the CMS crown for so long. Plugins, themes, and services are plentiful, but along with the endless combinations, comes drastic variations in performance. Variations that, without benchmarks, go unnoticed.

Every variable has some level of impact on the site’s overall performance – something that’s often taken for granted until it snowballs out of control. A few milliseconds here and there don’t seem like a lot, but over time, they can add up.

In this article, we’re going to show you how to perform benchmark tests on your WordPress site.
By performing these benchmarks regularly, you’ll be able to keep track of your site’s performance over time, track performance woes, and keep your site running in peak health.

Benchmarking Basics For the Uninitiated

We realize that benchmarking is a deep topic, full of nuance and different perspectives, approaches, and tools. Even if you’ve heard about many of the concepts before, you still might not understand how everything fits together.

That’s okay.

If you get a little lost, take a look at our recent article about how to understand WordPress benchmarking results. There’s a good chance that it’ll get you back on track.

Worst case, if you hit a snag, just keep reading. There are several concepts to discuss, and even if one isn’t quite your speed, another might be.

Anyways, with that out of the way, let’s get started.

Performing Basic Raw Performance Tests

The most basic of tests is to check raw performance. This is done by simply running a piece of code, often something CPU intensive like encryption, then seeing how long it takes to complete.

Since there’s no sense in reinventing the wheel, we’ll refer you to the WPPerformanceTester plugin by ReviewSignal. (Yes, we know it hasn’t been updated in a while. It still works fine though.)

Although its tests are isolated to the raw performance of your hosting environment, it’s a good starting point to determine some baseline data.

Performing Load Tests

Load testing is a completely different beast. As we discussed in our article about understanding WordPress benchmark results, load testing is all about seeing how your site performs under stress.

The most popular tool for performing load testing is k6. It’s reliable, open source, and can be as basic or complex as the tests you write for it.

For the purposes of this article, we’ll skip the basic installation and usage process, but if you need it, you can find a k6 quickstart guide within their documentation.

Test Methodology

Before we start tossing out configs, let’s talk a little about the methodology behind running these tests. Specifically, how and why you’ll want to run certain tests on different WordPress environments.

In a perfect world, we’d test everything, in every possible way. In a perfect world, we’d all poop pumpkin spice frosting too.

Your tests can and should become more robust over time, but what’s most important is to test the parts that are most likely to fail. For WordPress sites, this means pages that can’t be cached, particularly ones that perform a lot of database operations or other heavier tasks.

For example, a few good places to start testing are:

  • Any ecommerce pages that display a user’s cart
  • Checkout pages
  • User login and account pages
  • Large archives, especially if there’s any sort of filtering available
  • Subcategories, tags, recommended posts, or anything else that is likely to have lots of variation

If you’re not sure, spam it with some users and see what happens while caching if on, then test again with caching off. If the page isn’t significantly faster when caching is on, you’ve found a good candidate to include in your load tests.

Example Configuration

import http from 'k6/http';
import { sleep, check } from 'k6';

export const options = {
  stages: [
    { duration: '30s', target: 20 },
    { duration: '1m30s', target: 10 },
    { duration: '20s', target: 0 },
  ],
};

export default function () {
  const res1 = http.get('https://example.com/');
  check(res1, { 'status was 200': (r) => r.status == 200 });
  sleep(Math.random() * 30);
  
  const res2 = http.get('https://example.com/product/wordpress-pennant/');
  check(res2, { 'status was 200': (r) => r.status == 200 });
  sleep(Math.random() * 30);

  const res3 = http.get('https://example.com/page/2/');
  check(res3, { 'status was 200': (r) => r.status == 200 });
  sleep(Math.random() * 30);

  const res4 = http.get('https://https://example.com/2023/07/18/post-with-a-form-and-stuff/');
  check(res4, { 'status was 200': (r) => r.status == 200 });
  sleep(Math.random() * 30);
}

Combining and Enhancing Your Benchmarks

Once you’ve written a few tests, you’re going to find areas that you want to improve upon. If a page performs poorly and doesn’t scale well, you’ll want to optimize it. The reason is simple: it’s often better to optimize code than to scale infrastructure.

Even if you don’t already have an in-house development team, paying an agency or freelancer to optimize it for you is often cheaper in the long run. If your site slows down or goes offline from a traffic spike, you lost potential customers. If your host is nickel and diming you with their “moar PHP w3rkers plz” excuse, it’s going to continue to scratch away at your profits for all of eternity.

Get Granular

GIF from Fear and Loathing in Las Vegas that says "we can't stop here. this is bat country"

Benchmarks don’t have to be restricted to a whole page render – you can benchmark specific segments of your site’s code, down to the nanosecond. Remember that a WordPress site is made up of several different moving parts.

Start testing the parts to find the rusty old bolt.

Buckle in, we’re diving deep into code territory. If you’re not a dev and don’t understand any of this next section, keep reading, but consider hiring someone who would understand it. Do more of what you’re good at, hire someone who loves the things you don’t.

Like hosting. Want some hosting? We’ll sell you some.

You could use services like New Relic, but that’s more effort to get up and running, likely a subscription, and then you still have to learn how to use it. Alternatively, you could toss XDebug into profile mode and test locally, but the hosting environments aren’t going to match up.

Each solution has its benefits and drawbacks, but there’s another solution that you might not have considered: WordPress is built to be extensible… Just extend it to be more verbose.

Using Hooks as a Benchmarking Signal

There are hooks all over WordPress core. We can use them as mile markers and signposts. By looking at the hooks that are firing in any given request, you can see what it’s doing, why, when, and for how long. Plus, you can do it on your production environment if you really need to.

(For real though, don’t do this on a production environment unless you have no other choice. Cowboy coders deserve to be shamed – cowboy debuggers deserve to be mercilessly ridiculed. Myself included.)

To see what I mean, take a look at this quick little snippet:

<?php

add_action('shutdown', function() {
    global $wp_actions;
    var_dump($wp_actions);
});

“But that’s just a list of actions! I can get a list of actions from Query Monitor!” Yeah, I know. Keep your pants on – we’re getting there.

Now that we know all of the actions that are firing on the page, we can start timing things.

If you want to get the time of an action, just hook into the action, grab the time, and toss it somewhere like a global like this:

function add_to_time_global($hook) {
    global $time = array();

    $time[] = array( current_filter() => hrtime(true) );
}

function output_stuff() {
    global $time;
    var_dump( $time );
}

add_action('loop_start', 'add_to_time_global');
add_action('loop_end', 'add_to_time_global');
add_action('shutdown', 'output_stuff')

This tells us how long things take, at least in a very basic sense. We know the exact nanosecond that each hook fired, and how many times. We can time every hook in WordPress if we want.

Although this alone can do the trick for debugging, it still doesn’t help very much with benchmarking. It’s hardly practical or a real picture of what would happen under stress. It’s not like we can use it during load tests.

Or can we..?

Mocking Functionality

If we know what we’re testing, we can mock up a version of the code that takes measurements throughout the process. We could either log it, or even better – return it as a REST API response.

By returning it as a REST API response, we can integrate it into our load tests for automated testing. It also means that we can perform small tests from the WordPress admin, using client-side requests.

A server-side script can run something a bunch of times, but will only tell you how a single worker thread is performing. If you send multiple client-side requests instead, similar to a mini version of a load test, you get a much more accurate picture without any other tooling.

Overengineering a Stopwatch

For those of you who know the author of this post: did you really think I could write something like this without overengineering some sort of monstrosity?

While writing this article, I did a lot of thinking about how someone could start running benchmarks with as little friction as possible. I wanted something practical, portable, and with a low barrier of entry. Even users without much knowledge of the underlying details should be able to compare numbers with the click of a button.

Furthermore, the plugin should be extensible – encouraging others to write their own tests for specific scenarios, 3rd party plugins, or to contribute more robust tests that anyone can run easily.

Thus, WP Benchy was born. User clicks button, button runs tests, user gets numbers.

Let’s Write a Test

Without further ado, let’s write up a test that uses WP Benchy as a foundation. If you’re writing this along with us, be sure to install the latest WP Benchy plugin zip first.

Here’s what it looks like:

<?php
/*
* Plugin Name: Example Extension - Pressable Benchy
*/

require_once(ABSPATH . 'wp-content/plugins/wp-benchy/src/modules/Abstract_Module.php');

class Example_Benchy_Module extends Pressable\WP_Benchy\Modules\Abstract_Module {

    protected $id = 'example_benchy_module';

    public function run() {
        $this->checkpoint_hit('getting_posts');
        $posts = get_posts();
        $this->checkpoint_hit('got_posts');
    }
}

add_filter( 'pressable_benchy_register_modules', function( $modules ) {
    $modules['example_benchy_module'] = new Example_Benchy_Module();
    return $modules;
}, 10, 1);

Yup, that’s the entire plugin.

So simple that you can make a million of them, test all the things, and share them with the world.

Testing with Simplicity

Let’s walk through how it works alongside the Benchy plugin.

First, we define a class that extends the base class from Benchy, adding in a few items:

require_once(ABSPATH . 'wp-content/plugins/wp-benchy/src/modules/Abstract_Module.php');

class Example_Benchy_Module extends Pressable\WP_Benchy\Modules\Abstract_Module {

    protected $id = 'example_benchy_module';

    public function run() {
        ...
    }

}

This allows Benchy to do the heavy lifting for us. Behind the scenes, it’s doing things like:

  • Handling results
  • Registering REST API endpoints
  • Including the test in the Benchy UI
  • Managing “checkpoints” (we’ll go over that in a minute)

With that out of the way, let’s look at what’s happening in the test itself. The “meat and potatoes” of the module is everything inside of the run() method:

public function run() {
    $this->checkpoint_hit('getting_posts');
    $posts = get_posts();
    $this->checkpoint_hit('got_posts');
}

All we’re doing is here getting some posts and looping through them, registering checkpoint hits along the way. Simple, eh?

Remember what we said earlier about taking timings at different points? That’s exactly what we’re doing here by calling the checkpoint_hit() method. Each time this is called, it takes the timing, then stores it in the object instance for later use.

Finally, there’s a filter being called like so:

add_filter( 'pressable_benchy_register_modules', function( $modules ) {
    $modules['example_benchy_module'] = new Example_Benchy_Module();
    return $modules;
}, 10, 1);

The entire purpose of this is to create an instance of the class and add it to the runner that will handle all of the heavy lifting when needed.

Easy Results Through Automatically Registered REST Routes

In the end, you have a new REST API endpoint at /wp-json/wp-benchy/v1/module/example_benchy_module that outputs results like this:

{
  "checkpoints": {
    "getting_posts_0": 762393698200307,
    "got_posts_0": 762393698363932
  },
  "first": 762393698200307,
  "last": 762393698363932,
  "total": 0.16363
}

As you can see here, we now have:

  • Timestamps (in nanoseconds) of each checkpoint.
  • Timestamps for the first and last checkpoints.
  • The total time (in milliseconds) that it took the entire test to complete.

Making the Test Data Useful

Yay! We have data! And it’s available through the REST API! Now what? Time to make it useful.

From here, we have 2 options:

  • Use a 3rd party load testing tool like k6 to pound our endpoints into oblivion.
  • Use JavaScript on the client side to hit those API endpoints and process the results from inside of the WordPress admin.

The second option is the most interesting.

Because we can initiate multiple client side requests from within the WordPress admin, this makes performing simple benchmarks accessible to everyone, without any additional tools of configuration.

Running WordPress Benchmarks, From Inside WordPress

Any modules, whether built into the main Benchy plugin or included as an extension, are automatically made available from within the WordPress admin. This means that even the most basic of users can gain fresh insights on how these tests are performing.

Screenshot of the WP Benchy plugin settings screen

Is it fancy? No. But it’s a utility – it gets the job done.

Ain’t nobody got time to waste making a pretty UI. Well, you might. I don’t. If you do, make it fancier – PRs are welcome.

Benchmarks For All

Now that the foundations are now in place, go write up some tests. Share your results with your friends, get them to share their tests with you. While you’re at it, share your tests with us too.

Tests are far from complete. We would love your contributions, whether it be integrating tests in your existing plugins, providing feedback, or even better – contributing tests to the main plugin for everyone to use.

We’d also love to know what you think about our approach, and what you would do to improve it. Together, we can provide everyone with actionable, repeatable data that helps all skill levels with reliable test metrics.

If you have any thoughts, we’d love to hear them. Reach out on the GitHub repo or tag us on Twitter.

photo of Jeff Matson rolling up his sleeves

Jeff Matson

Jeff Matson is a distinguished figure in the world of WordPress development, public speaking, and marketing with over 15 years of experience. As a seasoned software developer, programmer and engineer, he seamlessly integrates technical proficiency with a strong understanding of SEO and content marketing. Jeff is a prominent and engaged member of the WordPress community, and his contributions to the WordPress core reflect his commitment to open source software along with his talent for creating compelling marketing strategies has established him as a thought leader, by bridging the gap between technical intricacies and effective communication. In his spare time, Jeff loves to restore classic arcade machines and make whatever ridiculous project pops into his mad scientist brain.