Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -1,4 +1,26 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

# Ensure PATH includes Node/NVM/Homebrew for GUI Git clients (e.g., GitHub Desktop)
if ! command -v npx >/dev/null 2>&1; then
# Prepend common Node, Homebrew, and pnpm binary paths
export PATH="/usr/local/bin:/opt/homebrew/bin:$HOME/Library/pnpm:$PATH"

# Append latest NVM node version path if present without requiring bash-only nvm.sh sourcing
if [ -d "$HOME/.nvm/versions/node" ]; then
latest_nvm_bin="$(ls -d "$HOME/.nvm/versions/node/"* 2>/dev/null | tail -n 1)/bin"
if [ -d "$latest_nvm_bin" ]; then
export PATH="$latest_nvm_bin:$PATH"
fi
fi

# Only source nvm.sh if running in bash or zsh (nvm.sh is not POSIX sh compatible)
if [ -n "$BASH_VERSION" ] || [ -n "$ZSH_VERSION" ]; then
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
fi
fi

npx lint-staged


Binary file added public/assets/lmby-performance.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/assets/perfguard-cronhealth.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/assets/perfguard-dashboard.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/assets/perfguard-welcome.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/assets/taming-bottlenecks.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
---
author: Greg Miller
datetime: 2026-07-28T12:50:00Z
title: "Taming WordPress Multisite Bottlenecks: Bot Mitigation & Cron Health with a Custom Plugin"
slug: taming-wordpress-multisite-bottlenecks-bot-mitigation-cron-health-with-a-custom-plugin
featured: true
draft: false
tags:
- wordpress
- multisite
- php
- performance
ogImage: "/assets/taming-bottlenecks.webp"
description: Learn how a custom WordPress network plugin resolves performance bottlenecks on a high-traffic multisite setup. Discover how early-exit bot firewalls block username enumeration attacks while targeted database pruning prevents WP-Cron option array bloat.
---

![A featured cover illustration depicting server traffic flow transitioning from chaotic bot requests into an organized, protected network pipeline](/assets/taming-bottlenecks.webp)

Managing high-traffic WordPress Multisite networks often reveals unique performance challenges. In large setups, standard off-the-shelf security or optimization plugins can introduce their own bloat, compounding the very issues they are meant to solve.

At the end of June 2026, we deployed a custom-engineered solution—**UXPA Network Performance & Guard Suite**—to address two persistent bottlenecks identified in server log audits: aggressive, automated bot harvesting and recurring database option table serialization locks.

---

## The Root Performance Bottlenecks

### 1. Automated Credential Harvesting via Username Enumeration

Bots continuously probe WordPress sites searching for valid administrative and author usernames. They typically target default query endpoints:

- Query strings targeting author archives: `/?author=N`
- Core REST API user endpoints: `/wp-json/wp/v2/users` or `/wp-json/wp/v2/users/me`

While standard security utilities can block these requests, letting every malicious scan boot up the full WordPress core, query the database, and execute complex plugin chains causes significant CPU and memory spikes. On a multisite network, this traffic degrades performance for genuine users across every sub-site.

### 2. Cron Array Serialization Failures

WordPress stores scheduled tasks inside a single serialized database option (`cron`). When background libraries like Action Scheduler accumulate tens of thousands of historic, failed, or duplicate events, this option row balloons in size.

Eventually, writing updates to this database row hits MySQL packet limits or thread locks, resulting in repeated system errors:
`Cron reschedule event error for hook: action_scheduler_run_queue... Error code: could_not_set`

When `action_scheduler_run_queue` fails to save its state, background processing stalls, creating a cascading backlog.

---

## The Solution: UXPA Network Performance & Guard Suite

To solve these issues without adding third-party plugin overhead, we engineered a dedicated, lightweight network suite.

### Key Architectural Capabilities

1. **Early-Exit Firewall:** Intercepts username enumeration attempts during the early `init` hook execution phase. It drops connection requests immediately before WordPress initializes heavy database queries or theme resources.
2. **Cron Database Health & Pruning:** Keeps the scheduler array lean by automatically stripping duplicate task hooks and offering a single-click queue purge.
3. **Action Scheduler Retention:** Limits completed action log retention to 7 days (down from the 30-day default), keeping table sizes under control.
4. **Threat Intelligence Integration:** Outbound links within the dashboard allow administrators to audit offending IP addresses directly on [AbuseIPDB](https://www.abuseipdb.com/).

![A screenshot of the UXPA Network Performance & Guard Suite welcome dashboard in WordPress admin, displaying key plugin feature cards for early-exit bot protection and cron optimization](/assets/perfguard-welcome.webp)

---

## Investigating Threats with AbuseIPDB

When an IP triggers our early-exit firewall, the dashboard provides direct lookup links to verify its threat profile before applying permanent edge or host-level blocks.

![A screenshot of the IP security dashboard showing blocked request logs, AbuseIPDB confidence scores, and IP lookup controls for high-volume offending addresses](/assets/perfguard-dashboard.webp)

For example, looking up an offending IP (`102.220.160.79`) shows a **100% Abuse Confidence Score** with 427 recent reports of failed WordPress logins and web application attacks. This confirms that the early-exit firewall is catching legitimate malicious actors.

---

## Managing Security & Blocking Strategies

The plugin dashboard aggregates threat statistics and offers quick export options for off-site auditing.

When an IP demonstrates persistent malicious behavior, we employ a multi-layered blocking strategy:

### 1. Edge-Level Blocking (Cloudflare)

Offloading blocked IPs to Cloudflare WAF drops malicious traffic at the CDN edge, preventing requests from reaching our web server entirely.

### 2. Host-Level Rules (WP Engine)

For persistent subnet probes, we configure access rules directly within the WP Engine control panel.

Adding IP deny rules at the host level stops the traffic at the web server layer (Nginx/Apache), protecting PHP execution limits.

---

## Restoring Scheduler Health

The **Cron Health** tab provides immediate visibility into the underlying state of the WordPress scheduler array.

### Performance Diagnostics Delivered:

- **Cron Option Size Tracking:** Keeps the serialized byte count visible (currently stabilized at a clean 8.12 KB).
- **Scheduled Event Auditing:** Monitors the total number of active queue items (49 total events).
- **Duplicate Event Cap:** Enforces strict limits on repetitive hook registrations to prevent option row bloat.
- **Manual Queue Purge:** Provides a one-click mechanism to purge historic Action Scheduler logs instantly.

![A screenshot of the Cron Health diagnostic interface displaying total active cron array size in kilobytes, event queue counts, and manual queue cleanup triggers](/assets/perfguard-cronhealth.webp)

---

## Opportunities for Future Improvement

While the suite has successfully stabilized background queue processing and short-circuited bot traffic, there are several areas targeted for future enhancement:

1. **Dedicated Custom Database Table (`dbDelta` Migration):**

- _Current State:_ Telemetry data uses bounded `update_site_option()` writes. In WordPress Multisite, `sitemeta` options preload across the entire network on every page request.
- _Enhancement:_ Transition log storage to a dedicated custom table (`wp_uxpa_security_logs`). This will remove telemetry writes from the preloaded network memory path entirely, allow longer log retention windows, and enable fast indexed per-IP querying.

2. **Automated Cloudflare API Integration:**

- _Current State:_ High-volume offending IPs are reviewed manually before copying them into Cloudflare or host firewall lists.
- _Enhancement:_ Add an optional Cloudflare API endpoint integration to allow one-click IP banning directly from the plugin dashboard into Cloudflare WAF rulesets.

3. **Automated Cron Array Auto-Recovery:**

- _Enhancement:_ Implement an automated health check that detects if the core `cron` option string becomes corrupted or un-serializable, automatically executing an array repair routine to prevent execution stalls entirely.

## Let me build a custom plugin for your community or multisite website

<div class="grid grid-cols-1 sm:grid-cols-[1fr_2fr] gap-6 items-center mt-8">
<div class="flex justify-center sm:justify-start">
<img src="/assets/lmby-performance.webp" class="sm:w-48 w-full h-auto rounded" alt="Tired of evaluating freemium plugins that don't quite serve your needs? Let me build one that works perfectly for you. Contact Shrinkray Interactive!" />
</div>

<p class="w-full">
Need a custom WordPress plugin tailored to your community, business, or multisite website? <a href="https://shrinkraylabs.com/contact-me/" class="underline decoration-dashed underline-offset-8 hover:text-skin-accent"><strong>Shrinkray Interactive</strong></a> is here to help. We research your specific needs and design, evaluate, implement, and continuously improve your white-labeled plugin.
</p>
</div>

Ready to lock down your network? Reach out to Greg to get your own custom plugin developed today!