WordPress delay from a plugin – curl delay from plugin
The following is some documentation of how I found an odd random delay which showed up on a WordPress website using a plugin, this is how I found the issue and how I would more quickly find it next time.
The WordPress Plugin Delay Problem
Every time the WordPress website would load, it would take about 15 second (actually between 15.2 seconds and 15.9 seconds) to respond.
It was very consistent in the delay and I quickly assumed it is a plugin.
I used two methods of debugging.
TCPDUMP
I ran TCP dump on the server and made sure that the web server received the packet I sent it, and that the delay was fully on the server
tcpdump host x.x.x.x port 80 -Xvvvvvvvvvvvvvvvvvvv
I found that the delay was on the server, the packets would be received by the server and the server would not respond until just over 15 seconds.
With this information I could confirm that without a doubt, the server was causing this 15 second delay.
LSOF
I used the lsof command to find out what open files were on the system when the command was delayed. I found that there was an outgoing http request to an odd IP address
#lsof -i:80 -n localip:28876->159.203.88.42:http
From experience with the website I knew that each time the WordPress application was called, it should not be calling ANY other website.
This did not help me find the problem, but I recognized that the issue was that some plugin was calling this IP address and it was stuck waiting to receive a result, which was blocking the page from loading. By running the lsof command multiple times during a request, I was able to see that this connection stayed open in the (SYN) mode for about 15 seconds. When I attempted to ping the IP, or open port 80 to the IP, I received no response.
To try to help me figure out what server this was and what plugin was calling this, I tried to lookup the IP
#dig -x 159.203.88.42 ;; QUESTION SECTION: ;42.88.203.159.in-addr.arpa. IN PTR ;; ANSWER SECTION: 42.88.203.159.in-addr.arpa. 1800 IN PTR 45215-36110.cloudwaysapps.com. ;; AUTHORITY SECTION: 203.159.in-addr.arpa. 80642 IN NS ns3.digitalocean.com. 203.159.in-addr.arpa. 80642 IN NS ns2.digitalocean.com. 203.159.in-addr.arpa. 80642 IN NS ns1.digitalocean.com.
With this I could have dug deeper to find out what plugins were hosted on the ip or something, but it seemed easier to just start disabling plugins until I no longer see the delay. So that is what I did, i just disabled one plugin at time (with a 15 second delay between each) until I reached ‘Easy Modal’. As soon as I disabled the plugin, the website loaded quickly.
Now, I could have just ditched the plugin since it clearly uses a method of verification which unacceptably blocks websites from using the plugin if their website is not running, but I dug deeper with the hopes that I will be able to more quickly figure out problems like this in the future.
I dug into the plugin and found that they have a hardcoded API url http://easy-modal.com . When I ping this url, i find that the IP resolves to:
#ping easy-modal.com 159.203.88.42
They luckily did use some WordPress built in functions in order make some calls to it server.
#wp_remote_get
wp_remote_get is a function which receives a url and returns information from the remote server for use in the programming, it appears they were using it to confirm that licensing was upto date, which would have been fine if they would have backgrounded the process in their code and then returned some sort of true in the case their server was not running correctly.
While this is not nearly as big of a deal it reminds of How one developer just broke Node, Babel and thousands of projects in 11 lines of JavaScript.
Now the quicker way to find out where some plugin is blocking based on a url request.
Code to evaluate external URL calls which might be slowing your page
I wrote the following to help me then track down all the locations in your site that are doing remote calls. It does not identify the url it is calling but it shows a backtrace in your error log which will lead you right to the location in the wp install that is making the call (whether it is a plugin or not)
I was VERY surprised how much network activity was occuring from the website server to other servers on EACH website request. you can write a plugin that does the following.
Add the following code to a plugin in your WordPress install
add_filter('http_request_args','log_wp_start_request'); add_filter('http_response','log_wp_end_request'); function log_wp_end_request($args) { global $page_log_tag,$log_request_tag; error_log("WPEND $log_request_tag Characters returned: ".strlen(print_r($args,true))); } function log_wp_start_request($arg) { global $page_log_tag,$log_request_tag; if(!$page_log_tag) $page_log_tag=chr(rand(65,80)).chr(rand(65,80)); $log_request_tag=$page_log_tag."_".chr(rand(65,80)).chr(rand(65,80)); $bt=debug_backtrace(); array_shift($bt); error_log("WPSTART $log_request_tag $nm $args"); foreach($bt as $fl) { $add.=" "; $btout="WPBACKT $log_request_tag $add $fl[file]:$fl[line]"; $btout=str_replace($_SERVER[DOCUMENT_ROOT],"",$btout); error_log($btout); } }
or you can check-remote plugin zip I created with the code. There are NO warranties on this.
If you have any debugging you would like done on your WordPress Plugins, Matraex does custom WordPress plugin development and would be happy to help you troubleshoot.