WordPress uses a system called WP-Cron to schedule repeated tasks. In Paid Memberships Pro, we extend this system to schedule things like membership expirations, expiration warning emails, and credit card expiration warnings.
If WP-Cron is not working properly on your site, expired members may not lose membership when you expect them to and certain membership-related emails may not be sent on time.
This post will go into some common issues with WP-Cron and how to troubleshoot and fix those issues on your WordPress site.
An Overview of the WP-Cron System
Every time WordPress is loaded, WP-Cron will check if there are any scheduled tasks. If there are, those tasks are kicked off and run during that page load. There are a few issues unavoidable issues with this setup:
- WP-Cron relies on traffic to your website. If no one is accessing your website in the early morning when PMPro wants to expire memberships, that task may not run on time or at all.
- WordPress is not loaded when your site serves a page from cache. While caching is a good idea to balance the load on your server, it means that only users accessing the WordPress dashboard or a non-cached page on your site will kick off WP-Cron.
- If your site is not running WP-Cron regularly, tasks can back up. This could lead to long load times for users when their one visit happened to trigger WP-Cron or timeouts where scheduled tasks never finish at all.
Debugging Crons with the WP Crontrol Plugin
One way to debug issues with WP-Cron is the WP Crontrol Plugin by John Blackbourn & ‘crontributors’. This free plugin will add a page to your dashboard under Tools > Cron Events
. This page will contain a table of all scheduled cron events for your WordPress site.
Browse through the list of cron events and look for the ones created by Paid Memberships Pro:
pmpro_cron_expire_memberships
pmpro_cron_expiration_warnings
pmpro_cron_credit_card_expiring_warnings
pmpro_cron_admin_activity_email
If these events are not on the list, then you can force PMPro to regenerate them by deactivating and reactivating the core PMPro plugin.
Some of the Paid Memberships Pro Add Ons also add cron events. We prefix all of our cron events with the term pmpro
. For example, the Series: Drip-Feed Add On adds a cron event titled pmpros_check_for_new_content
.
If the cron events are in the list, you can click the “Run Now” link to force the cron event to run. To test if expirations are working, you could set your own membership to expire on yesterday’s date. Then run the pmpro_cron_expire_memberships
event and see if your membership is expired and if you get the expiration email.
If your membership is expired, but you don’t get the email, see our email troubleshooting guide for help with that.
If the cron event runs fine when you run it through the Cron Events page, but doesn’t seem to trigger on it’s own at night, then you will want to read the next section on setting up a more reliable cron service.
Setting Up a More Reliable Cron Schedule
Remember that WP-Cron only runs when a user is visiting a non-cached page on your WordPress site. It would be better to set up the cron service at the server level to trigger WP-Cron to run every 5 minutes or so. Some hosts may have limits on how frequent cron job intervals may run. If you have a good WordPress host, like we recommend here, your host may already have something like this set up. If not, a support request like the following should be enough for them to set up your server to run WP-Cron every 5 minutes.
Hello. Thank you for the great service with my hosting account.
I am trying to set up a more reliable cron schedule for my WordPress site. Will you set up a cron job on my account to load this URL every 5 minutes?
http://yourdomain.com/wp-cron.php?doing_wp_cron
Please also exclude this URL from any caching that may be set up at the server level.
Thanks again.
Make sure to swap in your own domain name in the URL above. Make sure it ends with /wp-cron.php?doing_wp_cron
.
Also make sure that URL is excluded from any caching plugin or system you have running on the site.
Finally, once the server-based cron is running, you can disable the regular WP-Cron checks that happen on random page loads by adding the following to your wp-config.php file:
define('DISABLE_WP_CRON', true);
Adding the above to your wp-config.php
file will ensure that random users on your site do not kick off cron events that would slow down their browsing. Since your server is doing this every 5 minutes now, you won’t need WP-Cron to run on random page loads anymore.
If your host cannot or will not set up the cron job for you, ask them for information on how you can do it yourself. The directions will be different depending on the type of server and control panel software involved. You can find more information about how to set up a server side cron job in the WP developer documentation here and this useful blog post on WP-Cron by Tom McFarlin.
The cron job that you set up, should look something like this in the file:
*/5 * * * * wget -q -O - http://yourdomain.com/wp-cron.php?doing_wp_cron
Broken down, this line will tell cron to run every 5 minutes, every hour, every day, every month, every day of the week. The wget
command line program is run to load your website. The -q
parameter says to do so “quietly” with no output. The -O -
parameter is telling wget
to not save the webpage locally.
Another option is to use a paid service like SetCronJob. SetCronJob will basically set up a cron job on their own servers to ping your site every so often. This works exactly the same as setting a cron on your server itself, but could be less complicated for some users on some hosts.
We also recommend using a service like Cron-job.org It allows you to set up as many cronjobs as you like.