If comments are open on a WordPress site, spam bots will find them, often within days. Spam comments clutter moderation, fill the database, and, if approved by mistake, add junk links that hurt your SEO and your visitors’ trust. Here’s a layered approach that stops nearly all of it.

Step 1: tighten discussion settings

Settings → Discussion:

  • Comment must be manually approved, or “Comment author must have a previously approved comment”.
  • Hold a comment in the queue if it contains 2 or more links. Spam almost always contains links.
  • Automatically close comments on articles older than 30–90 days. Old posts attract most bot spam.
  • Uncheck “Allow link notifications from other blogs (pingbacks and trackbacks)”. Pingback spam is common, and the feature is rarely useful.
  • Use the Disallowed Comment Keys list for recurring spam words or domains.

Step 2: an anti-spam plugin

Plugin How it works Privacy
Akismet Sends comments to Automattic’s cloud for checking Data leaves your server; commercial sites need a paid plan
Antispam Bee Local checks (honeypot, timing, country, language, IP history) GDPR-friendly, no external service
Honeypot-based plugins (e.g. WP Armour) Hidden fields that bots fill in Local
CAPTCHA plugins (Turnstile, hCaptcha, reCAPTCHA) Challenge on the comment form Depends on provider

One good plugin is enough. Cloudflare Turnstile is a privacy-friendly, mostly invisible CAPTCHA alternative if you need a challenge.

Step 3: don’t need comments? Turn them off

Many business sites don’t need comments at all:

wp option update default_comment_status closed
wp option update default_ping_status closed
wp post list --post_type=post,page --comment_status=open --format=ids | xargs -r -n 50 wp post update --comment_status=closed --ping_status=closed

Or use a “Disable Comments” plugin, which also removes comment-related admin menus and endpoints.

Step 4: clean up existing spam

wp comment count
wp comment delete $(wp comment list --status=spam --format=ids) --force
wp comment delete $(wp comment list --status=trash --format=ids) --force

For huge numbers of pending spam comments (tens of thousands), delete in batches, or with SQL (back up first):

DELETE FROM wp_comments WHERE comment_approved = 'spam';
DELETE FROM wp_commentmeta WHERE comment_id NOT IN (SELECT comment_ID FROM wp_comments);

Then optimize the tables. See WordPress database optimization and WP-CLI guide.

Step 5: server-level protection

Bots post directly to wp-comments-post.php. On a VPS you can rate-limit it in Nginx, before PHP runs:

# nginx.conf (http block)
limit_req_zone $binary_remote_addr zone=wpcomments:10m rate=5r/m;

# site server block
location = /wp-comments-post.php {
    limit_req zone=wpcomments burst=3 nodelay;
    include snippets/fastcgi-php.conf;
    fastcgi_pass unix:/run/php/php8.3-fpm.sock;
}

Block XML-RPC too (pingback spam and abuse). See disable XML-RPC.

Fail2ban can ban IPs that post too often. See Fail2ban and Nginx rate limiting.

Contact form and registration spam

The same ideas apply to forms and user registrations:

  • honeypot or Turnstile on contact forms;
  • Settings → General → Membership: disable “Anyone can register” unless you need it. Spam registrations are common;
  • WooCommerce: enable a CAPTCHA on account creation, if registrations are open.

Spam is slowing the site?

Thousands of pending spam comments make the admin comment screens slow, and bloat wp_comments and wp_commentmeta. If your dashboard shows a huge pending count, clean it up first (Step 4), then add the plugin and server rules, so it doesn’t build up again. Check comment counts weekly for a while after the cleanup.

Quick reference

Layer Action
Settings Moderate links, close old posts, disable pingbacks
Plugin Antispam Bee (local) or Akismet (cloud)
Optional challenge Cloudflare Turnstile
Cleanup wp comment delete $(wp comment list --status=spam --format=ids)
Server Nginx limit_req on wp-comments-post.php, block XML-RPC

Related: WordPress security plugins and WordPress hardening.

  • WordPress
  • Security
  • Spam