Profiling WordPress REST API requests

Are those REST API endpoints responding as quickly as they should? Or, perhaps there are some problems with the returned data you want to dig into?

The ever-useful Query Monitor makes it nice and easy to get additional insights, as it can inject extra information (including a list of database queries) into the API responses. Here's my basic recipe.

  1. Start by installing and activating Query Monitor.
    • Take it for a test drive: open an admin page and click on the Query Monitor section of the admin toolbar, then open the database queries tab. If things are setup correctly, you should not see any warnings (like the one shown in the following screenshot):
      Screenshot showing Query Monitor's "Extended query information" warning.
    • If you do hit difficulties like this, follow the advice in the plugin wiki.
  2. For security (and perhaps performance) reasons, Query Monitor doesn't supply debug information to just anyone. So, when using it to examine REST API responses, you will need to follow this guidance on authentication. Or, if you are working locally on a test site without any sensitive data, you could use a snippet like the following (I hope it goes without saying that this could be risky in any other environment):
// Make it so the current user can always view query monitor,
// regardless of who the current user actually is.
add_filter( 'user_has_cap', function ( $capabilities ) {
	$capabilities['view_query_monitor'] = true;
	return $capabilities;
} );
  1. Now we're all set to debug some API requests! To maximize our insights we're going to need to use enveloped requests which really just means supplying the _envelope parameter in the URL. Here's an example, using CURL and WordPress's own posts endpoint (I'm saving the response in a temporary file—this is just to make it fast and easy to perform various tests without repeated fetches):
curl "local.site/wp-json/wp/v2/posts?_envelope" > /tmp/http-response
  1. Now, we can examine the response using utilities like jq.
    • To get a high-level sense of what sort of debug information is available, you might try jq .qm /tmp/http-response | jq -c "keys_unsorted".
    • You can check for duplicate queries with jq .qm.db_queries.dupes /tmp/http-response.
    • Or count the number of database queries used to form the response with jq .qm.db_queries.wpdb.total /tmp/http-response.
    • To check the total time spent in database queries, try jq .qm.db_queries.wpdb.time /tmp/http-response.
    • Getting a little fancier, discover how long the longest running query took to execute, with jq ".qm.db_queries.wpdb.queries[].time" /tmp/http-response | sort -n | tail -n1.

There are lots of different angles to examine using this sort of approach:

  • By profiling a variety of responses from various endpoints, we can start to build a picture of how many "baseline" queries are going to execute on each request (queries triggered by WordPress itself, as part of how the system operates).
  • We might also start detecting unwanted additional queries inadvertently added on each request by other plugins.
  • Or, we may see obvious opportunities for caching—and much more.

 

You may also like:

Custom (PHP) snippets in WordPress

Often you will see tutorials that describe how to customize WordPress and, frequently, they will suggest you do this by...