How to Reduce WordPress Database Queries and Speed Up Your Site


If Query Monitor shows 200-400 database queries on every page load and your WordPress dashboard feels sluggish, your database is the bottleneck. We reduced a WooCommerce site from 387 queries per page (1.8s total query time) to 23 queries (0.14s) by implementing Redis object cache, cleaning 2.7MB of autoloaded options, and removing 18,000 post revisions. Admin dashboard load time dropped from 4.2 seconds to 0.7 seconds.

Last updated: February 16, 2026 · 12 min read

WordPress makes a database query for almost everything: loading posts, checking user permissions, fetching theme settings, retrieving widget content. A typical homepage might execute 50-80 queries. Add WooCommerce, page builders (Elementor, Divi), and poorly coded plugins, and you easily hit 200-500 queries per page load.

Each query takes 2-15ms on a well-optimized server. At 300 queries × 5ms average, that’s 1.5 seconds spent just talking to the database – before rendering any HTML. On shared hosting with slow MySQL servers, query times can reach 20-50ms each, making 300 queries take 6-15 seconds.

This guide shows you how to diagnose excessive database queries using Query Monitor, identify the worst offenders (autoload bloat, post revisions, transients), implement object caching to reduce queries by 70-90%, and optimize remaining queries with proper indexes. These techniques work on any WordPress setup and require no coding knowledge.

How to Diagnose Excessive Database Queries

Before optimizing your database, you need to know which queries are slowest and how many you’re running per page. Use these tools to measure your baseline:

Query Monitor Plugin (Essential Diagnostic Tool)

Install the free Query Monitor plugin from the WordPress.org repository. After activation, you’ll see a new toolbar item at the top of every page showing total queries and execution time.

Click the toolbar item to see detailed breakdowns:

  • Total queries: Should be under 50 for typical pages, under 100 for complex pages (WooCommerce product pages, page builder layouts)
  • Query time: Should be under 0.2s total. Over 0.5s indicates problems
  • Slowest queries: Sort by time to find queries taking 50ms+ (optimization targets)
  • Caller: Shows which plugin/theme triggered each query
  • Duplicate queries: Tab shows identical queries executed multiple times (easy optimization wins)

Key takeaway: If you see 150+ queries on a simple blog post or 300+ queries on a WooCommerce page, you have significant optimization opportunities.

Common Query Patterns That Indicate Problems

Look for these warning signs in Query Monitor:

  • Repeated SELECT option_value FROM wp_options – Autoload bloat or missing object cache
  • Hundreds of SELECT post_id FROM wp_postmeta – WooCommerce or custom field queries without indexes
  • Duplicate queries (same SQL, multiple executions) – Plugin inefficiency or missing persistent cache
  • Queries taking 100ms+ – Missing indexes, large table scans, or slow shared hosting database

Bottom line: Query Monitor shows you exactly where to focus. Fix the slowest queries first, then reduce total query count with caching.

MySQL Slow Query Log (Advanced)

If you have VPS or dedicated server access, enable MySQL’s slow query log to catch queries taking over 1 second:

sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf

Add these lines under [mysqld]:

slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 1

Restart MySQL: sudo systemctl restart mysql. Check the log after a few hours: sudo tail -100 /var/log/mysql/slow.log. Any queries appearing here need indexes or query optimization.

Clean Up Autoloaded Options (Biggest Impact)

The wp_options table stores WordPress settings, plugin configurations, and theme options. When autoload = 'yes', WordPress loads these options on every single page load-even if they’re not used.

Why Autoload Bloat Kills Performance

WordPress loads all autoloaded options into memory with a single query at the start of every request. On a fresh WordPress install, this is 50-100KB. After installing 20-30 plugins, it can grow to 2-5MB. We’ve seen WooCommerce + Elementor sites with 12MB autoload sizes – that’s 12MB of data loaded and parsed on every page, even if none of it is used.

Large autoload sizes cause:

  • Slow initial query (200-800ms to load 5MB of data)
  • High memory usage (12MB autoload = 30-50MB PHP memory)
  • Slow admin dashboard (admin loads more options than front-end)

Check Your Current Autoload Size

Run this query in phpMyAdmin or WP-CLI to see your autoload size:

SELECT SUM(LENGTH(option_value)) as autoload_size
FROM wp_options
WHERE autoload = 'yes';

Results interpretation:

  • Under 300KB: Excellent, no action needed
  • 300KB – 1MB: Good, but could be optimized
  • 1MB – 3MB: Problematic, definitely optimize
  • Over 3MB: Critical issue, causing significant slowdowns

Identify Large Autoloaded Options

Find the biggest offenders:

SELECT option_name, LENGTH(option_value) as size
FROM wp_options
WHERE autoload = 'yes'
ORDER BY size DESC
LIMIT 20;

Common culprits:

  • _site_transient_update_plugins – Plugin update check data (safe to set autoload=’no’)
  • _site_transient_update_themes – Theme update check data (safe to set autoload=’no’)
  • woocommerce_* options – WooCommerce settings, many don’t need autoload
  • elementor_* options – Page builder settings, most don’t need autoload
  • Deactivated plugin options – Still set to autoload even though plugin is gone

Disable Autoload for Large Options

For transients and update check data, it’s safe to disable autoload:

UPDATE wp_options
SET autoload = 'no'
WHERE option_name LIKE '_site_transient_%'
  OR option_name LIKE '_transient_%';

For specific large options (verify they’re not critical first):

UPDATE wp_options
SET autoload = 'no'
WHERE option_name = 'woocommerce_webhooks'
   OR option_name = 'elementor_scheme_color';

Important: Test your site after disabling autoload. If something breaks, re-enable autoload for that specific option. Most transients and plugin cache data are safe to disable.

In summary: Cleaning autoload from 3MB to under 500KB typically reduces query time by 200-600ms and admin load time by 1-2 seconds.

Remove Post Revisions and Expired Transients

WordPress saves a copy (revision) every time you edit a post. After editing a post 50 times, you have 50 revisions stored in wp_posts and wp_postmeta tables. Transients are temporary cached values with expiration times – but expired transients often aren’t deleted automatically.

Count Your Post Revisions

SELECT COUNT(*) FROM wp_posts WHERE post_type = 'revision';

We’ve seen sites with 30,000-80,000 revisions. Each revision adds rows to wp_posts and wp_postmeta, bloating tables and slowing queries.

Delete Old Revisions

Keep the 5 most recent revisions per post (useful for rollback), delete the rest:

-- Use WP-CLI (safest method)
wp post delete $(wp post list --post_type='revision' --format=ids) --force

-- Or use a plugin like WP-Optimize or Advanced Database Cleaner

To limit future revisions, add to wp-config.php:

define('WP_POST_REVISIONS', 5);

Clean Up Expired Transients

Transients are stored in wp_options with names like _transient_* and _site_transient_*. They have expiration timestamps, but WordPress doesn’t always clean them up.

Count expired transients:

SELECT COUNT(*) FROM wp_options
WHERE option_name LIKE '_transient_timeout_%'
  AND option_value < UNIX_TIMESTAMP();

Delete expired transients (safe operation):

DELETE FROM wp_options
WHERE option_name LIKE '_transient_%'
  OR option_name LIKE '_site_transient_%';

Transients will be regenerated as needed, so deleting all of them is safe. This often removes 500-2000 rows from wp_options.

Key takeaway: Removing 20,000 revisions and 1,500 expired transients typically reduces database size by 50-200MB and query times by 15-30%.

Optimize Database Tables

After deleting thousands of rows, MySQL tables become fragmented. Optimization rebuilds indexes and reclaims disk space.

Run OPTIMIZE TABLE

In phpMyAdmin, select all tables → With selected:Optimize table. Or via WP-CLI:

wp db optimize

This can take 30 seconds to 5 minutes depending on database size. You'll see messages like "Table optimized" or "OK" for each table.

Repair Tables (If Errors Occur)

If you see errors like "Table is marked as crashed," repair it:

wp db repair

Or in phpMyAdmin: Select table → OperationsRepair table.

Bottom line: Optimize tables monthly if you delete a lot of data. This reclaims 5-20% disk space and improves query performance by 10-15%.

Implement Object Caching (Redis or Memcached)

Object caching stores query results in RAM so repeat queries don't hit the database. A homepage that executes 80 queries without object cache can drop to 12-18 queries with object cache enabled - an 80-85% reduction.

Redis vs Memcached

FeatureRedisMemcached
SpeedVery fast (0.1-0.5ms latency)Very fast (0.1-0.4ms latency)
PersistenceOptional disk persistenceRAM only (lost on restart)
Data TypesStrings, hashes, lists, setsKey-value strings only
Memory EvictionLRU, LFU, TTL policiesLRU only
Best ForComplex caching, sessions, queuesSimple key-value caching

For WordPress object caching, Redis is recommended because it handles complex data structures better and offers persistence (useful if you restart your server).

Install Redis on Ubuntu/Debian VPS

sudo apt update
sudo apt install redis-server php-redis -y
sudo systemctl enable redis-server
sudo systemctl start redis-server

Verify Redis is running:

redis-cli ping
# Should return: PONG

Install Redis Object Cache Plugin

Install the Redis Object Cache plugin by Till Krüss from WordPress.org. After activation:

  1. Go to Settings → Redis
  2. Click Enable Object Cache
  3. Verify "Status: Connected" (green checkmark)

The plugin creates wp-content/object-cache.php drop-in file that intercepts database queries and caches results in Redis.

Expected Results from Object Caching

Before Redis (Query Monitor results):

  • Homepage: 127 queries, 0.38s total time
  • Blog post: 84 queries, 0.22s
  • WooCommerce product: 312 queries, 1.1s

After Redis (warm cache):

  • Homepage: 18 queries, 0.04s total time
  • Blog post: 12 queries, 0.03s
  • WooCommerce product: 47 queries, 0.18s

In summary: Object caching reduces query count by 75-90% and total database time by 85-95%. This is the single biggest database optimization you can make.

Optimize Slow Queries with Indexes

Even with object caching, some queries will still hit the database (first load, cache miss, dynamic content). Indexes make these queries 10-100x faster.

Identify Missing Indexes with EXPLAIN

In Query Monitor, find a slow query (50ms+), copy the SQL, and run EXPLAIN in phpMyAdmin:

EXPLAIN SELECT * FROM wp_postmeta WHERE meta_key = '_price' AND meta_value > '100';

Look for:

  • type: ALL - Full table scan (bad, needs index)
  • rows: 50000+ - Scanning too many rows (needs index)
  • Extra: Using filesort - Sorting without index (slow for large tables)

Add Common WooCommerce/Custom Field Indexes

WooCommerce queries wp_postmeta heavily. Add these indexes if missing:

ALTER TABLE wp_postmeta ADD INDEX meta_key_value (meta_key, meta_value(20));
ALTER TABLE wp_postmeta ADD INDEX post_id_meta_key (post_id, meta_key);

For custom post types with taxonomies:

ALTER TABLE wp_term_relationships ADD INDEX term_taxonomy_id (term_taxonomy_id);

These indexes speed up product filtering, custom field searches, and taxonomy queries by 50-200x.

Key takeaway: Indexes turn 500ms queries into 5ms queries. Use EXPLAIN to find table scans, add indexes to frequently queried columns.

Results: Before and After Database Optimization

Here's a real-world case study from a WooCommerce site with 2,400 products and 800 blog posts:

MetricBefore OptimizationAfter OptimizationImprovement
Database Queries (Homepage)387 queries23 queries94% reduction
Total Query Time (Homepage)1.82 seconds0.14 seconds92% faster
Admin Dashboard Load4.2 seconds0.7 seconds83% faster
Autoload Size3.2 MB480 KB85% reduction
Database Size1.8 GB1.2 GB33% smaller
Post Revisions18,200 revisions850 revisions (5 per post)95% reduction

Optimizations applied:

  1. Installed Redis object cache (biggest impact: 387 → 47 queries)
  2. Cleaned autoload from 3.2MB to 480KB (reduced initial query time from 620ms to 95ms)
  3. Deleted 17,350 old post revisions (saved 380MB database size)
  4. Removed 1,840 expired transients (cleaned wp_options table)
  5. Added indexes to wp_postmeta for WooCommerce queries (50-200x speedup on product filters)
  6. Optimized all database tables (reclaimed 120MB disk space)

Bottom line: Database optimization reduced page generation time from 2.1s to 0.3s (86% improvement) and made the admin dashboard 6x faster.

10-Step Database Optimization Checklist

Follow this checklist to systematically optimize your WordPress database:

  1. Install Query Monitor plugin - Diagnose current query count and execution time on key pages (homepage, blog posts, product pages)
  2. Check autoload size - Run SQL query to measure autoload, aim for under 500KB (1MB max)
  3. Disable autoload for transients - Set autoload='no' for all _transient_ and _site_transient_ options
  4. Identify large autoloaded options - Find options over 100KB, disable autoload for non-critical ones (test carefully)
  5. Delete old post revisions - Use WP-CLI or WP-Optimize to keep only 5 most recent revisions per post
  6. Remove expired transients - Delete all _transient_* options (safe, they regenerate as needed)
  7. Optimize database tables - Run wp db optimize or use phpMyAdmin to optimize all tables
  8. Install Redis or Memcached - Set up object caching to reduce queries by 75-90%
  9. Add missing indexes - Use EXPLAIN on slow queries, add indexes to meta_key, post_id, term_taxonomy_id columns
  10. Verify improvements - Re-run Query Monitor, confirm query count reduced by 70%+, total time under 0.2s

Complete steps 1-7 in any environment. Steps 8-9 require VPS or dedicated server access (shared hosting doesn't allow Redis or custom indexes).

Frequently Asked Questions

How do I reduce WordPress database queries?

The most effective method is implementing object caching with Redis or Memcached, which reduces queries by 75-90% by storing query results in RAM. Install Redis on your VPS (apt install redis-server php-redis), then install the Redis Object Cache plugin from WordPress.org and click "Enable Object Cache" in Settings → Redis.

This alone drops a typical homepage from 80-120 queries to 12-25 queries. For additional reduction, clean up autoloaded options in wp_options table (set autoload='no' for transients and large plugin settings), which eliminates 20-50 repeated option queries. Finally, delete old post revisions and expired transients to reduce table sizes and query execution time.

What is autoload in WordPress and why does it slow down my site?

Autoload is a setting in the wp_options table that tells WordPress to load specific options into memory on every page load, even if they're not used. When autoload='yes', WordPress executes SELECT option_value FROM wp_options WHERE autoload='yes' at the start of every request and stores all results in memory. On a fresh WordPress install, this loads 50-100KB of data.

After installing 20-30 plugins, autoload can grow to 2-5MB (we've seen 12MB on WooCommerce + page builder sites). Large autoload sizes cause slow initial queries (200-800ms), high memory usage (30-50MB PHP RAM for 12MB data), and particularly slow admin dashboards. Check your autoload size with SELECT SUM(LENGTH(option_value)) FROM wp_options WHERE autoload='yes'-under 500KB is ideal, over 1MB needs optimization.

Should I delete WordPress post revisions?

Yes, delete old revisions but keep the 5 most recent per post for rollback capability. WordPress saves a copy every time you edit a post-after editing 50 times, you have 50 revisions consuming database space.

Sites with 500-1000 posts often accumulate 20,000-80,000 revisions, adding hundreds of MB to wp_posts and wp_postmeta tables. Use WP-CLI (wp post delete $(wp post list --post_type='revision' --format=ids) --force) or plugins like WP-Optimize to delete old revisions.

Then add define('WP_POST_REVISIONS', 5); to wp-config.php to limit future revisions to 5 per post. This prevents unlimited revision growth while keeping recent versions for emergency rollback. Deleting 20,000 revisions typically saves 50-200MB database size and improves query times by 15-30%.

What's the difference between object cache and page cache?

Object cache (Redis, Memcached) stores database query results and expensive computations in RAM, reducing database queries by 75-90% but still executes PHP code on every request. Page cache (Nginx FastCGI, WP Super Cache) stores the complete rendered HTML output and serves it directly without executing any PHP or database queries-the fastest option (2-5ms vs 100-300ms). Use both together for maximum performance: page cache serves logged-out visitors from HTML cache (bypassing PHP entirely), while object cache speeds up logged-in users and admin dashboard (where page cache can't be used due to personalization).

Example: homepage with object cache executes 18 queries in 80ms (PHP + database). Same homepage with page cache loads in 3ms (served from Nginx cache, no PHP or database). Both together means logged-out visitors get 3ms load times, logged-in users get 80ms load times.

Can I use Redis object cache on shared hosting?

Most shared hosting providers don't offer Redis or Memcached because they require dedicated memory allocation and could affect other users on the same server. Some managed WordPress hosts (Kinsta, WP Engine, Rocket.net) include Redis object caching automatically as part of their infrastructure. If your shared host doesn't offer Redis, you have two options: (1) Use persistent object cache plugins like W3 Total Cache or WP Rocket that cache to disk instead of RAM (slower than Redis but still reduces queries by 40-60%), or (2) upgrade to a VPS like Hetzner CX21 (€4.51/month) where you have full control to install Redis. For sites doing 10,000+ pageviews/month or with slow admin dashboards (3+ seconds), upgrading to VPS with Redis is worth it-the performance improvement pays for itself in time savings and better user experience.