Gatilab Products

Release Notes

Improvements, fixes, and the details behind each release.

GT Performance

Page caching, asset optimization, Cloudflare integration, and cache diagnostics.

View Product
← All GT Performance Releases
Beta

GT Performance 1.0.0-beta-5

Changed

  • Moved the everyday operations — purge GT cache, Cloudflare sync, and the two drop-in installers — from the Tools tab onto the dashboard. Purging after a content change no longer takes a detour, and the installers are visible during setup, which is exactly when they are needed. Tools keeps runtime drop-in status and database maintenance. Each operation now remembers which screen it was run from and returns there instead of always landing on Tools.

Fixed

  • Stale pages are now rebuilt instead of being served indefinitely. Nothing regenerated an entry between fresh_ttl and stale_ttl: the drop-in served the stale body and exited, and a preload request received that same stale body, so the only escape from the stale window was stale_until expiring. A live site measured 1,011 of 1,023 cached pages stale, median age 14.3 hours. The queue now sweeps for stale entries on each scheduled run and enqueues preloads, and the drop-in treats a stale entry as a miss when the request carries X-GT-Preload, so those preloads actually rebuild the page. Batches are capped at 5 per run — matching what the queue drains per tick, since enqueue() does not deduplicate — and skipped entirely while a preload backlog is still pending, so the job table cannot grow faster than it clears. The cap is filterable via gt_performance_revalidate_batch.
  • Fixed the Redis object cache silently flushing nothing. flush() and flush_group() build a SCAN MATCH pattern from the key prefix, which defaults to WP_CACHE_KEY_SALT — a random string that regularly contains [, ?, or *, all glob metacharacters. An unclosed [ makes the pattern match zero keys, so both calls deleted nothing and still returned true; a live site's wp cache flush reported success while the entries stayed in Redis. Literal prefixes are now escaped before use in a pattern.
  • Re-arm the queue cron when the scheduled event is missing. Activator schedules it once at activation and nothing restored it if it was later lost, which stops the queue permanently: purges never preload, warms never run, stale pages are never rebuilt. A production site was found with the event absent and jobs pending for seven days.
  • Invalidate a rebuilt page's metadata in the opcode cache. The drop-in reads metadata with include, so a refreshed entry could be read back with its previous timestamps until opcache revalidated — and never, on a host running opcache.validate_timestamps=0.
  • Wrapped the Redis object cache's SCAN loop in the same error handling every other Redis call already had. It was the one unguarded call in the drop-in, so a mid-scan disconnect raised an uncaught RedisException through group flushes and took the request down with a fatal instead of degrading to a cache miss. The loop is now bounded as well, so a driver that returns without advancing the cursor cannot spin.