What if you could get a performance code review from someone who's seen WordPress sites fail under load and remembers all the patterns that caused it?
That's what this Claude Code skill does. It knows 50+ anti-patterns that cause WordPress performance problems, and it flags them with severity levels, line numbers, and explanations of what actually happens when they run in production.
I built it because I kept seeing the same issues over and over. A site works fine in development, handles QA traffic without problems, then gets on the news and falls over within an hour. The code wasn't "wrong", it just had patterns that don't survive real traffic. Unbounded database queries. Cache bypass. N+1 problems. Accidental self-DDoS from polling. These things are invisible until they're not.
TL;DR: This Claude Code skill performs AI-powered WordPress code review that catches performance anti-patterns static analysis can't see. It understands context across files, knows platform-specific fixes for WordPress VIP, WP Engine, and shared hosting, and explains why patterns fail under load - not just that they violate a rule.
What WordPress Performance Issues It Catches
The obvious stuff is here, posts_per_page => -1, query_posts(), session_start() on the frontend. If you've worked on WordPress at any scale, you know these. But the skill also catches the patterns that look fine until they aren't:
Database writes on page loads. This one looks harmless:
add_action( 'wp_head', function() {
update_option( 'page_views', get_option( 'page_views', 0 ) + 1 );
} );
It's just incrementing a counter, right? But update_option is an INSERT or UPDATE query. Every visitor triggers a database write. At 1,000 visitors per hour, that's 1,000 write queries competing for row locks on wp_options. Your database CPU spikes, other queries queue up, page loads slow down, and eventually things start timing out.
Dynamic transient keys. This pattern creates rows in wp_options for every user:
set_transient( "user_{$user_id}_cart", $cart_data, HOUR_IN_SECONDS );
Syntactically fine. Functionally fine for a few hundred users. At 10,000 users, you have 20,000 rows in wp_options - WordPress stores the value and the timeout in separate rows. I've seen this pattern bloat wp_options to 40GB. The fix is to use wp_cache_set() instead, which uses object cache and doesn't touch the database.
Polling patterns. Someone adds a "live updates" feature:
setInterval(() => fetch('/wp-json/myapp/v1/updates'), 5000);
Every browser tab polls your server every 5 seconds. With 100 concurrent users, that's 100 requests every 5 seconds - 20 per second hitting your origin. These requests can't be cached because they're checking for "new" data. You've accidentally DDoS'd yourself.
Cron jobs that never stop multiplying. This is subtle:
register_activation_hook( __FILE__, function() {
wp_schedule_event( time(), 'hourly', 'my_plugin_sync' );
} );
Every time the plugin is activated, it schedules a new cron job. Deactivate and reactivate a few times during debugging, and you've got 5 instances of my_plugin_sync running every hour. The fix is checking wp_next_scheduled() first - but if you don't know to look for it, you won't.
Output summary from reviewing a WooCommerce site with custom plugins
How a Claude Code Skill Compares to Static Analysis Tools
I still run PHPCS with WordPress Coding Standards in my workflow - it's integrated with VS Code via this PHP Sniffer extension and catches real issues on every save. Tools like PHPStan and Psalm in some projects also add type checking and can catch bugs before runtime.
But static analysis has limits. It can tell you "this line violates rule X" but not "this pattern across your codebase will cause problems under specific conditions."
When to use static analysis:
- Enforcing coding standards on every save
- Type checking and catching null reference errors
- CI/CD pipeline checks for syntax and style
- Catching obvious mistakes before code review
When to use AI-powered code reviews:
- Finding performance issues that span multiple files
- Understanding WordPress-specific runtime behavior
- Getting context-aware recommendations for your hosting platform
- Catching patterns that are syntactically valid but semantically problematic
The best approach (if they're already part of your workflow): Use both. Run PHPCS and PHPStan in your IDE and CI pipeline. Then use this Claude Code skill for deeper WordPress performance analysis before major releases or when debugging production issues.
Here's an example of something static analysis can't catch. This code silently turns into an unbounded query when it fails:
$post_id = get_post_id_from_external_api(); // Returns false on timeout or 404
$query = new WP_Query( array( 'p' => intval( $post_id ) ) );
When get_post_id_from_external_api() returns false, intval(false) is 0. And in WP_Query, 'p' => 0 doesn't mean "get post with ID 0" - it means "don't filter by post ID." If there's no posts_per_page set, you've just queried every post in the database.
Static analysis can't catch this. It sees a valid function call with a valid argument type. It doesn't know that $post_id might be falsy, and it doesn't know the WordPress-specific behavior of 'p' => 0. The skill can reason about this and flag it: "You're passing a potentially falsy value through intval() into a post ID argument - validate before querying."
Another example: session_start() in a single plugin makes your entire site uncacheable. Page caching serves identical HTML to everyone. PHP sessions create per-visitor state - incompatible by design. One line in one plugin you installed last year can be the reason your page cache hit rate is 0% and you're wondering why Cloudflare isn't helping.
Static analysis sees session_start() and might flag it generically. But it doesn't understand the site-wide caching implications. The skill explains: "This bypasses all page caching. Every request hits PHP. Check if this plugin actually needs sessions on the frontend, or if it can be limited to logged-in users."
Finding N+1 Database Queries Across Files
This one is hard to spot in manual code review and very challenging for file-by-file static analysis to catch:
// In archive.php
while ( have_posts() ) {
the_post();
$author = get_extended_author_data( get_the_author_meta( 'ID' ) );
// render post...
}
// In functions.php
function get_extended_author_data( $user_id ) {
$user = get_user_by( 'id', $user_id ); // Database query
$meta = get_user_meta( $user_id ); // Another query if not primed
return array( 'user' => $user, 'meta' => $meta );
}
The loop runs 10 times. Each iteration calls get_extended_author_data(), which runs 2 queries. That's 20 database queries where there should be 2 - one to get all the users, one to get all the meta.
When you're looking at archive.php, you see a function call. When you're looking at functions.php, you see a function that does a couple of queries. Neither file is "wrong" in isolation. The problem is the interaction between them.
One fix could be to prime the caches before the loop - and the skill can suggest the best approach for your specific case depending on the context it learns from your codebase as a whole:
// Prime author cache before the loop
$author_ids = wp_list_pluck( $wp_query->posts, 'post_author' );
cache_users( $author_ids ); // Single query loads all authors
while ( have_posts() ) {
the_post();
$author = get_extended_author_data( get_the_author_meta( 'ID' ) );
// Now uses cached data - no additional queries
}
The skill sees across files. It understands that calling a function with database queries inside a WordPress loop is a red flag pattern, regardless of where that function is defined.
WooCommerce Performance Anti-Patterns
WooCommerce sites face unique WordPress performance challenges. The skill catches several WooCommerce-specific issues that can tank your store's performance:
Cart fragment AJAX overhead. In older WooCommerce versions (pre-7.8), the cart fragments script ran on every page load - even pages with no cart widget. While WooCommerce 7.8+ improved this behavior, many stores still have legacy code or third-party plugins that explicitly enqueue the script:
// Legacy pattern that can still cause unnecessary AJAX on every page
wp_enqueue_script( 'wc-cart-fragments' );
The skill flags when cart fragments are being loaded unnecessarily and suggests limiting them to pages that actually display cart data, or reviewing whether your theme/plugins truly need real-time cart updates on every page.
Order queries without limits. This pattern appears in admin dashboards and reports:
$orders = wc_get_orders( array(
'status' => 'completed',
'date_created' => '>' . strtotime( '-30 days' ),
) );
Looks reasonable - get last 30 days of orders. But stores with high volume can have 10,000+ orders in 30 days. Without a 'limit' parameter, you're loading them all into memory. The skill recommends adding pagination or using 'limit' => 100 with proper iteration.
Product query loops in templates. Custom product displays often trigger extra queries:
// In a custom template
$related = wc_get_related_products( $product_id, 4 );
foreach ( $related as $related_id ) {
$related_product = wc_get_product( $related_id ); // Query per product
// display...
}
The skill suggests using wc_get_products() with the IDs to batch-load products in a single query.
Platform-Specific WordPress Performance Advice
The right fix for your identified issues can also depend on where your production code runs. The Claude Code skill adapts and suggests its recommendations based on your hosting environment - if it's able to identify it from what it learns from your codebase. It can also suggest how different alternative approaches exist in WordPress-specific hosting platforms.
On WordPress VIP, there are platform-specific functions that handle caching for you. Instead of url_to_postid() - which does an expensive lookup on every call - you use wpcom_vip_url_to_postid(), which caches the result. For external HTTP calls, vip_safe_wp_remote_get() adds circuit-breaker logic that fails gracefully after repeated timeouts. The skill knows these alternatives exist and recommends them when it identifies VIP-specific patterns in your code.
On managed hosts like WP Engine or Pantheon, you usually have Redis or Memcached available. Transients use the object cache instead of the database, so the dynamic transient key problem I mentioned earlier is less severe (though still not ideal). Query Monitor is typically available for profiling slow queries.
On shared hosting, there's often no persistent object cache at all. Transients fall back to wp_options. That 20,000-row bloat is very real. You also can't rely on server-level cron, so DISABLE_WP_CRON may not be an option. The skill can flag these patterns more aggressively when it identifies, or you mention in your prompts, that you're not on a platform with object cache.
Real Results from WordPress Code Reviews
To give you a sense of what the skill finds in practice:
On a 50-file custom theme: The skill identified 12 performance issues in about 30 seconds. The most critical was an N+1 query pattern in the archive template that was causing 47 database queries per page load instead of 5. After fixing, page generation time dropped from 800ms to 180ms.
On a commercial Pro WooCommerce plugin: Found 4 issues including an unbounded order query in a reporting function and a missing nonce check (security, not performance, but still caught it). The order query was loading 15,000 orders into memory on a client with high volume.
On a migration from shared hosting to WP Engine: The skill identified 6 patterns that would work differently with Redis object cache enabled, including transient usage that was previously falling back to database but would now persist correctly.
The skill won't catch everything - it's not running your code or profiling actual queries. But it catches patterns that experienced WordPress developers learn to avoid after seeing them cause problems in production.
How to Install and Use the WordPress Performance Skill
Installation
First, add the marketplace to Claude Code:
/plugin marketplace add elvismdev/claude-wordpress-skills
Then install the plugin:
/plugin install claude-wordpress-skills
Important: After installation, exit Claude Code completely and relaunch it. The skill won't load until you restart:
# Exit Claude Code (Ctrl+C or type 'exit')
# Then relaunch from your project directory
claude
To verify the skill is loaded, you can check your installed plugins:
/plugin
You should see claude-wordpress-skills listed as installed and enabled.
Usage
Once installed, ask Claude Code to review your code:
- "Review this plugin for performance issues"
- "Check theme/functions.php before we launch"
- "Audit this PR for WordPress anti-patterns"
- "Look for N+1 queries in this WooCommerce extension"
The skill activates automatically when you're reviewing WordPress PHP code or mention performance-related terms like "slow," "timeout," or "performance review."
Troubleshooting
Skill not activating? Make sure you restarted Claude Code after installation. Check that the plugin shows as "enabled" in /plugin output.
Getting too many warnings? The skill errs on the side of caution. You can ask it to focus on critical issues only: "Show me only high-severity performance issues."
Need platform-specific advice? Tell Claude Code your hosting environment: "We're on WP Engine with Redis" and it will adjust recommendations.
Get It on GitHub
GitHub: https://github.com/elvismdev/claude-wordpress-skills
If you find patterns it misses, false positives it flags, or anti-patterns you've seen in the wild that aren't covered - open an issue or PR. A great goal would be to capture the stuff that experienced WordPress developers know to look for and make it available to everyone doing WordPress code review.
Contributing
The skill is defined in markdown files that Claude Code reads to understand WordPress performance patterns. To add a new anti-pattern:
- Fork the repository
- Add the pattern to the relevant category file
- Include: pattern description, code example, severity level, fix recommendation
- Submit a PR with before/after examples
Some Example Questions That Come to Mind
How do I check WordPress plugin performance?
Install the Claude Code WordPress performance skill, navigate to your plugin directory, and ask Claude to "review this plugin for performance issues." It will analyze your PHP files for 50+ anti-patterns including database query issues, caching problems, and code patterns that don't scale. For runtime profiling, combine with Query Monitor to see actual query counts and execution times.
What causes slow WordPress database queries?
The most common causes are: unbounded queries (posts_per_page => -1), N+1 query patterns where loops trigger individual queries instead of batch fetching, missing indexes on custom tables, meta_query without proper indexes, and autoloaded options in wp_options that load on every page. The skill catches all of these patterns and explains the specific fix for each.
How to find N+1 queries in WordPress?
N+1 queries happen when a loop triggers a database query on each iteration. Look for function calls inside while ( have_posts() ) or foreach loops that call get_post_meta(), get_user_by(), get_the_terms(), or similar functions. The Claude Code skill specifically identifies these patterns even when the querying function is defined in a different file than the loop.
What performance issue burned you the worst? I'm especially curious about patterns specific to WooCommerce or multisite - might end up in the next version.


Top comments (0)