Azure Websites: Has Your WordPress Site Started Running Slower?

Our product group has posted many excellent blogs on deploying, testing and troubleshooting various issues with WordPress deployments on Azure Websites. While I do recommend these and they would likely expose the issue I am going to discuss here, the root cause of the problem and the steps necessary to resolve it would still not be obvious.

As noted in the in the title of this blog post, the scenario here is that you have a WordPress deployment that has been running fine for some period of time, and then, all of a sudden, requests start taking 5-10 seconds or longer to complete. If your site is using the Contact Form 7 plugin along with Really Simple Captcha, you might be hitting an issue due to the number of files that are being created (and not cleaned up) in the wp-content/uploads/wpcf7_captcha folder by the plugin.

To determine if you are being affected by this problem, connect to your site using FTP or the Kudu diagnostic console. Once connected, check the contents of the wp-content/uploads/wpcf7_captcha folder. If you see 100s to 1000s of files in the folder, its a good bet the situation outlined above might be your problem.

Your first thought might be to just delete the files in this folder. However, if you try, you will see an Access Denied message. The cause of that message gets to the root of the problem. The code for the plugin creates these files with a read-only bit set. That means that subsequent cleanup attempts fail and the folder bloats with files. The problem is discussed in the this blog and in the WordPress forum, along with a reference to a code fix for the plugin.

So how do we get past the Access Denied message so that we can delete the files? We do that by using the Kudu console. First, let’s have a look at the error you receive if you try to delete the files with a simple DEL command. Here’s a screenshot of the resulting error message.

DelCaptcha1

To work around this error, you can use the following commands.

DEL *.png /A:R 
DEL *.txt /A:R

Deleting the files using this command will help to fix the current performance problem, but to really solve the problem, you need a solution to avoid getting here in the first place. You have a couple of different options for doing that.

First Option: Change the Plugin Code

You can change the code that is responsible for cleaning up the files so that it will not leave the files in read-only mode. You do that by adding a chmod command to alter the file properties prior to the cleanup code running. The following WordPress forum post provides some examples of modifying the plugin to do this. (Note that these examples are from the WordPress community and are not provided or supported by Microsoft. I suspect they could change as the plugin gets updated. If you have questions about these examples or how to implement them, you should contact the plugin owner.)

https://wordpress.org/support/topic/plugin-really-simple-captcha-function-cleanup-unlink-permission-denied?replies=10#post-3645857

These code samples add either a @chmod( $file, 0777 ) or a @chmod( $file, 0755 )   prior to the call to the unlink function. Since the files get deleted after doing this, I don’t think it matters which permission you choose, but for safety, I would probably use 0755 since it only provides Read and Execute for non-owners. See the chmod documentation for more information.

Keep in mind that if you add this code, it will be overwritten when you update the plugins, and you might not realize this has happened.

Second Option: Use a WebJob

It would be better to have a solution to the problem that doesn’t involve having to modify code for the plugin. Enter WebJobs. Using a WebJob, you can run a task to clean up the files at a scheduled interval. on-demand or continuously by monitoring for file changes.

In the blog I referenced earlier, the writer also suggests some cleanup code in PHP, and that code will work perfectly in a WebJob. I took the liberty of making two code changes below.

Original Code:
if($file != "." && $file != "..")

New Code:         
if($file != "." && $file != ".." && $file != ".htaccess")

NOTE: Since my goal is only to remove the PNG and TXT files, I changed the above line so that the .htaccess file wouldn’t be affected.

Original Code:

if (delSessionFiles('wp-content/uploads/wpcf7_captcha', '1800') === TRUE) { echo "Contact Form 7 temp files deleted."; }

New Code:

if (delSessionFiles( 'D:\home\Site\wwwroot\wp-content\uploads\wpcf7_captcha' , '1800') === TRUE) {

  echo "Contact Form 7 temp files deleted.";

}

NOTE: Changed above to use the absolute path where the files exist.

To use this code as a WebJob, simply save the full code in a text file with a .PHP extension, Zip the PHP file into a Zip file and upload the Zip from the Azure Portal. For this I chose a scheduled webjob that would run every hour and based on the code delete files older than 30 minutes.

I hope this helps resolve one of those hard to find performance issues in your WordPress site.

Thanks to Jim Cheshire for collaboration on this issue.

Additional Resources

10 Ways to Speed up your WordPress site on Azure websites

WordPress Troubleshooting Techniques on Azure Websites

How to host a Scalable and Optimized WordPress for Azure in minutes