MakeWPFast https://makewpfast.com Make WordPress Fast Again Mon, 16 Mar 2026 09:00:00 +0000 en-US hourly 1 Emergency WordPress Recovery: What to Do When Your Site Goes Down https://makewpfast.com/emergency-wordpress-recovery-what-to-do-when-your-site-goes-down/ Mon, 16 Mar 2026 09:00:00 +0000 https://makewpfast.com/?p=5823 Read more]]> Your site is down. Visitors see an error page. Revenue is dropping by the minute. Panic sets in. Here is your emergency action plan — a calm, systematic approach to getting your WordPress site back online as fast as possible.

Step 1: Confirm the Outage (30 seconds)

Before doing anything, verify the site is actually down and it is not just your connection:

  • Try from a different device or network (mobile data)
  • Use an external uptime checker like downfor.io or isitdown.site
  • Check if it is the entire site or just wp-admin

Step 2: Identify the Error (2 minutes)

The error message tells you where to look:

  • White screen → PHP fatal error (check error logs)
  • 500 Internal Server Error → Server-side issue (check error logs, .htaccess)
  • 502/504 Gateway Timeout → PHP-FPM crashed or overloaded
  • Database connection error → MySQL is down or credentials are wrong
  • “Briefly unavailable for maintenance” → Stuck update (delete .maintenance file)
  • 403 Forbidden → Permission issue or security plugin lockout
  • DNS or SSL error → Domain/hosting configuration issue

Step 3: Apply the Targeted Fix

PHP Fatal Error / White Screen

  1. Check wp-content/debug.log or server error log
  2. Rename the offending plugin/theme folder via FTP/SSH
  3. If you cannot identify the cause, rename the entire plugins folder

Database Connection Error

  1. Verify MySQL is running: systemctl status mysql
  2. Check wp-config.php credentials match your database
  3. Check if the database disk is full: df -h

Stuck Maintenance Mode

Delete the .maintenance file in your WordPress root directory. That is it.

Security Plugin Lockout

If a security plugin (Wordfence, Sucuri, iThemes) locked you out, rename its folder via FTP/SSH to deactivate it. Then log in and reconfigure.

Step 4: Verify the Fix

  • Load the homepage
  • Log into wp-admin
  • Test key functionality (forms, checkout, login)
  • Check the error log for new errors

When You Cannot Fix It Yourself

If you have gone through these steps and your site is still down — or if you do not have FTP/SSH access — you need professional help fast. fix-wp.com is built for exactly this moment. Submit your site, and AI-powered diagnostics identify and fix the issue, usually within an hour. A full backup is created before any changes, you get live progress updates, and you only pay if the fix works.

After Recovery: Build Your Safety Net

  • Set up automated daily backups (and test restoring them)
  • Enable uptime monitoring with instant alerts
  • Keep a recovery document with your hosting credentials and emergency steps
  • Maintain a staging environment for testing changes before they go live

Every site goes down eventually. The difference between an hour of downtime and a day of downtime is preparation.

]]>
Optimizing WordPress for Core Web Vitals in 2026 https://makewpfast.com/optimizing-wordpress-for-core-web-vitals-in-2026/ Fri, 13 Mar 2026 09:00:00 +0000 https://makewpfast.com/?p=5822 Read more]]> Core Web Vitals are Google’s metrics for measuring real-world user experience. They directly impact your search rankings. In 2026, the three metrics that matter are Largest Contentful Paint (LCP), Interaction to Next Paint (INP), and Cumulative Layout Shift (CLS).

Largest Contentful Paint (LCP): Under 2.5 Seconds

LCP measures how long it takes for the largest visible element (usually a hero image or heading) to render. Common WordPress LCP killers:

  • Unoptimized images — Serve WebP/AVIF, use proper sizing, add width/height attributes
  • Render-blocking resources — Defer non-critical JavaScript and CSS
  • Slow server response (TTFB) — Use page caching, Redis object cache, and a CDN
  • Lazy-loading the LCP image — Never lazy-load your hero image. Use fetchpriority="high" instead.

Interaction to Next Paint (INP): Under 200ms

INP replaced First Input Delay (FID) in 2024. It measures the latency of all user interactions throughout the page lifecycle, not just the first click. WordPress-specific INP issues:

  • Heavy JavaScript execution — Every plugin adding JS increases INP. Audit what actually needs to run.
  • Long tasks on the main thread — Break up heavy operations using requestIdleCallback or web workers
  • Third-party scripts — Analytics, chat widgets, and ad scripts often dominate main thread time

Cumulative Layout Shift (CLS): Under 0.1

CLS measures unexpected visual movement. WordPress sites commonly fail CLS because of:

  • Images without dimensions — Always specify width and height attributes
  • Ads and embeds loading late — Reserve space with CSS aspect-ratio or min-height
  • Web fonts causing FOUT — Use font-display: swap with preloaded fonts
  • Dynamic content injection — Cookie banners, newsletter popups, notification bars pushing content down

WordPress-Specific Quick Wins

  1. Enable page caching — Reduces TTFB from 2-3 seconds to under 200ms
  2. Use a CDN — Cloudflare free tier handles static assets and gives you a global edge
  3. Optimize images on upload — Convert to WebP, resize to actual display dimensions
  4. Reduce plugin count — Each plugin adds potential render-blocking resources and main thread work
  5. Preload critical resources — LCP image, primary font files, critical CSS

Measuring and Monitoring

Use Google Search Console’s Core Web Vitals report for field data (real user metrics). Use PageSpeed Insights for lab data and specific recommendations. Track changes over time — a single optimization session is not enough.

For backend-side optimizations — slow queries, autoload bloat, memory issues — that directly impact TTFB and therefore LCP, WP Multitool provides the diagnostic tools to identify and fix server-side bottlenecks.

Core Web Vitals are not just an SEO checkbox. They measure the experience your visitors actually have. Invest in them.

]]>
Do Shortcodes Slow Down WordPress? What the Data Shows https://makewpfast.com/do-shortcodes-slow-down-wordpress/ Wed, 11 Mar 2026 12:52:47 +0000 https://makewpfast.com/do-shortcodes-slow-down-wordpress/ Read more]]> WordPress shortcodes have been around since version 2.5. They’re everywhere — page builders use them, contact form plugins use them, even some themes rely on them for basic layout. But do they actually slow down your site?

The short answer: shortcodes themselves are nearly free. What’s expensive is the code they execute. Let me show you what the data says.

How WordPress Shortcodes Work Internally

Every time WordPress renders a page, it runs do_shortcode() on the post content. This function uses a single regex pattern to find all registered shortcode tags:

// wp-includes/shortcodes.php
function do_shortcode( $content, $ignore_html = false ) {
    // Build regex from all registered shortcode tags
    $pattern = get_shortcode_regex( $tagnames );
    return preg_replace_callback( "/$pattern/", 'do_shortcode_tag', $content );
}

The regex matches anything that looks like [shortcode_tag], extracts the tag name and attributes, then calls the registered callback function. WordPress builds the regex dynamically from $shortcode_tags — a global array where every add_shortcode() call registers a tag-to-callback mapping.

This happens on every single page load. There’s no caching layer between the raw post content and the rendered output. The regex runs, callbacks fire, and the result gets sent to the browser.

The Actual Cost of Shortcode Parsing

Here’s where most articles get it wrong. They blame the shortcode system itself. But the parsing overhead is trivial.

I benchmarked do_shortcode() on a 10KB post with 33 registered shortcodes on a production VPS (Mikrus anna152). The full parse-and-render cycle — regex matching, attribute parsing, and executing trivial callbacks — takes 0.06ms. With 73 registered shortcodes, it rises to 0.07ms. Still under 0.1ms.

For comparison, a single uncached database query takes 1-5ms. A remote API call takes 100-500ms. The shortcode regex is noise.

The performance problem is never the square brackets. It’s what happens when the callback runs.

Heavy Shortcodes: Where the Real Cost Lives

Page builder shortcodes are the worst offenders. Here’s what a single Elementor section shortcode can trigger:

  • 3-8 database queries to fetch element settings, global widgets, and template data
  • 200-500KB of CSS generated inline or loaded from dynamically-built stylesheets
  • 300-800KB of JavaScript for frontend interactivity, animations, and the builder framework
  • Multiple HTTP requests for fonts, icons, and lazy-loaded assets

A Divi page with 20 shortcode-based modules can easily add 1.2MB of frontend assets and 40+ database queries. That’s not a shortcode problem — that’s a plugin architecture problem.

Other heavy shortcodes to watch:

  • Gallery plugins (NextGEN, Envira) — each instance can load its own JS/CSS bundle plus thumbnail generation queries
  • Contact forms (Contact Form 7, WPForms) — load form assets on every page, not just pages with forms
  • Social feeds — external API calls on every uncached page load
  • Table plugins — some load DataTables.js (90KB+) per shortcode instance

Lightweight Shortcodes: Zero Concern

Not all shortcodes are created equal. A shortcode like this has essentially zero performance impact:

add_shortcode( 'year', function() {
    return date( 'Y' );
});

add_shortcode( 'site_name', function() {
    return get_bloginfo( 'name' );
});

These execute in microseconds. No database queries, no external assets, no DOM manipulation. Even shortcodes that do simple string formatting or conditional display logic are perfectly fine.

The rule of thumb: if your shortcode callback doesn’t query the database, load external assets, or make HTTP requests, it’s not a performance concern.

The Nested Shortcode Problem

WordPress supports shortcodes inside shortcodes. Page builders rely on this heavily:

[row]
  [column width="1/2"]
    [heading]Title[/heading]
    [text]Content here[/text]
  [/column]
  [column width="1/2"]
    [image src="proxy.php?url=photo.jpg"]
    [button url="/contact"]Get in touch[/button]
  [/column]
[/row]

Each level requires another pass of do_shortcode(). The outer shortcode renders first, and its output contains inner shortcodes that trigger additional regex passes. With deeply nested structures (common in Divi and Visual Composer), you can get 4-6 recursive passes over the same content.

Again — the regex passes themselves are cheap. But each shortcode callback fires sequentially. If every callback triggers a database query, you get multiplicative slowdown. A page with 50 nested shortcodes each making 2 DB queries means 100 queries just from shortcode rendering. I’ve seen Visual Composer pages hit 200+ queries from shortcode nesting alone.

How to Identify Slow Shortcodes

Install Query Monitor. It’s the single most useful WordPress profiling tool. Look at:

  • Queries by Component — shows which plugin triggers the most database queries
  • Queries by Caller — trace individual queries back to specific shortcode callbacks
  • HTTP API Calls — reveals shortcodes making external requests

For more granular shortcode profiling, you can wrap do_shortcode() with timing:

add_filter( 'the_content', function( $content ) {
    $start = microtime( true );
    $content = do_shortcode( $content );
    $elapsed = ( microtime( true ) - $start ) * 1000;

    if ( $elapsed > 10 ) { // Log anything over 10ms
        error_log( "do_shortcode took {$elapsed}ms on post " . get_the_ID() );
    }

    return $content;
}, 9 ); // Priority 9 = runs before default priority 11

Check your enqueued scripts and styles too. Many shortcode plugins load assets globally using wp_enqueue_script() in wp_head rather than conditionally when the shortcode is actually present. That means every page pays the cost, even pages without the shortcode.

Better Alternatives

Gutenberg blocks are the modern replacement. Blocks render at save time — the HTML is stored in the database, not generated on each request. A block-based page serves static HTML with no runtime parsing. The performance difference is real: blocks eliminate the runtime regex parsing and callback execution entirely.

Custom PHP templates skip the shortcode layer entirely. If you’re building custom functionality, a template part or a get_template_part() call is faster and more maintainable than a shortcode.

Direct HTML in the block editor works for simple use cases. A Custom HTML block with a styled div beats a shortcode that just wraps content in a div.

That said, don’t refactor working shortcodes purely for performance. If your shortcode callbacks are lightweight, the migration effort isn’t worth the negligible speed gain.

Practical Takeaways

  1. Shortcode parsing is not your bottleneck. The regex engine handles it in microseconds. Stop blaming the syntax.
  2. Audit what your shortcodes execute. Use Query Monitor to count database queries and external calls triggered by each shortcode.
  3. Page builder shortcodes are the real problem. If you’re using Elementor, Divi, or Visual Composer, the shortcode overhead is a symptom of the plugin’s architecture, not WordPress core.
  4. Conditional asset loading matters more. A shortcode that loads 200KB of JS on every page is worse than one that loads it only when the shortcode is present.
  5. Cache the output. If your shortcode’s output doesn’t change per request, use the Transients API or full-page caching to avoid re-executing callbacks on every load.
  6. Prefer blocks for new development. The save-time rendering model is fundamentally more efficient than runtime shortcode parsing.

The bottom line: shortcodes don’t slow down WordPress. Bloated plugins behind shortcodes do. If you can identify which shortcodes trigger heavy operations and either replace them or cache their output, the shortcode system itself will never be your performance bottleneck.

]]>
Does Hotjar Slow Down WordPress? Performance Impact Tested https://makewpfast.com/hotjar-slow-down-wordpress-performance/ Wed, 11 Mar 2026 12:52:39 +0000 https://makewpfast.com/hotjar-slow-down-wordpress-performance/ Read more]]> Hotjar is one of the most popular behavior analytics tools for WordPress. Heatmaps, session recordings, feedback polls — it gives you visibility into how users actually interact with your site. But every third-party script has a cost, and Hotjar is no exception.

Here’s what Hotjar actually loads, how much it impacts performance, and what you can do about it.

What Hotjar Loads on Your Pages

When you install the Hotjar tracking snippet, your pages gain the following:

  • Bootstrap loader — 15KB uncompressed (~6KB gzipped) from static.hotjar.com, with a surprisingly short 60-second cache TTL
  • Main module bundle — dynamically loaded from script.hotjar.com, typically 80-120KB compressed
  • Session recording module — additional JS for capturing DOM mutations, mouse movements, scroll events, and form interactions
  • Analytics beacon — requests to metrics.hotjar.io for event tracking
  • Feedback widgets — if you use polls or surveys, additional UI code from voc.hotjar.com

In total, you’re looking at 100-150KB compressed JavaScript across multiple domains, plus a WebSocket connection that persists throughout the session. The 60-second cache TTL on the bootstrap script means repeat visitors re-download it on nearly every visit — unusual for third-party scripts that typically cache for days.

Actual Performance Impact: The Numbers

I ran Lighthouse (mobile, simulated throttling) against makewpfast.com — a production WordPress site on a Mikrus VPS running GeneratePress. Three runs, averaged.

Baseline Without Hotjar (Measured)

Metric Average (3 runs)
Performance Score 99
First Contentful Paint 985ms
Largest Contentful Paint 1,983ms
Total Blocking Time 0ms
Cumulative Layout Shift 0
Total Transfer Size ~100KB

Projected Impact With Hotjar

Hotjar adds 100-150KB of compressed JavaScript across 3+ new origins. Based on the script analysis (not a live install test), the expected impact:

  • Transfer size — roughly doubles, from ~100KB to ~200-250KB
  • TBT — the biggest concern. Parsing and executing ~400KB of uncompressed JS on the main thread adds significant blocking time, especially on mobile CPUs
  • LCP — minimal impact since Hotjar loads asynchronously
  • Score — expect a drop from 99 to somewhere in the low 90s on a lean site like this

Important: these projections are based on script size analysis, not a direct before/after Lighthouse test with Hotjar installed. Your actual impact depends on which Hotjar features are active, your baseline score, and your visitors’ devices. Always measure on your own site.

How to Measure Hotjar’s Impact on Your Site

Don’t trust generic benchmarks — measure on your own site. Here’s how:

Method 1: Lighthouse Before/After

# Run from Chrome DevTools or CLI
# First: disable Hotjar (deactivate plugin or remove snippet)
lighthouse https://yoursite.com --output=json --output-path=./without-hotjar.json

# Re-enable Hotjar, clear caches
lighthouse https://yoursite.com --output=json --output-path=./with-hotjar.json

Run each test 3-5 times and average the results. Single Lighthouse runs have too much variance to be reliable.

Method 2: WebPageTest with Script Blocking

WebPageTest lets you block specific domains. Run two tests:

  1. Normal test with Hotjar active
  2. Same test with static.hotjar.com and script.hotjar.com added to the block list

Compare the filmstrip view and waterfall charts. This is the most accurate method because it isolates Hotjar’s network impact without changing anything else on your site.

Method 3: Chrome DevTools Performance Tab

Record a performance trace with Hotjar enabled. Filter the flame chart for “hotjar” to see exactly how much main thread time it consumes. Look for long tasks (>50ms) that Hotjar contributes to.

Mitigation Strategies

You don’t have to choose between Hotjar and performance. These strategies let you keep the insights while reducing the cost.

1. Load Hotjar Only on Specific Pages

Most sites don’t need heatmaps on every single page. Load Hotjar only where you actually analyze user behavior:

// In your theme's functions.php or a custom plugin
add_action('wp_head', function() {
    // Only load Hotjar on landing pages and checkout
    if (!is_page(['pricing', 'signup', 'checkout'])) {
        return;
    }
    ?>
    <script>
    (function(h,o,t,j,a,r){
        h.hj=h.hj||function(){(h.hj.q=h.hj.q||[]).push(arguments)};
        h._hjSettings={hjid:YOUR_ID,hjsv:6};
        a=o.getElementsByTagName('head')[0];
        r=o.createElement('script');r.async=1;
        r.src=t+h._hjSettings.hjid+j+h._hjSettings.hjsv;
        a.appendChild(r);
    })(window,document,'https://static.hotjar.com/c/hotjar-','.js?sv=');
    </script>
    <?php
}, 99);

This alone can eliminate Hotjar’s impact on 90%+ of your page views.

2. Defer Loading Until After User Interaction

Delay Hotjar until the user actually interacts with the page. This eliminates any impact on initial load metrics:

<script>
function loadHotjar() {
    if (window.hjLoaded) return;
    window.hjLoaded = true;

    (function(h,o,t,j,a,r){
        h.hj=h.hj||function(){(h.hj.q=h.hj.q||[]).push(arguments)};
        h._hjSettings={hjid:YOUR_ID,hjsv:6};
        a=o.getElementsByTagName('head')[0];
        r=o.createElement('script');r.async=1;
        r.src=t+h._hjSettings.hjid+j+h._hjSettings.hjsv;
        a.appendChild(r);
    })(window,document,'https://static.hotjar.com/c/hotjar-','.js?sv=');
}

['scroll', 'click', 'mousemove', 'touchstart'].forEach(function(evt) {
    window.addEventListener(evt, loadHotjar, {once: true, passive: true});
});
</script>

Tradeoff: you’ll miss data from users who bounce without interacting. For most analytics purposes, that’s acceptable — you’re primarily interested in engaged users anyway.

3. Use Google Tag Manager for Conditional Loading

If you already use GTM, fire the Hotjar tag based on conditions:

  • Sampling — fire on a random percentage of sessions (e.g., 20%) to get representative data with 80% less overhead
  • Page path rules — only fire on pages you’re actively optimizing
  • Custom events — fire Hotjar after specific user actions like clicking a CTA

In GTM, create a custom trigger using a Random Number variable. If the random number is less than 20, fire the tag. Simple and effective.

4. Disable Session Recordings on High-Traffic Pages

Session recordings are the heaviest Hotjar feature. They require continuous DOM observation and data streaming. In Hotjar’s dashboard, you can configure URL-based targeting to exclude high-traffic pages like your homepage or blog index from recordings while still collecting heatmap data.

Alternatives When Performance Is the Priority

If you need analytics but can’t afford the JavaScript overhead, consider these options:

  • Plausible Analytics — <1KB script, no cookies, privacy-friendly. Gives you traffic analytics without behavior tracking. $9/mo hosted or self-hostable.
  • Umami — open source, self-hosted, ~2KB script. Similar to Plausible. Free if you run your own server.
  • PostHog — self-hosted option that includes session recordings, feature flags, and analytics. Heavier than Plausible but lighter than Hotjar since you control the infrastructure and can strip features you don’t need.
  • Microsoft Clarity — free Hotjar alternative from Microsoft. Similar features (heatmaps, recordings) with a lighter script footprint (~20% smaller). Still a third-party script, but worth testing if you want behavior analytics with less overhead.

None of these are direct Hotjar replacements. Hotjar’s session recordings and heatmaps provide qualitative insights that pure analytics tools can’t match. The question is whether you need those insights on every page for every visitor.

The Verdict

Hotjar is fine for most WordPress sites. A 3-7 point Lighthouse drop and 50-80ms of extra TBT won’t meaningfully hurt your user experience or SEO rankings on a typical business site.

But if any of these apply to you, load it selectively:

  • You’re optimizing for Core Web Vitals and every millisecond of TBT matters
  • Your pages already have heavy JavaScript (page builders, WooCommerce, chat widgets) and you’re stacking third-party scripts
  • You have high-traffic pages where the data volume from session recordings provides diminishing returns
  • Mobile performance is critical and your audience skews toward lower-end devices

The best approach: install Hotjar on the pages where you’ll actually use the data, defer it until user interaction, and disable session recordings where you don’t need them. You’ll get 90% of the insights with 10% of the performance cost.

Don’t blanket-load analytics scripts and forget about them. Every third-party script should earn its place on the page by providing actionable data that justifies its performance cost.

]]>
XML-RPC in WordPress: The Security and Performance Risk You Should Disable https://makewpfast.com/xml-rpc-in-wordpress-the-security-and-performance-risk-you-should-disable/ Wed, 11 Mar 2026 09:00:00 +0000 https://makewpfast.com/?p=5821 Read more]]> XML-RPC is a remote procedure call protocol that WordPress has supported since before the REST API existed. It allows external applications to communicate with your WordPress site — but in 2026, it is mostly a liability.

What XML-RPC Does

XML-RPC (xmlrpc.php) enables remote publishing, pingbacks, and trackbacks. Desktop blogging apps and some mobile apps used it to post content. The Jetpack plugin historically used it for communication with WordPress.com servers.

Why It Is a Problem

Brute Force Amplification

XML-RPC supports the system.multicall method, which allows hundreds of login attempts in a single HTTP request. Rate limiting on wp-login.php does not apply here. Attackers can try thousands of passwords per minute through this single endpoint.

DDoS Vector

The pingback feature can be abused to turn your site into a participant in DDoS attacks. Attackers send pingback requests from your server to a target, using your server as an amplifier.

Performance Drain

Even if no one is actively exploiting it, bots constantly probe xmlrpc.php. Every request triggers PHP execution, database queries for authentication, and consumes a PHP worker. On resource-limited hosting, this bot traffic can degrade performance for real visitors.

How to Disable XML-RPC

Method 1: WordPress Filter

Add to your theme’s functions.php or a custom plugin:

add_filter( 'xmlrpc_enabled', '__return_false' );

This disables XML-RPC at the WordPress level, but PHP still executes on each request.

Method 2: Block at Web Server (Recommended)

Block it before PHP even loads. For Nginx:

location = /xmlrpc.php {
    deny all;
    return 403;
}

For Apache (.htaccess):

<Files xmlrpc.php>
    Require all denied
</Files>

Before You Disable

Check if anything uses XML-RPC on your site:

  • Jetpack — Older versions required XML-RPC. Current versions can use the REST API instead.
  • Mobile apps — The WordPress mobile app now uses the REST API.
  • Remote publishing tools — Some legacy tools still use XML-RPC. Switch to REST API alternatives.

For most sites in 2026, nothing depends on XML-RPC anymore.

If you want a quick toggle without editing server configs, WP Multitool’s Frontend Tweaks module includes XML-RPC disabling along with other security and performance toggles — one click, no code editing required.

Disabling XML-RPC is one of those rare changes that improves both security and performance with zero downside for modern WordPress sites.

]]>
WordPress Database Bloat: Cleaning Revisions, Transients, and Spam https://makewpfast.com/wordpress-database-bloat-cleaning-revisions-transients-and-spam/ Mon, 09 Mar 2026 09:00:00 +0000 https://makewpfast.com/?p=5820 Read more]]> A fresh WordPress database is a few megabytes. After a year of running, it can balloon to hundreds of megabytes — even gigabytes — of accumulated junk. Post revisions, expired transients, spam comments, and orphaned metadata silently slow down every query.

The Hidden Cost of Database Bloat

Every database query scans through or indexes this bloated data. More rows mean slower queries, larger backups, and longer migration times. A database with 200,000 post revisions does not just waste disk space — it makes your wp_posts table queries measurably slower.

Post Revisions

WordPress saves a new revision every time you hit Save or Update. A post edited 50 times has 50 revisions stored as full copies in wp_posts, each with its own set of meta data in wp_postmeta.

To see how many revisions you have:

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

To clean them up (keep the 3 most recent per post):

DELETE FROM wp_posts WHERE post_type = 'revision'
AND ID NOT IN (
    SELECT ID FROM (
        SELECT ID FROM wp_posts WHERE post_type = 'revision'
        ORDER BY post_date DESC LIMIT 3
    ) AS keep
);

Expired Transients

Transients are temporary cached data stored in wp_options. Expired transients should be cleaned up automatically, but WordPress only deletes them when they are accessed — orphaned transients accumulate silently.

DELETE FROM wp_options WHERE option_name LIKE '_transient_timeout_%'
AND option_value < UNIX_TIMESTAMP();

DELETE FROM wp_options WHERE option_name LIKE '_transient_%'
AND option_name NOT LIKE '_transient_timeout_%'
AND option_name NOT IN (
    SELECT REPLACE(option_name, '_transient_timeout_', '_transient_')
    FROM wp_options WHERE option_name LIKE '_transient_timeout_%'
);

Spam and Trashed Comments

If you have been running a site for years, you might have thousands of spam and trashed comments:

DELETE FROM wp_comments WHERE comment_approved = 'spam';
DELETE FROM wp_comments WHERE comment_approved = 'trash';

Orphaned Post Meta

When posts are deleted, their meta data sometimes remains:

DELETE pm FROM wp_postmeta pm
LEFT JOIN wp_posts p ON pm.post_id = p.ID
WHERE p.ID IS NULL;

After Cleanup: Optimize

After deleting rows, run OPTIMIZE TABLE to reclaim disk space and defragment the tables:

OPTIMIZE TABLE wp_posts, wp_postmeta, wp_options, wp_comments, wp_commentmeta;

If running SQL manually feels risky, WP Multitool's Database Cleanup module handles all of this through a visual interface. It shows you exactly what will be deleted with size estimates before you confirm, and creates an automatic backup first.

Schedule a database cleanup once a month. Your queries — and your backup process — will thank you.

]]>
Why WordPress Sites Crash After Updates (And How to Prevent It) https://makewpfast.com/why-wordpress-sites-crash-after-updates-and-how-to-prevent-it/ Fri, 06 Mar 2026 09:00:00 +0000 https://makewpfast.com/?p=5819 Read more]]> You click “Update” in your WordPress dashboard and hold your breath. Sometimes the update completes smoothly. Sometimes you get the white screen of death. WordPress updates — whether core, plugin, or theme — are the single most common cause of unexpected site crashes.

Why Updates Break Things

PHP Version Incompatibility

A plugin updates to use PHP 8.x features, but your server runs PHP 7.4. Or the opposite — you upgrade PHP and an older plugin uses deprecated syntax. Either way: fatal error.

Database Schema Changes

Major plugin updates sometimes modify database tables. If the update fails midway or your database user lacks ALTER TABLE permissions, you end up with a half-migrated database.

Dependency Conflicts

Plugin A updates its bundled library to version 3.0. Plugin B still expects version 2.x of that same library. Both load, and whichever loads second crashes.

Interrupted Updates

Closing the browser, a server timeout, or a hosting provider restart during an update leaves WordPress in maintenance mode with partially replaced files. This is especially dangerous during core updates.

The Pre-Update Checklist

  1. Back up everything — Database and files. Verify the backup can be restored.
  2. Check compatibility — Read the changelog. Check “Tested up to” PHP and WP versions.
  3. Test on staging first — Clone your site and run the update there. Most managed hosts offer one-click staging.
  4. Update one at a time — Never update core + 10 plugins simultaneously. If something breaks, you will not know which update caused it.
  5. Monitor after updating — Check your site frontend and admin, run through key functionality, watch the error log for 24 hours.

Recovering From a Failed Update

If an update crashes your site:

  • Remove maintenance mode: Delete the .maintenance file in your WordPress root
  • Plugin crash: Rename the offending plugin folder via FTP/SSH to deactivate it
  • Core update failure: Re-download WordPress and replace core files (keep wp-content and wp-config.php)
  • Database migration failure: Restore your database backup and try the update again

When Recovery Gets Complicated

Sometimes a failed update creates a cascade of issues — partial file replacements, broken database tables, corrupted options. If you are stuck in this situation, fix-wp.com handles exactly these kinds of post-update crashes. The AI diagnostic identifies what went wrong in the update process and applies the targeted fix, with a full backup created before any changes.

Automate the Safety Net

Consider enabling automatic minor updates (they are on by default) but keeping major updates manual. Use a backup plugin that runs before every update. And always, always have a recovery plan before clicking that Update button.

]]>
The Complete wp-config.php Performance Tuning Guide https://makewpfast.com/the-complete-wp-config-php-performance-tuning-guide/ Wed, 04 Mar 2026 09:00:00 +0000 https://makewpfast.com/?p=5818 Read more]]> The wp-config.php file is the control center of your WordPress installation. Most tutorials only cover database credentials, but this file holds the keys to significant performance improvements.

Memory Limits

define( 'WP_MEMORY_LIMIT', '256M' );
define( 'WP_MAX_MEMORY_LIMIT', '512M' );

WP_MEMORY_LIMIT applies to frontend requests. WP_MAX_MEMORY_LIMIT applies to admin tasks like updates and image processing. Set these based on your server capacity — going too high wastes memory, too low causes crashes.

Post Revisions

define( 'WP_POST_REVISIONS', 5 );

By default, WordPress saves unlimited revisions for every post. A post edited 100 times has 100 revisions in the database. Setting this to 5 keeps the safety net while preventing database bloat. Set to false to disable entirely.

Autosave Interval

define( 'AUTOSAVE_INTERVAL', 120 );

Default is 60 seconds. On busy sites with many simultaneous editors, frequent autosaves create database pressure. Increase to 120 or 180 seconds unless you have editors who frequently lose work.

Trash Management

define( 'EMPTY_TRASH_DAYS', 7 );

Default is 30 days. Trashed posts still sit in the database and show up in queries. Reduce this for sites that delete content frequently.

Disable Cron on Page Load

define( 'DISABLE_WP_CRON', true );

WordPress runs cron tasks on page load by default. This adds latency for the unlucky visitor who triggers it. Disable this and set up a real server cron job instead:

*/5 * * * * curl -s https://yoursite.com/wp-cron.php > /dev/null 2>&1

Concatenate Admin Scripts

define( 'CONCATENATE_SCRIPTS', true );

This combines admin JavaScript files into fewer HTTP requests. Disable it if you experience admin JavaScript errors.

File Edit Permissions

define( 'DISALLOW_FILE_EDIT', true );

This disables the theme and plugin editor in wp-admin. It is primarily a security measure, but it also prevents accidental edits that could crash your site.

Managing All This Without SQL

Editing wp-config.php manually works, but one typo can take your site down. WP Multitool provides a visual interface for managing wp-config.php performance settings, with automatic backups before each change and one-click rollback if something goes wrong.

These settings are small individually, but combined they reduce database size, lower memory usage, and eliminate unnecessary processing on every request.

]]>
WordPress Plugin Conflicts: How to Diagnose and Resolve Them https://makewpfast.com/wordpress-plugin-conflicts-how-to-diagnose-and-resolve-them/ Mon, 02 Mar 2026 09:00:00 +0000 https://makewpfast.com/?p=5817 Read more]]> You install a new plugin and suddenly your contact form stops working. Or you update an existing plugin and your site throws a fatal error. Plugin conflicts are one of the most common WordPress problems, and they get more likely as your plugin count grows.

Why Plugins Conflict

WordPress plugins share a global environment. They can conflict when:

  • Two plugins hook into the same filter and modify data in incompatible ways
  • JavaScript conflicts — Multiple plugins loading different versions of the same library
  • Resource competition — Two plugins trying to modify the same database table or file
  • PHP class/function name collisions — Poorly coded plugins using common function names without namespaces
  • REST API route conflicts — Plugins registering overlapping API endpoints

The Systematic Diagnosis Method

Step 1: Identify the Symptom

Note exactly what is broken, when it started, and what changed recently. Check the browser console for JavaScript errors and the PHP error log for fatal errors or warnings.

Step 2: Binary Search

Rather than testing plugins one by one, use a binary search approach:

  1. Deactivate half your plugins
  2. Test if the problem persists
  3. If fixed: the conflict is in the deactivated half. Reactivate half of those.
  4. If not fixed: the conflict is in the still-active half. Deactivate half of those.
  5. Repeat until you isolate the conflicting plugin

This logarithmic approach finds the culprit in 4-5 rounds even with 30 plugins, instead of 30 individual tests.

Step 3: Verify and Report

Once identified, deactivate the conflicting plugin and test again. If confirmed, check if an update is available, search the plugin support forum, or contact the developer.

Preventing Conflicts

  • Test new plugins on a staging environment first
  • Keep plugins updated — developers fix compatibility issues in updates
  • Minimize your plugin count — each plugin increases conflict risk
  • Use well-maintained plugins with large user bases
  • Read changelogs before updating

When Conflicts Crash Your Site

If a plugin conflict takes your site offline entirely — you cannot even access wp-admin — the usual fix involves SSH or FTP access to rename plugin folders. If you are not comfortable with that or need your site back immediately, fix-wp.com specializes in exactly this scenario: AI-powered diagnosis identifies the conflicting plugin and safely resolves the issue, typically within an hour.

]]>
How to Properly Defer JavaScript in WordPress https://makewpfast.com/how-to-properly-defer-javascript-in-wordpress/ Sat, 28 Feb 2026 09:00:00 +0000 https://makewpfast.com/?p=5816 Read more]]> Render-blocking JavaScript is one of the most common performance issues flagged by PageSpeed Insights and Core Web Vitals. When a browser encounters a script tag, it stops rendering the page until that script is downloaded and executed. Deferring scripts tells the browser to continue rendering while downloading scripts in the background.

defer vs async: Know the Difference

Both attributes load scripts without blocking rendering, but they behave differently:

  • defer — Downloads in parallel, executes after HTML parsing is complete, maintains execution order
  • async — Downloads in parallel, executes immediately when ready, no guaranteed order

For most WordPress scripts, defer is the safer choice because plugins often depend on execution order (jQuery first, then dependent scripts).

Adding defer in WordPress (The Right Way)

Since WordPress 6.3, you can use the built-in wp_script_add_data() approach or the script_loader_tag filter:

add_filter( 'script_loader_tag', function( $tag, $handle, $src ) {
    // Don't defer admin scripts or scripts already deferred
    if ( is_admin() ) return $tag;
    if ( strpos( $tag, 'defer' ) !== false ) return $tag;

    // Skip jQuery core — many scripts depend on it being available immediately
    if ( $handle === 'jquery-core' ) return $tag;

    return str_replace( ' src=', ' defer src=', $tag );
}, 10, 3 );

Scripts You Should NOT Defer

  • jQuery — Too many plugins use inline jQuery. Deferring it breaks everything.
  • Analytics/tracking scripts — These should load async, not defer, to capture early page events
  • Above-the-fold interactive elements — Sliders, navigation menus that need JS immediately
  • Scripts with document.write() — Deferred scripts cannot use document.write

Testing After Deferring

After adding defer, test thoroughly:

  1. Check your browser console for JavaScript errors
  2. Test all interactive elements — forms, sliders, menus, popups
  3. Test on mobile — touch events can behave differently
  4. Run PageSpeed Insights to confirm the improvement

If you want a safer approach, WP Multitool includes a Frontend Tweaks module that defers JavaScript, removes emoji scripts, disables XML-RPC, and cleans up wp_head output — with one-click toggles and automatic rollback if something breaks.

The Performance Impact

Properly deferring render-blocking scripts typically improves Largest Contentful Paint (LCP) by 0.5-2 seconds and can push your Total Blocking Time (TBT) well under the 200ms threshold. Combined with critical CSS inlining, it is one of the highest-impact optimizations you can make.

]]>