I have taken over a magento store that over 3 years has built up a large amount of product images that are no longer in use but were never deleted.

Is there a way i can delete all images that are no longer in use, whilst keeping all images that are being used? I searched for a module/extension but couldn't find one that worked with magento 1.9 community.

  • Magento doesn't do picture windows, sometimes other housekeeping optional such as old quotes... Which causes filesystem and database bloat. Which spawned the Image Clean module over on Connect for the first, various scripts for quote cleaning that depend on innodb delete on cascade to eliminate by past dates Apr 26, 2015 at 3:53

7 Answers 7


you can try the following shell script: https://gist.github.com/aleron75/07ab2a950b2e3429a820

I haven't tested it on v 1.9.x. yet

Note: do a backup before using it on a production environment and possibly test it on a staging environment before.

Hope it helps.

Kind regards, Alessandro

  • I don't have access to shell, is there a way to do this in PHP?
    – odd_duck
    Mar 4, 2015 at 18:22
  • Well, if you understand the underlying logic you can try to port the script in a controller action method. Mar 4, 2015 at 19:10

You could upload this script to the root of your Magento installation and run it even from your browser.


Check if your attributes for media are having these ids.

If you forget this, you could possibly break things

cpv.attribute_id in(85, 86, 87)

It will create checksums to detect duplicate files per product and unlink these from the filesystem and database.

The second step is detecting file which are on the filesystem and not in the database anymore.

Used it from 1.7 and up, so it should work.

If you are smart, I always recommend to create a backup first.


You can put in Magento root path this PHP script and call it from browser:

Script Web Console

The script will run by default in dry-mode for a safe test letting you actually delete orphans if everything sounds convincing.

  • this script display only unused image but not delete images from database... Aug 9, 2018 at 7:14

I would recommend heading over to

System -> Cache Management -> Flush Catalog Image Cache.

This will remove all the generated images and then re-generate them when a user hits the site.


I recommend using this n98-magerun module called EAVCleaner

After installing, run the following command to remove unused product images

n98-magerun eav:media:remove-unused

An advantage of using this module over the other scripts is that it can delete a larger quantity of images. Most of the other scripts linked above will create an array of images, then delete. This will traverse the media directory and remove the unused image when it finds it

We encountered an issue where a client's product information management system was uploading new product images every day and the media directory ballooned to nearly 400 GB in size. Every other script we found tried to put the hundreds of image file paths in memory and would error out. This script did the trick


Place the below script in magento root and execute


  $ob = new Clean();

  Class Clean {

  function removemedia() {
    $read = Mage::getSingleton('core/resource')->getConnection('core_read');
    $select = $read->select()
            ->from('catalog_product_entity_media_gallery', '*')

    $flushImages = $read->fetchAll($select);
    echo count($flushImages);
    $array = array();
    foreach ($flushImages as $item1) {
        $array[] = $item1['value'];

    $valores = $array;

    $pepe = 'media' . DS . 'catalog' . DS . 'product';

    $leer = $this->listDirectories($pepe);

    foreach ($leer as $item) {
        try {
            $item = strtr($item, '\\', '/');
            if (!in_array($item, $valores)) {
                $valdir[]['filename'] = $item;
                unlink('media/catalog/product' . $item);
        } catch (Zend_Db_Exception $e) {

        } catch (Exception $e) {

function listDirectories($path) {
    if (is_dir($path)) {
        if ($dir = opendir($path)) {
            while (($entry = readdir($dir)) !== false) {
                if (preg_match('/^\./', $entry) != 1) {
                    if (is_dir($path . DS . $entry) && !in_array($entry, array('cache', 'watermark'))) {
                        $this->listDirectories($path . DS . $entry);
                    } elseif (!in_array($entry, array('cache', 'watermark')) && (strpos($entry, '.') != 0)) {
                        $this->result[] = substr($path . DS . $entry, 21);
    return $this->result;


this way worked very well for me:

github repository

How to use:

Step 1: Check directory size before execution

du -s

Step 2:Copy Mr. dajve code and create a file in

vi shell/shell_delete_unused_images.php

Step 3: Execute file

php shell/shell_delete_unused_images.php

Step 4: Check directory size after execution

du -s

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.