SlideShare a Scribd company logo
speed things up with
 transients
@cliffseal
#wptrans
logos-creative.com/
     wcatl
LOL WUTAPI?
is the Transients
The Transients API
“offers a simple and standardized
way of storing cached data in the
database temporarily by giving it a
custom name and a timeframe after
which it will expire and be deleted.”
The Transients API

✓ like Options API, but with expiration
✓ uses fast memory (if configured)
✓ uses database otherwise
Native        Object Cache Plugin

               Persistent
 Option                              N/A
              (database)

               Persistent
Transient                     Persistent (varies)
              (database)

            Non-persistent
 Cache                        Persistent (varies)
              (memory)
                                              Thanks to Rarst.
thetransientsAPI




         Tweets             Friends                Scrobbles

                  Options API: Username, URL, ID



          externalAPIs
thetransientsAPI




         Tag Cloud   Ratings   Custom Queries




      expensivequeries
3
mainfunctions
mainfunctions

        set_transient(
           $transient,
           $value,
           $expiration
        );
         set_transient
mainfunctions


$transient
✓   (string) a unique identifier for your cached data

✓   45 characters or less in length

✓   For site transients, 40 characters or less in length



        set_transientargs
mainfunctions


$value
✓   (array|object) Data to save, either a regular variable or an
    array/object

✓   Handles serialization of complex data for you



        set_transientargs
mainfunctions


$expiration
✓   (integer) number of seconds to keep the data before
    refreshing

✓   Example: 60*60*24 or 86400 (24 hours)



       set_transientargs
mainfunctions



MINUTE_IN_SECONDS   =   60 (seconds)
HOUR_IN_SECONDS     =   60 * MINUTE_IN_SECONDS
DAY_IN_SECONDS      =   24 * HOUR_IN_SECONDS
WEEK_IN_SECONDS     =   7 * DAY_IN_SECONDS
YEAR_IN_SECONDS     =   365 * DAY_IN_SECONDS



        timeconstants
mainfunctions


get_transient($transient);
✓   If the transient does not exist, or has expired, returns false

✓   An integer value of zero/empty could be the stored data

✓   Should not be used to hold plain boolean values; array or
    integers instead


              get_transient
mainfunctions




delete_transient($transient);



      delete_transient
mainfunctions


 set_site_transient();
 get_site_transient();
delete_site_transient();
                These work ‘network wide’.


          wpmultisite
3
exampleusecases
cachetagcloud
cachetagcloud

function get_tag_cloud() {

    if ( false === ( $tag_cloud = get_transient( 'my_tag_cloud' ) ) ) {

        $tag_cloud = wp_tag_cloud( 'echo=0' );
        set_transient( 'my_tag_cloud', $tag_cloud, 60*60*24 );

    } else {

        $tag_cloud = get_transient( 'my_tag_cloud' );

    }

    return $tag_cloud;

}
EXPERT

MODE
cachetagcloud

function edit_term_delete_tag_cloud() {

    delete_transient( 'my_tag_cloud' );

}

add_action( 'edit_post', 'edit_term_delete_tag_cloud' );
cachemyissues
cachemyissues
function we_have_issues() {
    if ( false === ( $issues = get_transient( 'we_have_issues' ) ) ) {
        $response = wp_remote_get('https://api.github.com/repos/twitter/bootstrap/
issues?assignee');
        if ( is_wp_error( $response ) ) {
             $error_message = $response->get_error_message();
            echo "This borked: " . $error_message;
        } else {
             $issues = wp_remote_retrieve_body($response);
             set_transient( 'we_have_issues', $issues, 60*60*24 );
        }
    } else {
        $issues = get_transient( 'we_have_issues' );
    }
    $issues = json_decode($issues, true);
    $issuereturn = '';
    for ( $i = 0; $i < 5; $i++ ) {
        $issuereturn .= "<h3><a href='" . $issues[$i]["html_url"] . "'>".
$issues[$i]["title"] . "</a></h3>";
    }
    return $issuereturn;
}
EXPERT

MODE
cachemyissues
function refresh_my_issues() {
    delete_transient( 'we_have_issues' );
}

if ( is_admin() && isset($_GET['forcedel']) && $_GET['forcedel'] === 'yes' ) {
    refresh_my_issues();
}

function refresh_via_admin_bar() {
    global $wp_admin_bar;
    $wp_admin_bar->add_menu( array(
        'title' => __('Refresh'),
        'href' => admin_url('?forcedel=yes'),
        'id' => 'refresh-issues',
        'parent' => false
    ) );

}

add_action( 'wp_before_admin_bar_render', 'refresh_via_admin_bar' );
cachebigquery
cachebigquery
function query_for_commenters() {
    if ( false === ( $commenters = get_transient( 'top_commenters_cached' ) ) ) {
        global $wpdb;
        $commenters = $wpdb->get_results("
           select count(comment_author) as comments_count, comment_author, comment_type
    ! ! ! from $wpdb->comments
    ! ! ! where comment_type != 'pingback'
    ! ! ! and comment_author != ''
    ! ! ! and comment_approved = '1'
    ! ! ! group by comment_author
    ! ! ! order by comment_author desc
    ! ! ! LIMIT 10
         ");
        set_transient( 'top_commenters_cached', $commenters, 60*60*24 );
    } else {
        $commenters = get_transient( 'top_commenters_cached' );
    }
    $comment_list = '<ol>';
    foreach($commenters as $commenter) {
        $comment_list .= '<li>';
        $comment_list .= $commenter->comment_author;
        $comment_list .= ' (' . $commenter->comments_count . ')';
        $comment_list .= '</li>';
    }
    $comment_list .= '</ol>';
    return $comment_list;
}
cachebigquery

function delete_query_for_commenters() {

    delete_transient( 'top_commenters_cached' );

}

add_action( 'comment_post', 'delete_query_for_commenters' );
cachebigquery
function popular_posts( $num=10 ) {
    if ( false === ( $popular = get_transient( 'popular_posts' . $num ) ) )
{
        $query = new WP_Query( array(
             'orderby' => 'comment_count',
             'posts_per_page' => $num
        ) );
        set_transient( 'popular_posts' . $num, $query, 60*60*24 );
    } else {
        $query = get_transient( 'popular_posts' . $num );
    }

    return $query;
}
cachebigquery

$newquery = popular_posts(3);
if ( $newquery->have_posts() ) {
    while ( $newquery->have_posts() ) {
        $newquery->the_post(); ?>
    <h4><?php the_title(); ?></h4>
        <?php the_excerpt(); ?>
    <?php
    }
    wp_reset_postdata();
}
cachebigquery

function clear_popular_posts() {

    for ( $i = 0; $i < 50; $i++ ) {

        delete_transient( 'popular_posts' . $i );

    }

}

add_action( 'edit_post', 'clear_popular_posts' );
EXPERT

MODE
cachebigquery

    Once a transient expires, it remains so until the new result is saved.
    Heavy traffic can mean too many concurrent MySQL connections.

function popular_posts_panic( $num=10 ) {
    if ( false === ( $popular =
get_transient( 'popular_posts' . $num ) ) ) {
        return '';
    } else {
        $query = get_transient( 'popular_posts' . $num );
    }

     return $query;
}
                                                           Thanks to Andrew Gray for the idea.
cachebigquery

$newquery = popular_posts_panic(3);
if ( $newquery !== '' ) {
    if ( $newquery->have_posts() ) {
        while ( $newquery->have_posts() ) {
            $newquery->the_post(); ?>
        <h4><?php the_title(); ?></h4>
            <?php the_excerpt(); ?>
        <?php
        }
        wp_reset_postdata();
    }
}
cachebigquery
function renew_popular_posts() {
    for ( $i = 0; $i < 50; $i++ ) {
        if ( false === ( $popular = get_transient( 'popular_posts' .
$i ) ) ) {
            delete_transient( 'popular_posts' . $i );
            $query = new WP_Query( array(
                'orderby' => 'comment_count',
                'posts_per_page' => $i
            ) );
            set_transient( 'popular_posts' . $i, $query, 60*60*24*365 );
        }
    }
}

if ( !wp_next_scheduled( 'renew_popular_posts' ) ) {
    wp_schedule_event( time(), 'hourly', 'renew_popular_posts' );
}
TOP OF HACKER NEWS


  CONQUERED
4
warnings
Speed Things Up with Transients
expiry&garbagecollection


✓ everything works on request
✓ expired != deleted, unless requested
✓ unrequested, undeleted transients stay
  until you remove them explicitly
scalarvalues

✓ accepts scalar values (integer, float,
  string or boolean) & non-scalar
  serializable values (arrays, some
  objects)
✓ SimpleXMLElement will FREAK.
  OUT., so convert it to a string or array
  of objects (i.e. simplexml_load_string)
infinitetransients

✓ transients set without an expiration
  time are autoloaded

✓ if you don’t need it on every page, set
  an expiration (even if it’s a year)

✓ consider the Options API for non-
  transient data
cachinggotchas

✓ in some shared hosting environments,
  object caching can be slower than
  using the database; check your host’s
  recommended settings
✓ always use the Transients API to access
  transients; don’t assume they’re in
  the database (or vice versa)
3
usefultools
usefultools




    TLC Transients                               Artiss Transient Cleaner
                       Debug Bar Transients
    Supports soft-                                    Deletes expired
                       Adds panel to Debug
      expiration,                                transients and optimizes
                       Bar with transient info
 background updating                                       table
?
questions
logos-creative.com/
     wcatl

More Related Content

What's hot (20)

KEY
MTDDC 2010.2.5 Tokyo - Brand new API
Six Apart KK
 
PDF
Database Design Patterns
Hugo Hamon
 
PDF
PHP tips and tricks
Damien Seguy
 
PDF
The History of PHPersistence
Hugo Hamon
 
TXT
Gta v savegame
hozayfa999
 
KEY
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
Masahiro Nagano
 
PPTX
Drupal7 dbtng
Nicolas Leroy
 
PDF
Doctrine 2
zfconfua
 
PDF
PHP 5.3 and Lithium: the most rad php framework
G Woo
 
PDF
Intro to advanced caching in WordPress
Maor Chasen
 
PDF
Drupal - dbtng 25th Anniversary Edition
ddiers
 
PDF
From mysql to MongoDB(MongoDB2011北京交流会)
Night Sailer
 
PDF
WordPress as an application framework
Dustin Filippini
 
PDF
A Tour to MySQL Commands
Hikmat Dhamee
 
PDF
Spock and Geb
Christian Baranowski
 
PDF
The Zen of Lithium
Nate Abele
 
PDF
Everything About PowerShell
Gaetano Causio
 
KEY
The Query the Whole Query and Nothing but the Query
Chris Olbekson
 
PDF
What's new in Doctrine
Jonathan Wage
 
KEY
究極のコントローラを目指す
Yasuo Harada
 
MTDDC 2010.2.5 Tokyo - Brand new API
Six Apart KK
 
Database Design Patterns
Hugo Hamon
 
PHP tips and tricks
Damien Seguy
 
The History of PHPersistence
Hugo Hamon
 
Gta v savegame
hozayfa999
 
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
Masahiro Nagano
 
Drupal7 dbtng
Nicolas Leroy
 
Doctrine 2
zfconfua
 
PHP 5.3 and Lithium: the most rad php framework
G Woo
 
Intro to advanced caching in WordPress
Maor Chasen
 
Drupal - dbtng 25th Anniversary Edition
ddiers
 
From mysql to MongoDB(MongoDB2011北京交流会)
Night Sailer
 
WordPress as an application framework
Dustin Filippini
 
A Tour to MySQL Commands
Hikmat Dhamee
 
Spock and Geb
Christian Baranowski
 
The Zen of Lithium
Nate Abele
 
Everything About PowerShell
Gaetano Causio
 
The Query the Whole Query and Nothing but the Query
Chris Olbekson
 
What's new in Doctrine
Jonathan Wage
 
究極のコントローラを目指す
Yasuo Harada
 

Similar to Speed Things Up with Transients (20)

PPTX
Transients are good for you - WordCamp London 2016
Julio Potier
 
PDF
Introduction to the WordPress Transients API
topher1kenobe
 
PDF
Caching in WordPress
Tareq Hasan
 
PPTX
Caching, Scaling, and What I've Learned from WordPress.com VIP
Erick Hitter
 
PPTX
Lightweight use of transients
Phil Marx
 
PDF
WordPress Transients
Tammy Hart
 
PDF
Clug 2012 March web server optimisation
grooverdan
 
PDF
WordCamp San Francisco 2011: Transients, Caching, and the Complexities of Mul...
andrewnacin
 
PDF
Options, and Transients, and Theme Mods — Oh my!
Konstantin Obenland
 
PDF
Balancing Act of Caching LoopConf 2018
Maura Teal
 
KEY
Introduction to memcached
Jurriaan Persyn
 
PPTX
Consuming & embedding external content in WordPress
Akshay Raje
 
ODP
Caching and tuning fun for high scalability
Wim Godden
 
KEY
Caching: A Guided Tour - 10/12/2010
Jason Ragsdale
 
PDF
Cache Rules Everything Around Me
Russell Heimlich
 
PDF
Your backend architecture is what matters slideshare
Colin Charles
 
PDF
Balancing Act of Caching, WordCamp Europe 2018
Maura Teal
 
PDF
The Need For Speed: Caching Fundamentals
Frankie Jarrett
 
PDF
WordPress Speed & Performance from Pagely's CTO
Lizzie Kardon
 
KEY
DjangoCon 2010 Scaling Disqus
zeeg
 
Transients are good for you - WordCamp London 2016
Julio Potier
 
Introduction to the WordPress Transients API
topher1kenobe
 
Caching in WordPress
Tareq Hasan
 
Caching, Scaling, and What I've Learned from WordPress.com VIP
Erick Hitter
 
Lightweight use of transients
Phil Marx
 
WordPress Transients
Tammy Hart
 
Clug 2012 March web server optimisation
grooverdan
 
WordCamp San Francisco 2011: Transients, Caching, and the Complexities of Mul...
andrewnacin
 
Options, and Transients, and Theme Mods — Oh my!
Konstantin Obenland
 
Balancing Act of Caching LoopConf 2018
Maura Teal
 
Introduction to memcached
Jurriaan Persyn
 
Consuming & embedding external content in WordPress
Akshay Raje
 
Caching and tuning fun for high scalability
Wim Godden
 
Caching: A Guided Tour - 10/12/2010
Jason Ragsdale
 
Cache Rules Everything Around Me
Russell Heimlich
 
Your backend architecture is what matters slideshare
Colin Charles
 
Balancing Act of Caching, WordCamp Europe 2018
Maura Teal
 
The Need For Speed: Caching Fundamentals
Frankie Jarrett
 
WordPress Speed & Performance from Pagely's CTO
Lizzie Kardon
 
DjangoCon 2010 Scaling Disqus
zeeg
 
Ad

More from Cliff Seal (20)

PDF
Trust in the Future
Cliff Seal
 
PDF
Building Advocates with World-Class Customer Experiences
Cliff Seal
 
PDF
Mastering B2B Email
Cliff Seal
 
PDF
Death to Boring B2B Marketing, Part 2: Jobs-to-Be-Done
Cliff Seal
 
PDF
DIY WordPress Site Management: Configure, Launch, and Maintain
Cliff Seal
 
PDF
Inviting Experimentation by Design
Cliff Seal
 
PDF
Death to Boring B2B Marketing: How Applying Design Thinking Drives Success
Cliff Seal
 
PDF
Introducing WordPress Multitenancy (Wordcamp Vegas/Orlando 2015/WPCampus)
Cliff Seal
 
PDF
People Over Pixels: Meaningful UX That Scales
Cliff Seal
 
PDF
Friendlier, Safer WordPress Admin Areas
Cliff Seal
 
PDF
Meaningful UX At Any Scale
Cliff Seal
 
PDF
No one cares about your content (yet): WordCamp Charleston 2014
Cliff Seal
 
PDF
Usability, Groupthink, and Authority
Cliff Seal
 
PDF
Get Started in Professional WordPress Design & Development
Cliff Seal
 
PDF
No One Cares About Your Content (Yet): WordCamp Chicago 2013
Cliff Seal
 
PDF
No One Cares About Your Content (Yet): WordCamp Miami 2013
Cliff Seal
 
PDF
A Brief History of Metal
Cliff Seal
 
PDF
No One Cares About Your Content (Yet): WordCamp Phoenix 2013
Cliff Seal
 
PDF
WordPress and Pardot: The World’s Newest Power Couple
Cliff Seal
 
PDF
No One Cares About Your Content (Yet): Digital Atlanta 2012
Cliff Seal
 
Trust in the Future
Cliff Seal
 
Building Advocates with World-Class Customer Experiences
Cliff Seal
 
Mastering B2B Email
Cliff Seal
 
Death to Boring B2B Marketing, Part 2: Jobs-to-Be-Done
Cliff Seal
 
DIY WordPress Site Management: Configure, Launch, and Maintain
Cliff Seal
 
Inviting Experimentation by Design
Cliff Seal
 
Death to Boring B2B Marketing: How Applying Design Thinking Drives Success
Cliff Seal
 
Introducing WordPress Multitenancy (Wordcamp Vegas/Orlando 2015/WPCampus)
Cliff Seal
 
People Over Pixels: Meaningful UX That Scales
Cliff Seal
 
Friendlier, Safer WordPress Admin Areas
Cliff Seal
 
Meaningful UX At Any Scale
Cliff Seal
 
No one cares about your content (yet): WordCamp Charleston 2014
Cliff Seal
 
Usability, Groupthink, and Authority
Cliff Seal
 
Get Started in Professional WordPress Design & Development
Cliff Seal
 
No One Cares About Your Content (Yet): WordCamp Chicago 2013
Cliff Seal
 
No One Cares About Your Content (Yet): WordCamp Miami 2013
Cliff Seal
 
A Brief History of Metal
Cliff Seal
 
No One Cares About Your Content (Yet): WordCamp Phoenix 2013
Cliff Seal
 
WordPress and Pardot: The World’s Newest Power Couple
Cliff Seal
 
No One Cares About Your Content (Yet): Digital Atlanta 2012
Cliff Seal
 
Ad

Speed Things Up with Transients

  • 1. speed things up with transients
  • 4. LOL WUTAPI? is the Transients
  • 5. The Transients API “offers a simple and standardized way of storing cached data in the database temporarily by giving it a custom name and a timeframe after which it will expire and be deleted.”
  • 6. The Transients API ✓ like Options API, but with expiration ✓ uses fast memory (if configured) ✓ uses database otherwise
  • 7. Native Object Cache Plugin Persistent Option N/A (database) Persistent Transient Persistent (varies) (database) Non-persistent Cache Persistent (varies) (memory) Thanks to Rarst.
  • 8. thetransientsAPI Tweets Friends Scrobbles Options API: Username, URL, ID externalAPIs
  • 9. thetransientsAPI Tag Cloud Ratings Custom Queries expensivequeries
  • 11. mainfunctions set_transient( $transient, $value, $expiration ); set_transient
  • 12. mainfunctions $transient ✓ (string) a unique identifier for your cached data ✓ 45 characters or less in length ✓ For site transients, 40 characters or less in length set_transientargs
  • 13. mainfunctions $value ✓ (array|object) Data to save, either a regular variable or an array/object ✓ Handles serialization of complex data for you set_transientargs
  • 14. mainfunctions $expiration ✓ (integer) number of seconds to keep the data before refreshing ✓ Example: 60*60*24 or 86400 (24 hours) set_transientargs
  • 15. mainfunctions MINUTE_IN_SECONDS = 60 (seconds) HOUR_IN_SECONDS = 60 * MINUTE_IN_SECONDS DAY_IN_SECONDS = 24 * HOUR_IN_SECONDS WEEK_IN_SECONDS = 7 * DAY_IN_SECONDS YEAR_IN_SECONDS = 365 * DAY_IN_SECONDS timeconstants
  • 16. mainfunctions get_transient($transient); ✓ If the transient does not exist, or has expired, returns false ✓ An integer value of zero/empty could be the stored data ✓ Should not be used to hold plain boolean values; array or integers instead get_transient
  • 21. cachetagcloud function get_tag_cloud() { if ( false === ( $tag_cloud = get_transient( 'my_tag_cloud' ) ) ) { $tag_cloud = wp_tag_cloud( 'echo=0' ); set_transient( 'my_tag_cloud', $tag_cloud, 60*60*24 ); } else { $tag_cloud = get_transient( 'my_tag_cloud' ); } return $tag_cloud; }
  • 23. cachetagcloud function edit_term_delete_tag_cloud() { delete_transient( 'my_tag_cloud' ); } add_action( 'edit_post', 'edit_term_delete_tag_cloud' );
  • 25. cachemyissues function we_have_issues() { if ( false === ( $issues = get_transient( 'we_have_issues' ) ) ) { $response = wp_remote_get('https://api.github.com/repos/twitter/bootstrap/ issues?assignee'); if ( is_wp_error( $response ) ) { $error_message = $response->get_error_message(); echo "This borked: " . $error_message; } else { $issues = wp_remote_retrieve_body($response); set_transient( 'we_have_issues', $issues, 60*60*24 ); } } else { $issues = get_transient( 'we_have_issues' ); } $issues = json_decode($issues, true); $issuereturn = ''; for ( $i = 0; $i < 5; $i++ ) { $issuereturn .= "<h3><a href='" . $issues[$i]["html_url"] . "'>". $issues[$i]["title"] . "</a></h3>"; } return $issuereturn; }
  • 27. cachemyissues function refresh_my_issues() { delete_transient( 'we_have_issues' ); } if ( is_admin() && isset($_GET['forcedel']) && $_GET['forcedel'] === 'yes' ) { refresh_my_issues(); } function refresh_via_admin_bar() { global $wp_admin_bar; $wp_admin_bar->add_menu( array( 'title' => __('Refresh'), 'href' => admin_url('?forcedel=yes'), 'id' => 'refresh-issues', 'parent' => false ) ); } add_action( 'wp_before_admin_bar_render', 'refresh_via_admin_bar' );
  • 29. cachebigquery function query_for_commenters() { if ( false === ( $commenters = get_transient( 'top_commenters_cached' ) ) ) { global $wpdb; $commenters = $wpdb->get_results(" select count(comment_author) as comments_count, comment_author, comment_type ! ! ! from $wpdb->comments ! ! ! where comment_type != 'pingback' ! ! ! and comment_author != '' ! ! ! and comment_approved = '1' ! ! ! group by comment_author ! ! ! order by comment_author desc ! ! ! LIMIT 10 "); set_transient( 'top_commenters_cached', $commenters, 60*60*24 ); } else { $commenters = get_transient( 'top_commenters_cached' ); } $comment_list = '<ol>'; foreach($commenters as $commenter) { $comment_list .= '<li>'; $comment_list .= $commenter->comment_author; $comment_list .= ' (' . $commenter->comments_count . ')'; $comment_list .= '</li>'; } $comment_list .= '</ol>'; return $comment_list; }
  • 30. cachebigquery function delete_query_for_commenters() { delete_transient( 'top_commenters_cached' ); } add_action( 'comment_post', 'delete_query_for_commenters' );
  • 31. cachebigquery function popular_posts( $num=10 ) { if ( false === ( $popular = get_transient( 'popular_posts' . $num ) ) ) { $query = new WP_Query( array( 'orderby' => 'comment_count', 'posts_per_page' => $num ) ); set_transient( 'popular_posts' . $num, $query, 60*60*24 ); } else { $query = get_transient( 'popular_posts' . $num ); } return $query; }
  • 32. cachebigquery $newquery = popular_posts(3); if ( $newquery->have_posts() ) { while ( $newquery->have_posts() ) { $newquery->the_post(); ?> <h4><?php the_title(); ?></h4> <?php the_excerpt(); ?> <?php } wp_reset_postdata(); }
  • 33. cachebigquery function clear_popular_posts() { for ( $i = 0; $i < 50; $i++ ) { delete_transient( 'popular_posts' . $i ); } } add_action( 'edit_post', 'clear_popular_posts' );
  • 35. cachebigquery Once a transient expires, it remains so until the new result is saved. Heavy traffic can mean too many concurrent MySQL connections. function popular_posts_panic( $num=10 ) { if ( false === ( $popular = get_transient( 'popular_posts' . $num ) ) ) { return ''; } else { $query = get_transient( 'popular_posts' . $num ); } return $query; } Thanks to Andrew Gray for the idea.
  • 36. cachebigquery $newquery = popular_posts_panic(3); if ( $newquery !== '' ) { if ( $newquery->have_posts() ) { while ( $newquery->have_posts() ) { $newquery->the_post(); ?> <h4><?php the_title(); ?></h4> <?php the_excerpt(); ?> <?php } wp_reset_postdata(); } }
  • 37. cachebigquery function renew_popular_posts() { for ( $i = 0; $i < 50; $i++ ) { if ( false === ( $popular = get_transient( 'popular_posts' . $i ) ) ) { delete_transient( 'popular_posts' . $i ); $query = new WP_Query( array( 'orderby' => 'comment_count', 'posts_per_page' => $i ) ); set_transient( 'popular_posts' . $i, $query, 60*60*24*365 ); } } } if ( !wp_next_scheduled( 'renew_popular_posts' ) ) { wp_schedule_event( time(), 'hourly', 'renew_popular_posts' ); }
  • 38. TOP OF HACKER NEWS CONQUERED
  • 41. expiry&garbagecollection ✓ everything works on request ✓ expired != deleted, unless requested ✓ unrequested, undeleted transients stay until you remove them explicitly
  • 42. scalarvalues ✓ accepts scalar values (integer, float, string or boolean) & non-scalar serializable values (arrays, some objects) ✓ SimpleXMLElement will FREAK. OUT., so convert it to a string or array of objects (i.e. simplexml_load_string)
  • 43. infinitetransients ✓ transients set without an expiration time are autoloaded ✓ if you don’t need it on every page, set an expiration (even if it’s a year) ✓ consider the Options API for non- transient data
  • 44. cachinggotchas ✓ in some shared hosting environments, object caching can be slower than using the database; check your host’s recommended settings ✓ always use the Transients API to access transients; don’t assume they’re in the database (or vice versa)
  • 46. usefultools TLC Transients Artiss Transient Cleaner Debug Bar Transients Supports soft- Deletes expired Adds panel to Debug expiration, transients and optimizes Bar with transient info background updating table