I am using WP-Crontrol and have some CRON jobs running daily to check the age of the posts. If the post is 2 days older, they will be deleted.

This works but for some reason, only some of the three days and older posts get deleted. There are still some that remain published.

It must be because there are a lot of posts on the site around 3000. Is there a way to make my CRON job more efficient?

Here is the current code that I have running:

class EventsWPCron {

    public function __construct() {

        if ( ! wp_next_scheduled( 'trash_old_events' ) ) {
            wp_schedule_event( time(), 'daily', 'trash_old_events' );

        add_action( 'trash_old_events', array( $this, 'delete_events' ) ); 


    public function delete_events() {
        $args = array(
            'post_type' => 'event',
            'post_status' => 'publish',
            'posts_per_page' => -1,
            'date_query' => array(
                    'before' => '2 days ago'

        $query = new WP_Query( $args );
        $posts = $query->get_posts();

        foreach( $posts as $post ) { 
            wp_delete_post( $post->ID, true );



new EventsWPCron();
  • You can get only post ID in WP_Query, add 'fields' => 'ids' to args array (WP Codex).
    – nmr
    Commented Aug 12, 2018 at 6:32

2 Answers 2


You're not specifying the number of posts you want back from the query, so it defaults to whatever you have set under Settings > Reading.

If you want all that match your criteria, then add 'posts_per_page' => -1 to your query arguments.

  • Thanks. I actually have it already in my code but still, the same thing is happening. I updated the code in my post. Commented Aug 11, 2018 at 19:56
  • But if there are many posts, then the cron handler function can get killed... Commented Aug 12, 2018 at 6:10

Almost always there is a time limit set for PHP scripts. If a script runs longer than the limit, it gets killed.

So if there are many posts to delete, then there is a chance that the script gets killed, so it deletes only part of them.

But doing it this way isn’t very efficient either - what if there will be many many posts, so they won’t fit in memory limit?

Much better approach would be to run your cron event more often and delete only part of old posts. It will be much nicer for server too...

So instead of running it daily, run it hourly and put an explicit limit in the query. Let’s say there are 1000 posts to delete on average. So your script should remove 42 hourly. Let’s set it to 100 - this way you’ll be sure all of them will be deleted.

And if they should be deleted faster, then set the cron event to run even more often - every 5 minutes?

PS. There is one more thing worth noticing. If old posts should not be shown on site, then I would modify queries in such way, that these posts will be ignored. Relying on cron in this case won’t be very good idea (deleting posts may take a while, cron may not get called and so on...). Of course you can still delete them after they are ignored by all site queries...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.