Today I received an email with an interesting question about ICS Calendar and caching. The sender wanted to know about when ICS Calendar retrieves the feed, and whether or not that can be controlled via a cron job.
Good question! Here’s an edited and expanded version of my response.
The basics of ICS Calendar caching
The calendar is retrieved when the page that contains it is loaded; it is then cached for one hour. You can change the duration of the cache on the ICS Calendar admin page.
Since ICS Calendar is loaded in a shortcode, and shortcodes only run when a page that contains them is requested by a user, all of the ICS Calendar functionality happens in response to that request. This includes retrieving the calendar from the source server, parsing the calendar data, and formatting it for ICS Calendar’s display. This happens quickly, but not instantly, so ICS Calendar creates two caches: first it caches the raw data it receives from the source calendar. Then it also caches the parsed data tailored to that specific view. (If a site has multiple shortcodes that retrieve the same calendar but display it in different ways, the parsed data may be different.)
So, caching is important, but you also don’t want cached calendar data to stick around for too long, since it’s time-sensitive information that can change. So I went with one hour as the default cache duration. You can change this overall setting on the ICS Calendar page in your WordPress admin. You can also set the duration for individual calendar shortcodes using the reload
parameter.
If you are using another caching plugin, you may want to bypass ICS Calendar’s caching altogether. This is done by setting reload="1"
in your shortcode.
What about cron?
The Pro version also has an option to pre-cache the calendars using WP-Cron.
If you’re not familiar with how WP-Cron works, it’s a “pseudo” cron job. The nature of a web application like WordPress is that it only runs when it’s requested, but adding tasks to WP-Cron means they can run on any request to your site, not just a specific page. In other words, using WP-Cron pre-caching lets your site update the cached calendars whenever someone visits any page, not just the page with the calendar.
WordPress has hourly, daily and weekly cron queues, and it fires off WP-Cron when it’s shutting down after completing a request, if the allotted amount of time has passed since it last ran. (ICS Calendar Pro uses the hourly queue.) But if your site doesn’t get regular traffic, some jobs can end up “overdue”. For example: if your site only gets a hit once every three hours, an hourly cron job is going to be as much as three hours overdue.
So, if I use WP-Cron, will ICS Calendar Pro only load the calendar at most once per hour? No. The pre-caching is just an extra means of updating your calendar cache if your actual calendar page doesn’t get a lot of traffic. ICS Calendar’s code always fires off when the page containing the shortcode is loaded… pre-caching can just make the difference between always having to retrieve the calendar from the source server vs. already having it cached.
OK, so if WP-Cron isn’t real, what about a real cron job?
If you have direct server access you can set up a “real” cron job to replace WP-Cron. Some tools like cPanel also let you create cron jobs using their web-based interface.
A typical way to do this, assuming that your site has a lot of important WP-Cron tasks going on, is to disable WP-Cron’s firing on the WordPress shutdown
action, and run it as a real, OS-level cron job instead. There are several tutorials online that describe how to do this. (Note that since ICS Calendar Pro’s pre-cache option is the only way either ICS Calendar or ICS Calendar Pro uses WP-Cron, this will only affect Pro users who are taking advantage of the pre-cache feature.)
If you’re just after a way to make sure your calendar data gets pre-cached outside of WP-Cron, and you’re not necessarily interested in moving all WP-Cron tasks to a dedicated OS cron job, you can create a cron job that uses the wget
command to load the page your calendar is on, which would look something like this in your /etc/crontab
file:
*/10 * * * * root wget https://example.com/calendar > /dev/null 2>&1
The above cron command is configured to run every 10 minutes, to execute as the root user*, and to retrieve the URL https://example.com/calendar
with all output being silenced.
Using the wget
method in a “real” cron job works with either ICS Calendar (free version) or ICS Calendar Pro.
I hope this overview provides some helpful tips for how you can best optimize your caching and cron usage to get optimal performance while keeping your calendars up-to-date.
—Scott
* This cron job doesn’t really have to run as root; follow your own best practices.