I want to auto delete images in the media library that are older than 3 days. Is there a method to do this?

  • You mean, WordPress attachments that are of the image type, and you want to delete all those images which are 3 days old from the date they were uploaded (and created as attachments)? – Sally CJ Nov 15 '18 at 5:03
  • yes that's what I want to do – TravelWhere Nov 15 '18 at 5:09

You can use these functions to find and delete image attachments that are 3 days old since their date of creation:

// Delete attachments (images) that are {n} days old.
function auto_delete_old_image_atts() {
    // How many days old.
    $days = 3;

    // TRUE = bypasses the trash and force deletion.
    $force_delete = true;

    // Get all attachments that are images.
    $atts = get_posts( array(
        'post_type'        => 'attachment',
        'post_mime_type'   => 'image/%',
        'posts_per_page'   => -1,
        'post_days_old'    => $days,
        'suppress_filters' => false,
    ) );

    $current_date = current_time( 'mysql' );
    foreach ( $atts as $att ) {
        // Get the number of days since the attachment was created.
        $created_datetime = new DateTime( $att->post_date );
        $current_datetime = new DateTime( $current_date );
        $interval = $created_datetime->diff( $current_datetime );

        // If the attachment is $days days old since its CREATION DATE, delete
        // the attachment (post data and image) and all thumbnails.
        if ( $interval->days >= $days ) {
            wp_delete_attachment( $att->ID, $force_delete );

// Filter the query so that only posts which are {n} (e.g. 3) days old will be
// returned by MySQL. For this to work, use 'post_days_old' when querying for
// posts using `get_posts()` or `new WP_Query()`.
add_filter( 'posts_clauses', 'filter_posts_by_dates_days', 10, 2 );
function filter_posts_by_dates_days( array $clauses, WP_Query $wp_query ) {
    $days = $wp_query->get( 'post_days_old' );
    if ( is_numeric( $days ) && $days >= 0 ) {
        global $wpdb;
        $clauses['where'] .= $wpdb->prepare( "
            AND ( DATEDIFF( NOW(), {$wpdb->posts}.post_date ) >= %d )
        ", $days );

    return $clauses;

For optimization purposes, we filter the WP_Query request/query so that MySQL would only select and return posts/attachments that are 3 days old; and in the foreach loop, we use PHP's built-in DateTime::diff() function to make sure that each post is actually 3 days old.

Now for the automatic deletion part, you can use wp_schedule_event like so: (see the Codex for further details)

// Schedule an event that runs once in every hour.
add_action( 'init', 'schedule_my_hourly_event' );
function schedule_my_hourly_event() {
    if ( ! wp_next_scheduled( 'my_hourly_event' ) ) {
        wp_schedule_event( time(), 'hourly', 'my_hourly_event' );

// Auto-check for old images and delete them, if any.
add_action( 'my_hourly_event', 'auto_delete_old_image_atts' );

Or you can ignore the above code and use WP Crontrol instead to add the cron event. (See the plugin's page for details on doing that)

I suggest you to disable wp-cron.php

Yes, because the auto_delete_old_image_atts() could take a long (if not very long) time to complete, so you should instead use a "real" cron job, and see this and this for more details.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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