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.