Comparing WordPress REST API Performance to admin-ajax.php

#

Since the introduction of the WordPress REST API, many plugin developers have started converting their plugins to use the REST API instead of the older AJAX API (admin-ajax.php). Aside from the REST API simply being newer technology, rumor has it that the REST API is also faster and more reliable than the older endpoints due to the fact that not as much of WordPress is loaded during a typical REST request.

In this article, we’ll be looking at the life of a typical REST request as well as a similar request made over admin-ajax.php to see how they compare.

The Life of an admin-ajax.php Request

Let’s start by breaking down what happens when we make a typical AJAX request to admin-ajax.php. When your browser makes a request to that file, it loads a few other core WordPress files in order to be able to serve the request with core functions loaded:

/wp-load.php
/wp-config.php
/wp-settings.php (which loads most core files, all active plugins and themes, and the REST API)
/wp-admin/admin.php
/wp-admin/includes/ajax-actions.php

After loading these files, WordPress calls the admin_init hook, which several core functions hook into. The below core functions were called on this hook in WordPress 4.5.3:

register_admin_color_schemes
send_frame_options_header
_wp_check_for_scheduled_split_terms
_wp_admin_bar_init
_maybe_update_core
_maybe_update_plugins
_maybe_update_themes

After these functions have been called, WordPress finally calls the AJAX action provided in the $_GET[‘action’] or $_POST[‘action’] variable.

The Life of a REST API Request

Compared to the admin-ajax.php request, the typical REST request looks slightly different. Since the REST endpoints are handled by the WordPress Rewrite API, the request is passed to /index.php, which then loads the rest of WordPress normally.

/index.php
/wp-blog-header.php
/wp-load.php
/wp-config.php
/wp-settings.php (which loads most core files, all active plugins and themes, and the REST API)

Unlike requests sent over admin-ajax.php, the REST API doesn’t load the WordPress admin section via /wp-admin/admin.php, nor does it fire the admin_init action hook. Based on that, it’s likely that any plugins or themes that don’t rely on admin-specific functionality – but are using admin-ajax.php – should see a slight performance boost by switching over to the REST API.

The Benchmarks

Now that we’ve seen a bit of what happens behind the scenes, let’s set up a scenario that can be easily benchmarked. To do this, we’re going to create a simple function that can be run on either admin-ajax.php or over the REST API:

function benchmark_request() {
    $result = array( 'time' => time() );
    echo json_encode( $result );
    exit;
}

add_action( 'wp_ajax_benchmark_request', 'benchmark_request' );
add_action( 'rest_api_init', function() {
    register_rest_route( 'benchmark/v1', '/benchmark/', array(
        'methods'  => 'POST',
        'callback' => 'benchmark_request'
   ) );
} );

The above function just returns the time in JSON – this just helps make it easier to see that the requests aren’t being cached.

To perform the actual benchmarking, we’re going to be using ApacheBench, a command line benchmarking tool that allows you to fire off multiple requests at once to get a feel for how the server is performing.

Let’s test the admin-ajax.php version first.

 ab -n 100 -c 1 -p ~/Desktop/post.data -g ~/Desktop/ajax.tsv -T application/x-www-form-urlencoded http://localhost/rest-api/wp-admin/admin-ajax.php

The above command sends 100 POST requests to the /wp-admin/admin-ajax.php file and logs the response times. The post.data file referenced is simply a text file containing the URL encoded $_POST values to be sent with the request (in this case, action=benchmark_request).

ajax

With 100 requests, the average response time was 253ms on a fresh install of WordPress on MAMP and PHP 7 with no other plugins activated. This gives a good baseline for the same test over the REST API:

ab -n 100 -c 1 -p ~/Desktop/post.data -g ~/Desktop/rest.tsv -T application/x-www-form-urlencoded http://localhost/rest-api/wp-json/benchmark/v1/benchmark/

rest

Not surprisingly, the REST API is slightly faster in this comparison, with an average response time of 217ms over 100 requests. This obviously isn’t a huge difference, with the REST API only being about 15% faster than the traditional AJAX API, but over many requests this small difference can definitely add up, especially as more plugins are added.

Let’s run the same benchmarks but with a few plugins activated. For these tests I activated a few common plugins that you might find on a typical website:

  • ACF
  • Akismet
  • Black Studio TinyMCE Widget
  • WP Migrate DB
  • WP Super Cache
  • Yoast SEO

Despite the increase in overall response time, the performance gap between admin-ajax.php and the REST API remains about the same. With the additional plugins loaded, the REST API was about 16% faster, and had an average response time of 490ms compared to 567ms over admin-ajax.php:

ajax-plugins

rest-plugins

A website with a larger number of plugins could see an even larger performance increase from the REST API, but that depends completely on which plugins are running and how they are coded.

So Should You Use the WordPress REST API?

From a performance standpoint, it’s clear that there is a slight advantage. Adding custom API endpoints is incredibly easy, and since it doesn’t have to load as much of WordPress core (including the admin area and the commonly-used admin_init hook), it will likely be faster than using admin-ajax.php in most cases.

In terms of reliability, the REST API still depends on the quality and integrity of the active plugins or themes. A poorly coded plugin could still easily interfere with REST requests, especially as more plugins adopt the REST API in the future. However since there are less plugins using the REST API, it should be slightly more reliable for now.

Overall, it’s definitely a good idea to at least consider using the REST API. Adding custom API endpoints is incredibly easy, and it doesn’t take much to switch over existing code either.

Have you converted anything over to the REST API yet? Did you see a similar performance increase? Let us know in the comments below.

About the Author

Matt Shaw

Matt is a WordPress plugin developer located near Philadelphia, PA. He loves to create awesome new tools with PHP, Javascript, and whatever else he happens to get his hands on.