Shopware 6.7, PHP 8.1 or newer, MySQL 5.7.4 or MariaDB 10.3 upwards - the latter because of session timeouts via MAX_EXECUTION_TIME. Automatic cleanup needs a running worker.
Installation
Upload the plugin in the Shopware admin, install and activate it. The module then appears under Extensions, Database Cleanup & Optimizer.
Opening the module
The module shows the current situation, manual cleanup, the settings for automatic runs and the log.
The problem: orphaned order versions
Every time an order is edited in the admin, Shopware creates a working copy - a draft. If the edit is cancelled instead of saved, that draft stays behind in the order and order_line_item tables.
Over months this adds up. Eventually admin forms such as the line items view start timing out because they have to work through tens of thousands of orphaned rows. Those are exactly the rows this plugin removes.
The delete criteria in detail
Only rows meeting both conditions are deleted:
WHERE version_id != UNHEX('0fa91ce3e96a4bc2be4bd9ce752c3425')
AND COALESCE(updated_at, created_at) < NOW() - INTERVAL X DAY
Live version protected
The current, visible order carrying version 0fa91ce3... is never touched.
Age filter
Seven days by default, which protects edits currently in progress.
What stays untouched
Order states are preserved: Order, payment and delivery states live in state_machine_history and are not version-bound. They are not touched.
Dependent tables such as order_address, order_delivery and order_transaction clean themselves up through the foreign keys, so nothing is left behind.
Current situation
The top area shows live how many orphaned order and line item versions exist, and how many of them are older than seven days. That is the honest answer to whether a run is worth it at all.
Manual cleanup
Minimum age
In days, as described in the age filter.
Batch size
Rows per DELETE, between 100 and 1,000,000.
Preview
Shows what would be deleted without deleting anything.
Running the preview before the first real cleanup is worthwhile - it costs nothing and shows the scale.
Automatic cleanup
Cleanup can run on its own. You can set the interval - hourly, every 2, 6 or 12 hours, daily or weekly - along with the minimum age and how long log entries are kept.
Prerequisite: The scheduled task only runs with an active worker, either the admin worker or messenger:consume. Without one, nothing happens.
Log
Every real run is logged, whether triggered from the admin, the console or automatically. Time, trigger, user, number of deleted rows and duration are recorded.
Aborting a running job
While a job runs, the footer shows a seconds counter. The job can be aborted at any time; DELETE batches already in flight are finished cleanly so the database stays consistent.
Ideally inside a tmux or screen session so the run survives a dropped connection. Afterwards enable automatic cleanup, daily with a seven day minimum age, and the tables stay clean for good.
Reclaiming disk space
InnoDB only marks deleted pages as free and does not hand the space back to the file system. Only this command actually reclaims it:
OPTIMIZE TABLE `order`, `order_line_item`;
Not during business hours: The command briefly locks the tables. Run it outside opening times.
Diagnostic endpoint
If a run unexpectedly deletes zero rows, this endpoint helps find the cause:
GET /api/_action/staw-order-version-cleaner/diagnose
It returns exact counts, sample version IDs and a test DELETE inside a transaction that is rolled back immediately. It changes nothing.
Safety notes
Create a database backup before every real run. Deleted rows are gone.
Handle --age-days=0 with care: Without the age filter, edits in progress can be destroyed - someone is editing an order and the draft is deleted from under them. The seven day default is the safe value.
Troubleshooting
Zero rows are deleted
Either there is nothing to delete, or all candidates are younger than the minimum age. The diagnostic endpoint shows which it is.
Disk usage does not go down
That is normal. Only OPTIMIZE TABLE releases the space.
Automatic cleanup does not run
There is no active worker. Without the admin worker or messenger:consume no scheduled task runs.
The run breaks off in the browser
Use the console for very large tables. The admin is subject to the HTTP timeout, the terminal is not.
Support
We are happy to help with the first run on a large database - get in touch via the contact page or write to info@stoneandwater.online.
All settings
Every setting of the plugin with its default value and explanation, in the same order as in the administration. The texts come straight from the plugin (version 1.0.24).
Manual cleanup
Minimum age (days)Default: 7
Only delete versions older than X days. The default of 7 protects active edit sessions. 0 = no age filter (careful!).
Batch size (rows per DELETE)Default: 50000
How many rows are removed per DELETE statement. Higher = faster, but longer table locks. Allowed: 100 to 1,000,000. Recommended: 50,000 (default), for very large tables also 100,000-250,000. Allowed range: 100 to 1000000.
Automatic cleanup
Enable automatic cleanupDefault: off
When active, cleanup runs at the configured interval via scheduled task.
IntervalDefault: Daily
How often the automatic cleanup should run: hourly, every 2, 6 or 12 hours, daily or weekly.
Minimum age (days)Default: 7
Only delete versions that are at least X days old.
Log retention (days)Default: 365
Log entries older than X days are removed automatically. 0 = keep forever.
Version commits cleanup
Minimum age (days)Default: 7
Safety filter for phase 4 (aggressive). Lower = more is cleaned.
Aggressive modeDefault: off
Additionally remove ALL non-live commits older than X days, even if their version still exists. Recommended after large cleanups.
log_entry
Minimum age (days)Default: 30
Deletes log_entry rows older than X days. 0 = empty the whole table (all entries).
Table overview & OPTIMIZE
Show tables larger than (MB)Default: 10
Tables smaller than X MB are hidden.
Heavily orphaned orders
Show orders with more than X versionsDefault: 5
Lists orders that have more than X entries in the order table (including the live version).
Through the store or directly from us.
Two routes, the same feature set - pick whichever suits your setup.
Directly from Stone & Water
Available right now
Monthly4,99 €
Best valueYearly50,90 €15 % cheaper
All prices net, plus VAT.
Download the free Plugin Suite and upload it in the admin, no SSH needed. It installs and updates the plugin with one click. You buy the licence directly from us, with an invoice from us and support straight from the developer.
The plugin will be listed in the official Shopware Community Store. Installation and automatic updates then run through the plugin manager, billing through your Shopware account. We will link it here as soon as it is live.
A lean database?
Back to Cleanup & Optimizer.
All features on the product page. We are happy to help with setup and cleanup strategy.