Cron and Publishing
The plugin relies on WordPress cron to publish scheduled activities. This page explains how the cron job works, how to configure it, and how to debug problems.
How the cron job is registered
Section titled “How the cron job is registered”On every init, the plugin checks whether the cron event is scheduled:
if ( ! wp_next_scheduled( 'buddypress_schedule_activity_publish' ) ) { $frequency = apply_filters( 'buddypress_schedule_activity_frequency', 'bp_every_min' ); wp_schedule_event( time(), $frequency, 'buddypress_schedule_activity_publish' );}The bp_every_min interval (60 seconds) is registered by the plugin. See Hooks and Filters to change the frequency.
Publishing logic
Section titled “Publishing logic”When the cron fires, buddypress_check_schedule_activity_publish() runs:
-
Acquire a transient lock. The lock key is
bpsa_publish_lockwith a 60-second TTL. If the lock already exists, the function exits immediately to prevent two concurrent cron runs processing the same activities. -
Query due activities.
SELECT a.idFROM {prefix}bp_activity aLEFT JOIN {prefix}bp_activity_meta am ON (a.id = am.activity_id)WHERE date_recorded <= %sAND am.meta_key = '_bp_activity_status'AND am.meta_value = 'scheduled' -
Atomic status update. For each activity, update
_bp_activity_statusfromscheduledtopublishing. This uses aWHERE meta_value = 'scheduled'condition so only the winning process updates the row. If$wpdb->rows_affectedis 0, the activity was already taken by another process - skip it. -
Publish. For activities where the update succeeded (
rows_affected > 0):- Delete the
_bp_activity_statusmeta entirely (makes the activity visible to the public feed). - Update
date_recordedto the current time (so the post appears at the top of the feed with an accurate timestamp).
- Delete the
-
Release the lock in a
finallyblock, ensuring it is always released even if an exception is thrown.
Setting up a real server cron job
Section titled “Setting up a real server cron job”WP-Cron only fires when someone visits your site. On low-traffic sites, scheduled posts may publish minutes late. For reliable publishing, disable WP-Cron’s HTTP-based trigger and set up a real cron job:
In wp-config.php:
define( 'DISABLE_WP_CRON', true );Cron job (run every minute):
* * * * * wget -q -O /dev/null "https://yoursite.com/wp-cron.php?doing_wp_cron" 2>/dev/nullOr using WP-CLI:
* * * * * /usr/local/bin/wp cron event run --due-now --path=/var/www/yoursite --quietChecking cron status
Section titled “Checking cron status”Via WP-CLI:
wp cron event list | grep buddypress_schedule_activityIn PHP:
$event = wp_get_scheduled_event( 'buddypress_schedule_activity_publish' );if ( $event ) { echo 'Next run: ' . gmdate( 'Y-m-d H:i:s', $event->timestamp );} else { echo 'Not scheduled.';}Clearing a stuck transient lock
Section titled “Clearing a stuck transient lock”If the cron job fails mid-run (server crash, PHP timeout), the lock can remain set and block future runs for up to 60 seconds. The lock expires automatically, but if publishing appears stuck you can clear it manually:
Via WP-CLI:
wp transient delete bpsa_publish_lockIn PHP:
delete_transient( 'bpsa_publish_lock' );Cron error logging
Section titled “Cron error logging”The plugin logs errors to the PHP error log prefixed with BPSA Cron Error: or BPSA Cron Warning:. Enable WP_DEBUG_LOG to capture these:
define( 'WP_DEBUG', true );define( 'WP_DEBUG_LOG', true );Errors logged include:
- Failed database query to fetch due activities.
- Failed atomic status update for a specific activity.
- Failed deletion of status meta.
- Failed update of
date_recorded. - Activity not found when trying to publish.
Plugin deactivation cleanup
Section titled “Plugin deactivation cleanup”When the plugin is deactivated, it clears the buddypress_schedule_activity_publish cron event and deletes the bpsa_publish_lock transient. Scheduled activities that have not yet published remain in the database but will not publish after deactivation.
On uninstall, the plugin removes the _bp_activity_status and _bp_schedule_activity_title_for_youzify meta from all activities.

