Invite-only beta · 9 free places left · Managed hosting on AWS

AceMedia HostTalk to us

CACHING · 8 NOVEMBER 2026

Give every Redis key a lifetime, even when the code asks for a week

Plugins ask for week-long transients that set Redis key lifetimes, and some cache writes ask for no expiry at all. On a shared Redis instance, cold keys crowd out the ones sites actually read. Ace Redis Cache now caps every lifetime, and a second check found large values that were never stored at all.

Several WordPress sites on AceHost share one Redis instance for their object and page caches, each in its own namespace. Redis has a memory limit, and when it is reached it evicts the least recently used keys. That works well when most keys are useful. It works badly when much of the memory is holding things nobody will read again.

When I looked, keys on the shared instance had an average remaining lifetime of about six days. Plugins ask for week-long transients as a matter of habit. Some writes asked for no expiry at all, and earlier versions of my drop-in gave those a seven-day backstop. Most of those keys were cold long before they expired.

A Redis key lifetime cap that every write honours

Ace Redis Cache 0.8.13 cut the backstop for keys without an expiry to one day. 0.8.14 went further and added a maximum lifetime that every object cache write honours, including writes that ask for a longer one:

  • set, add, set_multiple and the shared transient path all store for at most the smaller of the requested lifetime and the cap.
  • Increments and decrements pull an existing longer lifetime down to the cap.
  • The cap defaults to one day. It can be changed per site, or turned off, and a constant in wp-config.php wins over the setting.
  • The generation counter, which the drop-in uses to invalidate a site's keys in one step, is exempt and keeps no expiry.
  • The page cache has its own optional cap on fresh time plus stale grace.

A shorter lifetime does not mean more misses for data that is in use. Anything read often is rebuilt and stored again. What changes is that a key nobody reads stops occupying memory after a day instead of a week.

Why not just add memory?

Because the working set does not grow, only the leftovers do. Raising the memory limit gives cold keys more room. Capping their lifetime keeps the memory for the data sites actually re-read.

The value that was never stored

A related trap turned up on a client's site at the same time. Its sitemaps took several seconds each to build and were around a megabyte each, so they were cached as transients. Nothing got faster.

The object cache drop-in has a maximum value size of 64 KB by default, which protects Redis from very large values. Anything bigger is silently not stored. The transient call returns, the next request finds nothing, and the sitemap is built again. A cache that quietly declines a write looks exactly like a cache that works until you time it.

Those sitemaps are now cached as files, written with an atomic rename, and served in around ten milliseconds. Other large fragments on other sites are compressed, and split into chunks where needed, so they fit under the limit.

Redis key lifetime checklist

  • Look at the remaining lifetimes of keys on your Redis instance, not only the count.
  • Set a maximum lifetime, and make sure explicit expiries respect it.
  • Give every key a lifetime, including counters, apart from the few that must persist.
  • Find out your object cache's value size limit, and time anything large you cache.
More hosting tipsTalk about your hosting

INVITE-ONLY BETA

Tell us about your site.

Nine free hosting beta invites remain for open-source projects, charities, community organisations and other public-benefit work. Tell us what you’re building; we’ll review the fit and reply personally. Fields marked * are required.

Please do not send passwords or private customer data. We’ll use these details to reply. Privacy notice.

Prefer email? Write to [email protected].