Running the batch job over the existing media library
What the run does — and what has to be switched on beforehand
The two image modules of Kakapo Performance work at the moment WordPress generates the image sizes: the compression sets the quality and removes EXIF, IPTC and XMP markers from the generated sizes, the format module creates the WebP and AVIF derivatives. Both therefore take effect from the next upload onwards. For images that are already in the Media Library, nothing happens — and that is exactly the gap the batch run closes.
The run does not invent any work. It applies to your existing files exactly what you switched on further up for new uploads: WebP and/or AVIF, and “Remove metadata”. If none of that is on, the start button is locked and names the reason — for example that the server cannot write WebP, or that simply no setting is active. You will find the card “Reprocess existing media library” in the “Images” area below the image settings; the order in the interface matches the order of operation: first configure, then run over your existing files.
Only attachments of the type JPEG and PNG that are not in the trash are touched. The row “JPEG/PNG images in stock” tells you the number before you start.
Start, watch, pause
A click on “Start batch run” creates the run and begins immediately. The work happens in passes with a time budget of 8 seconds; after that the pass reports back, the display is updated and the next one starts after 200 milliseconds. If less than 3.5 seconds are left at the end of a pass, no further attachment is started — internally the format module allows at least three seconds per image. On servers with max_execution_time set, the budget is additionally capped at 80 percent of that limit, so that the pass is not cut off in the middle of the request.
The bar shows real progress: the number of attachments done divided by the total. Below it are the running numbers — derivatives created and skipped, one row each for WebP and AVIF, plus files stripped down and bytes freed up. Right at the bottom, the last 14 log lines run along, each with the file name and what came out for that file.
“Pause” stops the run. The button is then called “Resume”, and the next start continues exactly at the attachment where it stopped. The same happens if you simply close the tab: the run pauses, nothing is lost. If you open the page again, it queries the state and drives a run that is still open onwards by itself.
How the run survives an abort
The state is saved before the work on each individual attachment, not only afterwards. If a pass dies in the middle — the execution limit of the web server, memory, a file that GD chokes on —, then the next pass knows where it got stuck. If the same attachment goes three attempts without any progress at all, it is passed over with a plain-text line in the log instead of holding the run at one file forever.
Two admin pages open at the same time cannot get in each other's way: a lock only ever allows one pass. If a pass is shot down by the web server and the lock is left behind, it counts as orphaned after 180 seconds and is taken over.
When resuming, the total is determined afresh instead of being frozen — between pausing and resuming, files may have been uploaded or deleted. If you switch off all image settings in the middle of the run, it pauses itself instead of doing work that nobody has ordered any more. “Reset” discards progress and report; the files already created stay where they are.
Reading the report correctly
At the end there is a closing line with measured file sizes — no estimates. For every derivative created, the run compares the size of the source with the size of the result, both real values from the moment of creation. Only what was newly created in this run is counted; whatever was already converted at upload time does not show up a second time.
Three things are deliberately stated there as they are and not more prettily: WebP and AVIF get separate rows, because two derivatives are created from the same source — a joint total would count the source twice. The percentages therefore apply per row and must not be added up; a browser only ever fetches one of the two formats. And the new files take up additional space on the hard disk: the saving is in the transfer to the visitor. Storage space is really freed up only by the removal of the metadata, and those bytes are in a row of their own.
If nothing was created, the report says so too: either everything had already been done for the stock, or no result was smaller than its source. A result that is not smaller is discarded and counted as “skipped” — never as a gain.
When something is skipped
Every derivative that is not created gets a reason in plain text, and the reasons are collected in the closing line:
• “not smaller than the source file” — normal, the source file stays. • “too large for the available memory” — the format module checks the image dimensions before decoding and refuses, instead of letting PHP run into the memory limit. • “a file was already at the target location” — it is not overwritten. That typically happens when the note on the attachment was lost but the files are still there. • “not readable” — corrupt, a CMYK JPEG or an exotic variant. • “not writable” — check the permissions in the uploads folder. • “format not available on this server” — AVIF requires PHP 8.1 or newer with libavif, WebP a GD library with libwebp.
Two things that are often taken for errors but are not: a second run shows hardly any movement, because what is done is not repeated — a marker on the attachment records for how many files the removal of the metadata has already been done. And changing a quality level does not renew any file that has already been created; for that, the derivatives would have to be gone first.