Skip to content

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.

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.

When the cron fires, buddypress_check_schedule_activity_publish() runs:

  1. Acquire a transient lock. The lock key is bpsa_publish_lock with a 60-second TTL. If the lock already exists, the function exits immediately to prevent two concurrent cron runs processing the same activities.

  2. Query due activities.

    SELECT a.id
    FROM {prefix}bp_activity a
    LEFT JOIN {prefix}bp_activity_meta am ON (a.id = am.activity_id)
    WHERE date_recorded <= %s
    AND am.meta_key = '_bp_activity_status'
    AND am.meta_value = 'scheduled'
  3. Atomic status update. For each activity, update _bp_activity_status from scheduled to publishing. This uses a WHERE meta_value = 'scheduled' condition so only the winning process updates the row. If $wpdb->rows_affected is 0, the activity was already taken by another process - skip it.

  4. Publish. For activities where the update succeeded (rows_affected > 0):

    • Delete the _bp_activity_status meta entirely (makes the activity visible to the public feed).
    • Update date_recorded to the current time (so the post appears at the top of the feed with an accurate timestamp).
  5. Release the lock in a finally block, ensuring it is always released even if an exception is thrown.

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):

Terminal window
* * * * * wget -q -O /dev/null "https://yoursite.com/wp-cron.php?doing_wp_cron" 2>/dev/null

Or using WP-CLI:

Terminal window
* * * * * /usr/local/bin/wp cron event run --due-now --path=/var/www/yoursite --quiet

Via WP-CLI:

Terminal window
wp cron event list | grep buddypress_schedule_activity

In 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.';
}

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:

Terminal window
wp transient delete bpsa_publish_lock

In PHP:

delete_transient( 'bpsa_publish_lock' );

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.

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.