The Problem
One of our e-commerce clients recently contacted us with a major issue: their daily backups were suspended due to a lack of storage. At first, the solution seemed straightforward—we could have just recommended more storage. But knowing the backups were incremental, we realized there was no obvious reason for their space usage to skyrocket. Simply adding storage would be a short-term fix, and it would increase their costs unnecessarily.
Instead, we decided to dive deeper and identify the real culprit.
Our client’s website is built on WordPress with WooCommerce, and that’s where we began our investigation.
The Discovery
Upon reviewing the WordPress installation directory, we discovered that the largest amount of storage was being consumed by files in the wp-content/uploads
directory. This directory contained all the files uploaded by customers, particularly for print-on-demand products. Customers could upload custom designs, which were stored indefinitely. Over time, these files accumulated, eating up significant storage.
The e-commerce store relied on theWooCommerce Product Add-Ons Ultimate, by Plugin Republic. for these uploads The plugin worked flawlessly for our client’s needs, but it lacked an automatic cleanup function. Our client didn’t need to keep files for orders older than 30 days, so we had a clear path forward.
Our Approach
Now, here’s where things get a bit technical.
Now, here’s where things get a bit technical.
After exploring the plugin’s implementation, we found that the relationship between each uploaded image and its respective order was stored in the post_meta
table within the database. To address the issue, we created a Stored Procedure that gathered all post_meta
entries with image paths for orders older than 30 days. Although a PHP script could handle this, we opted for SQL to achieve optimal performance—especially crucial for the first run, where we had thousands of files to process.
With a list of files tied to outdated orders, we were able to loop through each entry, deleting both the file on the server and the corresponding post_meta
entry in the database.
But there was an additional challenge: files uploaded during product customization were stored even if no order was actually placed. As a result, the server was cluttered with files that were not associated with any orders.
To address this, we took a different approach. We listed all physical files in the uploads directory and compared this list with paths from orders under 30 days old. If a file didn’t match any recent orders, it was safe to delete.
Finally, we automated the entire process by setting up a CRON job to run this cleanup daily, ensuring storage usage stayed under control.
The Results
The results were impressive! On our first cleanup run, we reduced the storage used from 60GB down to just 7GB—a massive 88% reduction. Here are some additional benefits our client enjoyed:
- Backup reliability restored: Daily backups were resumed with ease.
- Database optimization: Removing old
post_meta
entries streamlined queries and improved database performance. - Cost savings: By managing storage more efficiently, our client saved on monthly hosting costs.
- Faster disaster recovery: Smaller backups mean faster restoration times in case of an emergency.
- Smoother staging environment duplication: The process of duplicating the site for testing became much quicker.
Want more technical insights into this implementation? Feel free to reach out to us by email!