Performance Optimizations
Performance Optimizations
Event sites with hundreds of events and thousands of attendees can strain database performance. Tickets Please uses three strategies to keep page loads fast: transient caching for expensive queries, meta prefetching to eliminate N+1 queries, and deferred term counting during bulk operations.
Transient Caching
Tickets Please caches the results of expensive database queries using WordPress transients. Transients are stored in the wp_options table (or in an object cache like Redis/Memcached if configured).
Cached Queries
| Transient Key | TTL | Contents |
|---|---|---|
tec_events_list_{hash} | 1 hour | Event list query results. The hash is generated from the query parameters (date range, category, page number, etc.). |
tec_event_capacity_{id} | 15 minutes | Capacity data for a single ticket, including total capacity, sold count, and remaining. |
tec_month_view_{YYYY-MM} | 1 hour | Pre-rendered month view HTML for a specific year and month. |
How Cache Invalidation Works
Transients are automatically invalidated when their underlying data changes:
- Event list caches are flushed when any event is created, updated, deleted, or changes status.
- Capacity caches are flushed when a ticket is purchased, an attendee is cancelled, or capacity is manually edited.
- Month view caches are flushed when any event within that month is modified.
You do not need to manually clear caches after content changes. The plugin handles invalidation internally.
Clearing All Caches
If you need to force a full cache clear (e.g., after a database migration or debugging):
// Delete all Tickets Please transients.global $wpdb;$wpdb->query( "DELETE FROM {$wpdb->options} WHERE option_name LIKE '_transient_tec_%' OR option_name LIKE '_transient_timeout_tec_%'");Or use WP-CLI:
wp transient delete --allNote that wp transient delete --all removes all transients on the site, not just Tickets Please transients.
Object Cache Compatibility
When a persistent object cache (Redis, Memcached) is active, WordPress stores transients in the object cache instead of the database. This is faster and recommended for high-traffic event sites. Tickets Please transients work with any object cache plugin that implements the WordPress object cache API.
Meta Prefetching
WordPress stores post meta in a separate table. Without optimization, loading 10 events on an archive page would execute 10+ individual get_post_meta() queries — one per event, per meta key. This is the “N+1 query problem.”
Tickets Please calls update_post_meta_cache() on event batches during archive queries. This single query loads all meta for all events in the current page into WordPress’s internal cache. Subsequent get_post_meta() calls for those events read from memory, not the database.
When Prefetching Runs
- Event archive pages — Meta is prefetched for all events in the main query.
- Month view — Meta is prefetched for all events in the displayed month.
- Related events — Meta is prefetched for the related events batch.
- REST API list endpoints — Meta is prefetched for all events in the response.
Prefetching adds one extra query per page load but eliminates 10-50+ individual meta queries depending on the number of events displayed.
Monitoring Meta Queries
Use the Query Monitor plugin to verify that meta prefetching is working. On an event archive page, you should see a single SELECT ... FROM wp_postmeta WHERE post_id IN (...) query for all displayed events, rather than individual queries per event.
Deferred Term Counting
WordPress updates term counts (how many posts are in each category/tag) every time a post’s terms change. During bulk operations — CSV imports with hundreds of events, bulk status changes, bulk deletions — this creates hundreds of unnecessary COUNT queries.
Tickets Please defers term counting during bulk operations:
- Before the bulk operation starts,
wp_defer_term_counting( true )is called. - The bulk operation processes all records without triggering individual term count updates.
- After the operation completes,
wp_defer_term_counting( false )is called, which triggers a single term count recalculation for all affected terms.
This turns N individual COUNT queries into one batch recalculation.
When Deferral Is Active
- CSV import — Term counting is deferred for the entire import batch.
- Bulk status changes — When changing the status of multiple events at once from the list table.
- Bulk deletion — When deleting multiple events.
Normal single-event operations (creating one event, editing one event) do not defer term counting. The overhead is negligible for individual operations.
Performance Recommendations
Beyond the built-in optimizations, follow these practices for the best performance on high-traffic event sites:
- Install a persistent object cache. Redis or Memcached dramatically speeds up transient reads and WordPress core’s internal caches.
- Use a page cache. Plugins like WP Super Cache or W3 Total Cache serve static HTML to anonymous visitors, bypassing PHP and the database entirely.
- Limit events per page. Displaying 50 events per page loads 50x the meta data of displaying 10. Keep the events per page setting reasonable for your content.
- Optimize images. Event featured images are often the largest assets on the page. Use appropriate dimensions and compression.
- Monitor with Query Monitor. Periodically check that query counts stay reasonable on key pages.
Common Questions
Do I need to configure caching manually? No. Transient caching and meta prefetching are active by default. The only optimization you should add yourself is a persistent object cache plugin.
Will a page cache serve stale event data? Page caches serve static HTML. If an event is updated, the cached page shows old data until the cache expires or is purged. Configure your page cache plugin’s TTL to balance freshness and performance. Most page cache plugins integrate with WordPress to purge cached pages when posts are updated.
Does the capacity cache cause overselling? The capacity cache has a 15-minute TTL and is invalidated immediately on any purchase or cancellation. In practice, the cache is almost never stale during active ticket sales because each sale triggers invalidation.
How much database load do these optimizations save? On a site with 200 events and 20 events per page, meta prefetching alone reduces meta queries from approximately 60 per page load to 1. Transient caching eliminates the main event query entirely on cached page loads. The combined effect is typically a 50-80% reduction in database queries on event pages.
Can I disable transient caching for debugging?
Define WP_DEBUG as true in wp-config.php. Tickets Please still uses transients, but you can delete them manually or use Query Monitor to inspect query behavior. There is no dedicated setting to disable Tickets Please caching.
Does caching work with multisite? Yes. Transients are site-specific in a WordPress multisite installation. Each site in the network has its own set of Tickets Please transients.
Next Steps
- General Settings — Configure events per page to control query size.
- Geocoding — Geocoding results are cached in venue meta to avoid repeated API calls.
- REST API Reference — API responses benefit from the same caching layer.