Spam comments were the first thing I fought on my first WordPress blog, and the pattern hasn’t really changed. Bots crawl the web looking for open wp-comments-post.php endpoints, paste in a link-stuffed comment, and move on to the next site. Your job is to make it expensive enough that they skip yours.
You don’t need a stack of plugins for this. Most WordPress spam is handled by three things: Akismet, a few Discussion settings, and stripping HTML from the comment form. The rest is diminishing returns.
Akismet, with discard enabled
Akismet ships with every WordPress install. It’s made by Automattic (where I work) and it catches most comment spam at the API level before the comment ever hits your database.

Setup is short:
- Sign up at akismet.com and grab an API key. The personal plan is free.
- Go to Plugins → Akismet in WordPress, paste the key, and save.
- Open Akismet’s settings and enable Silently discard the worst and most pervasive spam.

That last option matters. Without it, Akismet still catches the obvious spam, but it dumps it into the Spam queue for you to eyeball. “Silently discard” throws away the worst of it automatically, so your queue only contains edge cases. On a busy blog, it’s the difference between scanning 50 spam comments a week and scanning 500.
Tune the Discussion settings
Settings → Discussion already has enough levers to handle a lot of spam without any code. The combination I use on every site I run:

- Comment must be manually approved. On low-traffic sites, I just approve everything myself. On busier sites, I drop this and rely on the next two settings.
- Comment author must have a previously approved comment. After someone’s first approved comment, they can post freely. First-time commenters wait for review.
- Hold a comment in the queue if it contains N or more links. Set
Nto 2. Spammers almost always include at least one link in the comment body plus the URL field, so 2 catches most of them without false-flagging real commenters. - Disable trackbacks and pingbacks. Both are abused constantly and rarely used for anything legitimate anymore. Uncheck “Allow link notifications from other blogs.”
Block common spam keywords
The Comment Moderation and Disallowed Comment Keys boxes at the bottom of the Discussion screen let you list words or phrases that should trigger moderation or auto-rejection.

Instead of building a block list from scratch, look at whatever ends up in your own Spam queue for a week and pick out the recurring patterns, product names, pharmacy terms, gambling keywords, casino URLs, and so on. A short, actual list from your own site is better than a generic list you copied off someone else’s blog.
If you want a starting point, the WordPress community maintains a decent comment blacklist on GitHub that you can paste into Disallowed Comment Keys and then prune over time.
Strip HTML from comments
The main reason spammers bother posting comments is the anchor tag. Take HTML out of the comment body entirely and you remove most of the incentive:
add_filter( 'preprocess_comment', 'shameem_comment_post', 1 );
add_filter( 'comment_text', 'shameem_comment_display', 1 );
add_filter( 'comment_text_rss', 'shameem_comment_display', 1 );
add_filter( 'comment_excerpt', 'shameem_comment_display', 1 );
function shameem_comment_post( $incoming_comment ) {
$incoming_comment['comment_content'] = htmlspecialchars( $incoming_comment['comment_content'] );
$incoming_comment['comment_content'] = str_replace( "'", ''', $incoming_comment['comment_content'] );
return $incoming_comment;
}
function shameem_comment_display( $comment_to_display ) {
return str_replace( ''', "'", $comment_to_display );
}
The incoming filter escapes every comment as it’s saved. The display filter converts the single-quote placeholder back on output. Inline links stop working, which is the point.
Remove the URL field from the comment form
The URL field in the default comment form is the main thing bots are after, it gives them a clickable link back to their site. Remove it and most of the automated spam stops bothering:
add_filter( 'comment_form_default_fields', 'shameem_remove_url_field' );
function shameem_remove_url_field( $fields ) {
if ( isset( $fields['url'] ) ) {
unset( $fields['url'] );
}
return $fields;
}
Real commenters almost never miss this field. You can’t imagine how often they would’ve left a URL if the box had been there, because they almost never notice it’s gone.
Block off-site comment requests
A lot of comment spam doesn’t come through your actual comment form. Bots POST directly to wp-comments-post.php from their own scripts. You can block that at the .htaccess level by requiring the request to come from your own domain:
RewriteEngine On
RewriteCond %{REQUEST_METHOD} POST
RewriteCond %{REQUEST_URI} .wp-comments-post\.php*
RewriteCond %{HTTP_REFERER} !.*yourblog\.com.* [OR]
RewriteCond %{HTTP_USER_AGENT} ^$
RewriteRule (.*) ^http://%{REMOTE_ADDR}/$ [R=301,L]
Replace yourblog.com with your own domain. This bounces any POST to the comment endpoint that either doesn’t have a referrer header or has one from somewhere other than your site. It won’t catch a bot that forges headers correctly, but it catches the cheap ones, and the cheap ones are most of them.
Always take a backup before editing .htaccess. A typo in this file will break the whole site.
Block specific IPs when one bot gets aggressive
Every so often a single IP or small range will hammer you repeatedly. You can block specific IPs straight from Settings → Discussion → Disallowed Comment Keys (just paste the IP), or from .htaccess if you want to block all traffic, not just comments:
Order allow,deny
Deny from 88.136.129.110
Allow from all
Don’t over-invest in this. IPs rotate, ranges change, and if you’re getting enough traffic from a single IP that you need to block it at the server level, a WAF (Cloudflare, Sucuri) is a better tool than .htaccess.
Plugins, only if you need more
If Akismet plus the settings above plus the filters still leaves you with too much spam, the anti-spam plugins I’ve actually seen hold up over time are:
- Antispam Bee: free, no external API, light footprint.
- Anti-Spam by CleanTalk: paid API, very low false-positive rate.
- WPBruiser: invisible, no CAPTCHA shown to users.
Stack one of these on top of Akismet only if you actually need it. Most blogs won’t.
Spam comments are an arms race. You won’t hit zero, but you can get it down to where you’re checking the Spam queue once a week out of habit and not because you have to.
Join the Conversation
Have thoughts, questions, or a different take? I'd love to hear from you.
Powered by Giscus · Sign in with GitHub to comment. · Privacy policy