I'm currently building a pretty straightforward plugin, but it relies quite extensively on AJAX requests. I'm using the standard admin-ajax endpoint for the requests, but I find that it seems to be massively inconsistent, sometimes the request (for the same data) will take a few hundred milliseconds and then sometimes take a couple of seconds.

I am aware that there is heartbeat issue that can be a problem when using admin-ajax which when modified can help improve request speeds when using the endpoint.

I suppose I could point the requests directly to a PHP file and use that as an endpoint, but is there anyway I can create an endpoint that uses Wordpress's routing?

So my question is; Does Wordpress have support for custom ajax endpoints / url parameters that will fire function calls etc..?

I'm also aware that I could use the REST API route callbacks, but I'd like this plugin to be dependency free where possible so it will be supported on version of Wordpress that don't include the REST API.

Thanks for any help!


2 Answers 2


Use add_rewrite_rule to make your own API and handle the endpoints yourself.

Tools like Monkeyman Rewrite Analyzer will help you understand how your rewrite rules end up working with existing rules.

if ( ! class_exists( 'WPSEAPIEndpoint' ) ):

    class WPSEAPIEndpoint {

        // WordPress hooks
        public function __construct() {
            add_filter( 'query_vars', array ( $this, 'add_query_vars' ), 0 );
            add_action( 'parse_request', array ( $this, 'sniff_requests' ), 0 );
            add_action( 'init', array ( $this, 'add_endpoint' ), 0 );

        // Add public query vars
        public function add_query_vars( $vars ) {
            $vars[] = '___my-api';
            $vars[] = 'action';
            return $vars;

        // Add API Endpoint
        public function add_endpoint() {
            add_rewrite_rule( '^my-api/v1/([^/]*)/?', 'index.php?___my-api=1&action=$matches[1]', 'top' );
            flush_rewrite_rules( false ); //// <---------- REMOVE THIS WHEN DONE TESTING

        // Sniff Requests
        public function sniff_requests( $wp_query ) {
            global $wp;

            if ( isset( $wp->query_vars[ '___my-api' ], $wp->query_vars[ 'action' ] ) ) {
                wp_die( "Action requested: " . $wp->query_vars[ 'action' ] );

    $wptept = new WPSEAPIEndpoint();

endif; // WPSEAPIEndpoint

There are 3 main parts to this; add your custom query vars, add your custom endpoint, and handle the request when you see your custom query vars.

flush_rewrite_rules() really only needs to occur once after you've added the new rules but it makes testing much faster to put it inline like I've shown. Just remove it when you're done. Or remove it early and flush the rewrite rules by saving your permalinks in the settings menu.


The main problem with native ajax endpoint is that it has to load whole WordPress core. Unless something is causing those slowdowns in your code it's likely something else bogs down that process.

Going through a different endpoint will no help you in this case since you still need to load core and back to square one.

Couple of seconds doesn't sound normal and I would recommend to first figure out where does that delay comes from.

The only practical technique for fast ajax endpoint in WP is custom core load with SHORTINIT, but that is limited to private projects since it cannot be practically coded generic enough to distribute in public solution (though some do and that crap breaks on any install slightly less than dead default).

  • "The main problem with native ajax endpoint is that it had to load whole WordPress core." - Is this still the case (WP 4.6), I assume that is why the 'heartbeat' was necessary to determine when the core had loaded completely or to a sufficient extent that the admin-ajax endpoint could successfully parse requests?
    – connorb
    Aug 20, 2016 at 18:44
  • I am not sure what heartbeat thing you refer to. Any request to admin-ajax.php performs full core load, I am not aware of that changing and it's unlikely it ever will (with WP's commitment to extreme backwards compatibility).
    – Rarst
    Aug 20, 2016 at 19:05
  • I'm think I'm going to rip parts of the REST API to build a basic route callback system which should suffice for what I'm trying to achieve. Thanks for the help.
    – connorb
    Aug 20, 2016 at 19:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.