# Media Library Disk Usage by Type and Year (WP-CLI)

> Adds a "wp media-usage" command that totals how much disk space uploads use, grouped by file type or by upload year, including every generated image size, to see what fills your hosting space.

- Type: PHP
- Runs: Run everywhere
- Category: [Developer](https://wpide.com/library/category/developer/)
- Tags: wp-cli, media, disk-space
- Author: WPIDE Team
- Installs: 0
- Updated: 2026-10-28
- Page: https://wpide.com/library/cli-media-size-report/

## Code

```php
if ( ! defined( 'WP_CLI' ) || ! WP_CLI ) {
    return;
}

WP_CLI::add_command( 'media-usage', function ( $args, $assoc_args ) {
    $by     = ( $assoc_args['by'] ?? 'type' ) === 'year' ? 'year' : 'type';
    $totals = array();
    $paged  = 1;

    do {
        $ids = get_posts( array(
            'post_type'      => 'attachment',
            'post_status'    => 'inherit',
            'posts_per_page' => 500,
            'paged'          => $paged++,
            'fields'         => 'ids',
            'no_found_rows'  => true,
        ) );

        foreach ( $ids as $id ) {
            $file  = get_attached_file( $id );
            $bytes = $file && file_exists( $file ) ? filesize( $file ) : 0;
            $meta  = wp_get_attachment_metadata( $id );
            foreach ( (array) ( $meta['sizes'] ?? array() ) as $size ) {
                $path   = $file ? path_join( dirname( $file ), $size['file'] ) : '';
                $bytes += $path && file_exists( $path ) ? filesize( $path ) : 0;
            }
            if ( ! empty( $meta['original_image'] ) && $file ) {
                $original = path_join( dirname( $file ), $meta['original_image'] );
                $bytes   += file_exists( $original ) ? filesize( $original ) : 0;
            }

            $group = 'year' === $by ? get_the_date( 'Y', $id ) : ( get_post_mime_type( $id ) ? get_post_mime_type( $id ) : 'unknown' );
            $totals[ $group ]['files'] = ( $totals[ $group ]['files'] ?? 0 ) + 1;
            $totals[ $group ]['bytes'] = ( $totals[ $group ]['bytes'] ?? 0 ) + $bytes;
        }
    } while ( count( $ids ) === 500 );

    uasort( $totals, function ( $a, $b ) {
        return $b['bytes'] <=> $a['bytes'];
    } );

    $rows = array();
    foreach ( $totals as $group => $data ) {
        $rows[] = array( $by => $group, 'files' => $data['files'], 'size' => size_format( $data['bytes'], 1 ) );
    }

    if ( ! $rows ) {
        WP_CLI::success( 'The Media Library is empty.' );
        return;
    }

    WP_CLI\Utils\format_items( $assoc_args['format'] ?? 'table', $rows, array( $by, 'files', 'size' ) );
}, array(
    'shortdesc' => 'Shows Media Library disk usage grouped by type or year.',
    'synopsis'  => array(
        array( 'type' => 'assoc', 'name' => 'by', 'optional' => true, 'default' => 'type', 'options' => array( 'type', 'year' ) ),
        array( 'type' => 'assoc', 'name' => 'format', 'optional' => true, 'default' => 'table', 'options' => array( 'table', 'csv', 'json' ) ),
    ),
) );
```

## Notes

Run "wp media-usage --by=year" or "--by=type" (default); it reads file sizes from disk, so large libraries take a moment.

## How to use it

Install the free WPIDE plugin (https://wordpress.org/plugins/wpide/), find "Media Library Disk Usage by Type and Year (WP-CLI)" in its snippet library and add it in one click; or create a new PHP snippet in WPIDE (or any code snippets plugin) and paste the code above. More snippets: https://wpide.com/library/
