Skip to content

Instantly share code, notes, and snippets.

@kasparsd
Last active October 14, 2025 11:06
Show Gist options
  • Select an option

  • Save kasparsd/0bf0c8aad5bb1dbefb1a67836f819dcf to your computer and use it in GitHub Desktop.

Select an option

Save kasparsd/0bf0c8aad5bb1dbefb1a67836f819dcf to your computer and use it in GitHub Desktop.
Autoload all WordPress transients including those with expiration (add this as a mu-plugin)
<?php
/**
* Plugin Name: Transient Autoload
* Description: Autoload transients with expiration since they're not preloaded by WP core.
* Version: 1.0.0
*/
namespace Transient_Autoload;
function get_transient_option(): array {
global $wpdb;
$transient_options = $wpdb->get_results(
"SELECT option_name, option_value FROM $wpdb->options WHERE option_name LIKE '_transient_%'",
ARRAY_A
);
if ( ! empty( $transient_options ) && is_array( $transient_options ) ) {
return array_combine(
array_column( $transient_options, 'option_name' ),
array_column( $transient_options, 'option_value' )
);
}
return [];
}
if ( function_exists( 'wp_cache_set_multiple' ) && ! wp_installing() && ! wp_using_ext_object_cache() ) {
$transient_options = get_transient_option();
// Populate run-time object cache with expiring transients which are not autoloaded.
wp_cache_set_multiple( $transient_options, 'options' );
/**
* Avoid DB lookups for known non-existent transients.
*
* Use the `all` hook since get_transient() doesn't have anything firing
* before wp_prime_option_caches() which does the DB lookup.
*
* @see https://github.com/WordPress/wordpress-develop/blob/97382397b2bd7c85aef6d4cd1c10bafd397957fc/src/wp-includes/option.php#L1465-L1466
*/
add_action(
'all',
function( string $filter_name ) use ( $transient_options ) {
if ( 0 === strpos( $filter_name, 'pre_transient_' ) ) {
$transient_option_name = substr( $filter_name, 3 ); // Remove the `pre` prefix.
$notoptions = wp_cache_get( 'notoptions', 'options' );
if ( is_array( $notoptions ) && ! isset( $notoptions[ $transient_option_name ] ) && ! isset( $transient_options[ $transient_option_name ] ) ) {
// Mark transient and timeout options as known notoption.
$notoptions[ $transient_option_name ] = true;
$notoptions[ str_replace( '_transient_', '_transient_timeout_', $transient_option_name ) ] = true;
wp_cache_set( 'notoptions', $notoptions, 'options' );
}
}
}
);
}
@kasparsd
Copy link
Author

kasparsd commented Oct 14, 2025

By default, transient values with expiry aren't included in the alloptions cache (because they have autoload=no) so WordPress doesn't preload their values.

This must-use plugin adds all transient option values to in-memory cache when an external (persistent) object cache is not used. In case of external object cache, the transient values with expiry timestamp would be cached so no need to re-populate that data.

Transient values persisted in options run-time cache

Use the following snippet to check the DB query with and without the plugin active:

foreach ( range( 1, 100 ) as $i ) {
	$sample = get_transient( 'non-existing-transient-' . time() . $i );
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment