Schedule Drafts to Publish X/Day with Real Cron (Step-by-Step)
WordPress does not natively support scheduling a fixed number of draft posts to publish daily using a real system cron job. This can be a problem if you want to automate gradual content rollout without manually publishing drafts. The quick fix is to set up a real cron job that runs a WP-CLI command to publish a specified number of drafts each day.
Quick Fix
- Write a WP-CLI command to publish X drafts per run.
- Set up a system cron job to run this command daily.
- Enable logging to track published posts and errors.
Why This Happens
WordPress has a built-in cron system (WP-Cron) that relies on site visits to trigger scheduled tasks. This is unreliable for precise scheduling, especially on low-traffic sites. Also, WordPress does not have a default feature to publish a fixed number of drafts daily. Using a real system cron with WP-CLI allows precise control and reliability.
Step-by-step
1. Create a WP-CLI Command to Publish Drafts
Create a PHP file in your theme or a custom plugin directory, for example publish-drafts.php
, and add the following code:
<?php
if ( defined( 'WP_CLI' ) && WP_CLI ) {
/**
* Publish a fixed number of draft posts.
*
* ## OPTIONS
*
* <count>
* : Number of drafts to publish.
*
* ## EXAMPLES
*
* wp publish-drafts 5
*/
class Publish_Drafts_Command {
public function __invoke( $args, $assoc_args ) {
list( $count ) = $args;
$count = intval( $count );
if ( $count <= 0 ) {
WP_CLI::error( 'Count must be a positive integer.' );
return;
}
$drafts = get_posts( array(
'post_status' => 'draft',
'post_type' => 'post',
'posts_per_page' => $count,
'orderby' => 'date',
'order' => 'ASC',
'fields' => 'ids',
) );
if ( empty( $drafts ) ) {
WP_CLI::success( 'No drafts found to publish.' );
return;
}
foreach ( $drafts as $post_id ) {
$updated = wp_update_post( array(
'ID' => $post_id,
'post_status' => 'publish',
'post_date' => current_time( 'mysql' ),
'post_date_gmt' => current_time( 'mysql', 1 ),
), true );
if ( is_wp_error( $updated ) ) {
WP_CLI::warning( "Failed to publish post ID {$post_id}: " . $updated->get_error_message() );
} else {
WP_CLI::log( "Published post ID {$post_id}" );
}
}
WP_CLI::success( "Published {$count} drafts (or fewer if not enough drafts)." );
}
}
WP_CLI::add_command( 'publish-drafts', 'Publish_Drafts_Command' );
}
Then include this file in your theme’s functions.php
or better, in a custom plugin:
if ( defined( 'WP_CLI' ) && WP_CLI ) {
require_once __DIR__ . '/publish-drafts.php';
}
2. Test the WP-CLI Command
Run this command in your WordPress root directory to publish 3 drafts:
wp publish-drafts 3
You should see output confirming published posts or no drafts found.
3. Set Up a System Cron Job
Open your server’s crontab editor:
crontab -e
Add a line to run the WP-CLI command daily at 2 AM (adjust path and user accordingly):
0 2 * * * /usr/bin/wp --path=/var/www/html/your-site publish-drafts 3 >> /var/log/wp-publish-drafts.log 2>&1
/usr/bin/wp
is the WP-CLI binary path; adjust if different. --path
points to your WordPress root.
4. Enable Logging
The cron job above appends output and errors to /var/log/wp-publish-drafts.log
. Make sure the log file is writable by the cron user. You can monitor this log to verify daily publishing and troubleshoot issues.
Works on
- Web servers: Apache, Nginx, LiteSpeed
- Hosting control panels: cPanel, Plesk, DirectAdmin
- Linux-based servers with WP-CLI installed
- Any environment where you have SSH access and can create system cron jobs
FAQ
Q1: Can I schedule publishing drafts more than once per day?
Yes. Adjust the cron timing syntax to run multiple times per day, for example every 6 hours:
0 */6 * * * /usr/bin/wp --path=/var/www/html/your-site publish-drafts 3 >> /var/log/wp-publish-drafts.log 2>&1
Q2: What if I want to publish drafts of a custom post type?
Modify the WP-CLI command’s post_type
parameter in get_posts()
to your custom post type slug.
Q3: How do I install WP-CLI if it’s not available?
Follow the official WP-CLI installation guide at https://wp-cli.org/#installing. It requires PHP and command-line access.
Q4: Can I schedule publishing drafts based on categories or tags?
Yes. Extend the get_posts()
query with tax_query parameters to filter drafts by category or tag.
Q5: What if my hosting does not allow system cron jobs?
Consider using a third-party cron service (e.g., EasyCron) to trigger a custom WP-CLI endpoint or use WP-Cron with a plugin that improves its reliability.