Skip to content

Instantly share code, notes, and snippets.

@pretzelhands
Last active February 26, 2022 21:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pretzelhands/a0b45d629943403d4cca1ab1eb5e2277 to your computer and use it in GitHub Desktop.
Save pretzelhands/a0b45d629943403d4cca1ab1eb5e2277 to your computer and use it in GitHub Desktop.
A benchmark of WordPress' official REST API against a raw PHP file.

Performance implications of the official WordPress REST API

On Feb 25, I had to optimize a client's website. A plugin I built for them was struggling with performance issues when liking entries posted by other users. The database query took an average of 1.2ms to perform. Nevertheless, the API response took up to 1.2s(!) in the worst case for 63 bytes of JSON data.

I started investigating and noticed that the official WordPress REST API seemed to be at fault. So I did the first thing I could think of, ripped out the voting script and placed it in a raw PHP script that loads the bare minimum of WordPress I needed to perform my action.

The result was astounding. The response time went down from an average of 900ms to an average of 23ms. Slightly confounded by these results and a speed up of up to 5200%, I investigated.

Is the WordPress REST API really that slow?

These are my findings.

Benchmark

All benchmarks with n=1 are questionable at best, but nevertheless I want to lay out my results:

Official REST API Custom PHP script
~31ms ~7ms

These results were acquired under the following pre-conditions:

  • Wordpress 5.9.1, PHP 7.4.27
  • Running on localhost under nginx with local MySQL (v8.0.27)
  • Requests were performed 10x each with Firefox 98 and then averaged
  • No plugins were installed, except the one used to register the API endpoint

So, from my limited scale test, the WordPress REST API causes an overhead of at least 400%, for a bare bones installation. This seems to get worse by another order of magnitude if you install 20-30 plugins.

Code

You can find the code used below. It doesn't claim to be the most pretty. It's the bare minimum I could do to produce a reasonable JSON response. The raw PHP file includes helpful comments to explain what's going on.

Caveats

I don't think using raw PHP files as API endpoints is a good practice or recommendable. It potentially exposes internal details about your plugin to the outside world. Use it sparingly and exercise caution as to when the trade-off is worth it.

If you need the raw performance, consider a double-edged sword in your arsenal.

Cheers, pretzelhands

<?php
/*
Plugin Name: API Test
*/
function get_user()
{
return [
'hello' => 'world',
'user_id' => get_current_user_id()
];
}
add_action( 'rest_api_init', function() {
register_rest_route( 'test/v1', 'user', [ 'callback' => 'get_user' ] );
} );
<?php
// Ensure browsers parse our response correctly
header('Content-Type: application/json');
// Short-circuit WordPress. Loading the CMS with this
// option enabled loads the absolute minimum necessary
// to provide you with a global $wpdb object.
//
// You really don't get much more than that.
//
// For details check wp-settings.php and find the
// term SHORTINIT to see exactly what is being loaded.
define('SHORTINIT', 1);
// Load WordPress.
require_once $_SERVER['DOCUMENT_ROOT'] . '/wp-load.php';
// Load whatever WordPress includes we need.
// In this case I used a function from wp-includes/user.php
require_once ABSPATH . WPINC . '/user.php';
// Convenience function that returns minimal data.
function get_user()
{
return [
'hello' => 'world',
'user_id' => get_current_user_id()
];
}
// Response
echo json_encode( get_user() );
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment