Guides /Security
Security

How to Limit Login Attempts in WordPress (And Why You Should)

September 2, 20257 min readHostBible Team

WordPress allows unlimited login attempts by default. An automated attack can try thousands of password combinations per minute without triggering any defence. Limiting login attempts converts an unlimited attack surface into a rate-limited one. It takes five minutes to configure and meaningfully reduces brute-force risk even on sites with imperfect password hygiene.

The risk without limits

Brute force attacks against WordPress use two main approaches. Dictionary attacks try common passwords (password123, the site name, the business name, seasonal patterns like Summer2024!) against known usernames, these work at alarming rates against weak passwords. Credential stuffing uses real username/password pairs leaked from data breaches at other sites, effective against users who reuse passwords across services, regardless of how strong the password is.

Without rate limiting, a bot can make thousands of attempts before triggering any defence. If your password is reused from a breached service, credential stuffing will find it. If your password is weak, a dictionary attack will crack it. Beyond the security risk, unlimited login attempts consume server resources, PHP processes, MySQL connections, and memory. A sustained attack on your login page can slow or crash the site through resource exhaustion alone, even if the attack never succeeds.

Plugin: Limit Login Attempts Reloaded

This is the most widely installed solution with over 2 million active installations. Install from the WordPress plugin repository, then go to Settings > Limit Login Attempts for configuration. The key settings to configure:

  • Allowed Retries: Set to 4 or 5. This is the number of failed attempts before an IP is locked out. Lower values frustrate legitimate users who mistype their password; higher values give attackers more chances per cycle.
  • Lockout Period: 20 minutes is a reasonable balance. Long enough to meaningfully slow an attack (at 5 attempts per 20 minutes, an attacker can make 360 attempts per day, versus thousands per minute without limiting), short enough not to cause serious inconvenience if a legitimate user triggers it.
  • Allowed Lockouts: Set to 2 or 3. After this many consecutive lockout cycles, the IP moves to a long lockout.
  • Long Lockout Period: 24 hours. After repeated lockout cycles, the IP is blocked for a full day. This makes sustained attacks against a single site effectively impractical.
  • Trusted IP Origins: This setting determines how the plugin identifies the visitor's IP. On most shared hosting, use REMOTE_ADDR. If your site is behind Cloudflare, use HTTP_CF_CONNECTING_IP. If behind another reverse proxy, use HTTP_X_FORWARDED_FOR. An incorrect setting causes the plugin to block your CDN's IP rather than the attacker's, which can lock everyone out simultaneously.

Reading and acting on the lockout log

Go to Settings > Limit Login Attempts > Logs tab. This shows recent lockouts: the locked IP, number of attempts, what username was attempted, and the timestamp. Check this weekly in the first month after installation to understand the attack pattern against your site.

IPs that appear repeatedly, multiple lockout cycles over days or weeks, are persistent attackers. Add them to the plugin's IP blocklist manually via the "Blocklist" tab. If you see thousands of attempts from IP ranges in a specific country that has no legitimate reason to access your wp-admin, consider adding those ranges to a geographic IP block via Cloudflare or your server's firewall.

Pay attention to which usernames are being attempted. If you see "admin" being tried, this confirms you should change the admin username (if you haven't already). If the attacker is trying your actual username, they know something about your site, investigate how (public author bylines, email addresses exposed in source code).

Alternative: Wordfence login protection

If you're already running Wordfence Security, it includes brute force protection that overlaps with Limit Login Attempts Reloaded. Configure it at Wordfence > All Options > Brute Force Protection. Key settings: enable brute force protection, set lockout threshold (5 failures), lockout duration, and enable the option to immediately block IPs that try to log in with usernames known to not exist on your site (this catches a large volume of generic automated attacks that try "admin" even when no such user exists).

Don't run both Wordfence and Limit Login Attempts Reloaded simultaneously for brute force protection, pick one. They'll track lockouts separately and can cause confusion about which is actually blocking what. If you're running Wordfence for firewall and scanning, use its built-in login protection.

Server-level vs plugin-level rate limiting

Plugin-level limiting runs after PHP has already executed and WordPress has loaded. The server processes the full request, PHP initialises, WordPress loads, the plugin checks the IP, before blocking. This means a sustained high-volume attack still consumes significant server resources per blocked attempt.

Server-level or CDN-level rate limiting blocks excess requests before PHP executes. Cloudflare's WAF (free plan) allows creating rate-limiting rules: if a single IP sends more than 5 requests to /wp-login.php within 10 seconds, block it for 1 hour. Navigate to Cloudflare > Security > WAF > Rate Limiting Rules. Cloudflare absorbs the attack traffic at its edge, your server never sees blocked requests at all.

The strongest configuration is both: Cloudflare rate limiting to stop attacks before they reach the server, and a WordPress plugin as a fallback for requests that bypass Cloudflare (direct-to-origin requests or if Cloudflare is bypassed). Defence in depth means a single layer failing doesn't expose you completely.

Handling the REST API login endpoint

WordPress's REST API (/wp-json/) doesn't use wp-login.php, so attempts to authenticate via the API bypass plugin-level login limiting that only watches wp-login.php. Some attacks specifically target /wp-json/wp/v2/users to enumerate usernames, then attempt authentication via the API.

Wordfence's brute force protection covers REST API login attempts in addition to wp-login.php. If you're using Limit Login Attempts Reloaded, verify it's configured to monitor REST API attempts as well (check its settings for REST API coverage options). Alternatively, disable REST API user enumeration via a security plugin or the relevant setting in iThemes Security.

Testing that limiting is working

Test your setup by intentionally failing 5+ login attempts from a non-production environment. Use a browser in incognito mode or a different device and try a wrong password five times in a row. You should be shown a lockout message and subsequent attempts should be blocked immediately. After the lockout, check the plugin's log to confirm the attempt was recorded correctly. If no lockout occurred, check the Trusted IP Origins setting, the plugin may be misidentifying your IP.

Server-level protection on top of your plugin stack

HostBible's infrastructure blocks known malicious IPs at the network level before they reach your site. Plugin-level limiting handles everything else, giving you two layers of defence.

View Hosting Plans