Quicksave Performance Improvements

Quicksaves are my go to when troubleshooting WordPress issues. Arguably one of the most useful feature of CaptainCore, if you ask me :). They track themes and plugins with a visual breakdown of what changed and when. A huge time saver at identifying source of disruptions. Best of all, any theme or plugin can individually be rolled back to a previous version without messing around with site backups or undoing other parts of WordPress.

Under the hood quicksaves are just a git repo, a bit of UI and some cleaver WordPress version tracking information. With daily scans these quicksaves really start to add up. Recently I’ve noticed performance issues while trying to view them. My own site has collected 582 quicksaves over a 3 year timeframe. Loading the quicksave section can take anywhere from 5 seconds to 30 seconds of loading time. Yikes! Let’s dig in how it got this slow and what I’m doing to resolve the bottleneck.

Backup tab within CaptainCore for a site
List of Quicksaves within CaptainCore for a site

Quicksaves are synced to a WordPress custom database table.

While my maintenance server handles generating new quicksavesas via bash scripts within CaptainCore, a copy of that data is then pushed up to WordPress and stored in a custom database table. That is how quicksaves are viewable from the WordPress interface. This has worked well for the first few years of collection however is now too slow. You see each time WordPress reads in the list of quicksaves it has to do a bunch of complicated calculations to determine what changed and how to visually show it. Not to mention the massive database usage as shown here.

Custom WordPress table with 276,230 rows and over 900MBs of data.
Quicksave table structure

Does WordPress really need all of that data?

I took some architectural inspiration from how I built the backup interface which is powered by Restic, a command line application. With backups nothing is stored within WordPress itself except for a few metrics so I can show how many backup snapshots have been made. Viewing the backup simply asks the maintenance server for a list of backups. The maintenance server will then ask Restic for a response or return a cached Restic response stored as JSON files. This works surprisingly well for a quick and efficient interface.

I think the same lean approach for quicksaves makes sense. As in couldn’t I just drop the wp_captaincore_quicksaves table entirely and let the interface talk to the quicksave git repos directly? Well that’s what I’m doing. This requires a few cleaver reworking. Using git log you can only extract a minimal amount of information like the hash, created date and commit message. For quicksaves to work properly I information from inside each git commit. Information like the theme and plugin manifest which is stored in various json files as shown below. That’s not possible within the context of git log and it would get really time consuming to do even if it was possible.

Plugin manifest as stored within an individual quicksave.

Generated JSON responses for fast quicksave list generation.

In order to keep the list generation process quick, I decided to move the heavy process time to generating individual quicksave responses. Once those are generated as JSON files, I can then patch information from those files into the full quicksave list. That keeps the full quicksave list generation quite lightweight. That’s great because the list needs to be regenerated each time a new quicksave is added.

Generated quicksave list and individual responses.

Fetching a JSON file requires very little processing time. Based on what I’m seeing in local development I expect this to fully resolve the performance bottleneck. These new improvements will be rolled out with the next CaptainCore v0.13.0 release.