User Guide
How to install, configure, and use Login Delay Shield on your WordPress site.
Getting Started
Login Delay Shield is available on WordPress.org. It requires zero configuration — activate and it works immediately:
- In your WordPress admin, go to Plugins → Add New and search for “Login Delay Shield”.
- Click Install Now, then Activate.
- That’s it. Failed login attempts are now delayed by 1 second automatically.
For fine-tuning, navigate to Settings → Login Delay Shield. The settings page shows a protection summary at the top with a count of enabled features (out of 8), followed by collapsible sections for each feature area.
Delay Settings
The delay is applied only to failed login attempts — successful logins are always instant.
Fixed Delay
Set a fixed number of seconds (0–10) added after every failed login attempt. The default is 1 second. Even a 1-second delay is barely noticeable to legitimate users but makes brute-force attacks impractical (1 second × 10,000 attempts = nearly 3 hours).
Random Delay
Instead of a fixed value, use a random delay within a configurable range (e.g., 1–5 seconds). This prevents attackers from using timing analysis to detect the exact delay value.
| Setting | Default | Range |
|---|---|---|
| Fixed delay | 1 second | 0–10 seconds |
| Random delay (min) | 1 second | 1–10 seconds |
| Random delay (max) | 5 seconds | 1–10 seconds |
Progressive Delay
When enabled, the delay increases with each consecutive failed attempt from the same IP address. The formula adds the increment value for each failure until the maximum is reached.
For example, with a 1-second base delay, 1-second increment, and 30-second max:
| Attempt | Additional delay | Total delay |
|---|---|---|
| 1st failure | +1s | 1s |
| 2nd failure | +2s | 2s |
| 3rd failure | +3s | 3s |
| 10th failure | +10s | 10s |
| 30th+ failure | +30s (capped) | 30s |
Delays reset to zero after a successful login or after 1 hour of no failed attempts from that IP.
| Setting | Default | Range |
|---|---|---|
| Increment per attempt | 1 second | 1–10 seconds |
| Maximum delay | 30 seconds | 5–60 seconds |
IP Lockout
After a configurable number of failed attempts, the IP address (or IP + username pair) is temporarily blocked from logging in. During lockout, the login form shows a countdown message indicating when the user can try again.
| Setting | Default | Range |
|---|---|---|
| Failed attempts before lockout | 10 | 1–100 |
| Lockout duration | 60 minutes | 1–1,440 minutes (24h) |
| Tracking strategy | IP only | IP only / IP + username |
| Trust proxy headers | Off | On / Off |
Trust proxy headers — Enable this only if your server is behind a reverse proxy (Cloudflare, nginx, AWS ELB). When off, the plugin uses REMOTE_ADDR exclusively, which prevents IP spoofing.
See Lockout Strategy below for details on IP only vs. IP + username tracking.
IP Whitelist
Add trusted IP addresses that bypass all delays and lockouts. Useful for office networks, VPN endpoints, or development servers.
Supported formats (one per line):
- Single IPv4 —
192.168.1.100 - Single IPv6 —
2001:db8::1 - IPv4 CIDR range —
192.168.1.0/24(covers 192.168.1.0–255) - IPv6 CIDR range —
2001:db8::/32
Whitelisted IPs bypass all security measures: delays, progressive delay, lockout, and email tracking.
Email Notifications
Get email alerts when failed login attempts cross a threshold. The plugin tracks failures per IP address and notifies you when the count is reached.
| Setting | Default | Range |
|---|---|---|
| Failed attempts before notification | 5 | 1–100 |
| Notification email address | Site admin email | Any valid email |
| Email cooldown | 5 minutes | 0–60 minutes |
The email includes the IP address, username attempted, number of failed attempts, and timestamp. The cooldown prevents inbox flooding during distributed attacks. During the cooldown period, only one email is sent site-wide, regardless of how many IPs trigger the threshold.
Set cooldown to 0 to disable rate-limiting (one email per threshold event).
XML-RPC Protection
xmlrpc.php is a common brute-force target. There are two levels of XML-RPC protection:
- Apply delays — XML-RPC authentication failures receive the same delay and lockout treatment as wp-login.
- Block entirely — All XML-RPC authentication is blocked immediately, returning an error to the caller.
If you use the WordPress mobile app, Jetpack, or remote publishing tools, use “apply delays” mode. If you don’t use any of these, blocking XML-RPC removes the attack surface entirely.
REST & App Password Protection
Beyond wp-login and XML-RPC, WordPress has two more authentication surfaces: the REST API and application passwords.
REST API Protection
When enabled, failed REST API authentication attempts receive the same delay, progressive delay, and lockout treatment as wp-login. This covers any third-party integration or headless frontend that authenticates via the REST API.
Application Password Protection
WordPress 5.6 introduced application passwords for authenticating external apps via HTTP Basic Auth. When this toggle is enabled, failed application-password attempts are tracked and subject to delays and lockout.
| Setting | Default | Description |
|---|---|---|
| REST API protection | On | Apply delays and lockout to REST API authentication failures |
| Application password protection | On | Apply delays and lockout to application-password authentication failures |
Both settings are enabled by default. Disable them only if you have another plugin handling rate-limiting for these authentication methods, or if a specific integration is being falsely throttled.
Login Log
All failed login attempts are logged to the database with the timestamp, username attempted, IP address, and source. The source indicates where the attempt came from: wp-login, xmlrpc, rest, or application-password. Logs are used by the dashboard widget and can be filtered and exported.
| Setting | Default | Range |
|---|---|---|
| Log retention | 30 days | 0–365 days |
Old entries are automatically cleaned up by a daily cron job. Set retention to 0 to keep logs indefinitely. Cleanup runs in batches of 1,000 rows to avoid database locks on large tables.
Custom Login URL
Hide your WordPress login page by replacing /wp-login.php with a custom URL slug (e.g., /my-login). This reduces automated bot traffic targeting the default login URL.
| Setting | Default | Description |
|---|---|---|
| Enable custom login URL | Off | Replace wp-login.php with a custom slug |
| Login slug | my-login | Lowercase letters, numbers, and hyphens only |
When enabled, login, logout, lost password, and password reset all route through the custom URL. Visiting /wp-login.php directly returns a 404. Reserved slugs (wp-admin, login, wp-json, wp-content, wp-includes, xmlrpc, feed, robots, sitemap, etc.) are automatically rejected.
Important: After enabling or changing the slug, visit Settings → Permalinks and click Save Changes to flush rewrite rules. Bookmark the new login URL so you don’t lose access.
Login Feedback
When lockout is enabled, the login screen shows two extra messages:
- Remaining attempts — After a failed login, the error message includes how many attempts remain before lockout (e.g., “Login failed. 3 attempts remaining before temporary lockout.”).
- Lockout countdown — When locked out, the message shows when the lockout expires (e.g., “Too many failed login attempts. Please try again in 2 minutes.”).
Messages are kept generic to avoid leaking information about whether a username exists.
Trend Analytics
The settings page includes a 7-day trends panel that gives you a quick overview of recent attack activity:
- Daily totals — Failed login attempts per day for the last 7 days
- Top IPs — The IP addresses with the most failed attempts
- Top usernames — The most targeted usernames
Trends are computed from the login log database table, so they reflect the same data as the log filters and CSV export. If log retention is set to fewer than 7 days, the trends panel will show data only for available days.
Dashboard Widget
A widget on the WordPress dashboard shows the 10 most recent failed login attempts, including:
- Time of the attempt (relative, e.g., “5 minutes ago”)
- Username attempted
- IP address
- Source (wp-login, XML-RPC, REST API, or application-password)
The widget data is cached for 2 minutes to minimize database queries. A link at the bottom takes you to the settings page.
Log Filters & Export
The settings page includes tools for investigating and exporting your failed login log.
Filtering
Filter log entries by any combination of:
- Source — wp-login, xmlrpc, rest, or application-password
- IP address — show attempts from a specific IP
- Username — show attempts targeting a specific username
- Date range — from/to dates to narrow results to a time window
Filters apply to both the log view and CSV export. Clear all filters to return to the full log.
CSV Export
Click “Export CSV” to download the log as a CSV file. Each row contains the source, IP address, username, and timestamp. If filters are active, only matching entries are exported.
The export streams in batches so it works reliably even with very large logs (100,000+ entries) without running into memory limits. Cell values are sanitized to prevent spreadsheet formula injection.
Lockout Strategy
Choose how failed attempts are tracked for lockout and progressive delay:
IP Only (default)
One counter per IP address. All failed attempts from the same IP count together, regardless of which username was tried. Simple and effective for most sites.
IP + Username
Separate counters for each IP + username pair. If someone tries “admin” 10 times and “editor” 10 times from the same IP, each username has its own counter. This reduces false positives on shared networks (offices, mobile carriers, coworking spaces) where multiple legitimate users share an IP.
Recommendation: Use “IP + username” if your site has users on shared networks. Use “IP only” for single-user sites or when you want the strictest protection.
Lockout Recovery
If you or a legitimate user gets locked out, Login Delay Shield provides two ways to recover without deactivating the plugin:
Admin Unlock Button
On the settings page, the IP Lockout section includes an “Unlock Current IP” button. Clicking it immediately removes the lockout and resets the failure counter for your current IP address. This is useful when testing lockout settings or recovering from accidental lockouts.
WP-CLI Commands
If you cannot access the admin, use WP-CLI from the server command line:
# Unlock a specific IP address
wp login-delay-shield unlock-ip 203.0.113.42
# Clear all lockouts site-wide
wp login-delay-shield flush-lockouts
See WP-CLI below for full command details.
2FA Health Check
The settings page checks whether a two-factor authentication plugin is active. If one is found, the notice says which one. If not, it recommends installing one.
These 2FA plugins are recognized by default:
- Two Factor
- WP 2FA
- miniOrange 2-Factor Authentication
- Google Authenticator
If you use a different 2FA plugin, developers can register it through the wldelay_2fa_providers filter — see the developer reference for details.
This check is informational only. Login Delay Shield works independently of any 2FA plugin.
Object Cache Notice
When no persistent object cache is active (Redis, Memcached, etc.), the settings page shows a notice about it. Failure counters and lockout state live in WordPress transients, which fall back to the database without an object cache. On sites with heavy login traffic, that means extra database queries on every failed attempt.
Most managed WordPress hosts already include object caching. If you manage your own server, see the Performance section for recommended plugins.
WP-CLI
Login Delay Shield registers two WP-CLI commands for managing lockouts from the command line.
wp login-delay-shield unlock-ip <ip>
Removes the lockout and failure counter for a specific IP address. Validates the IP format before processing.
$ wp login-delay-shield unlock-ip 203.0.113.42
Success: Removed 2 entries for IP 203.0.113.42.
wp login-delay-shield flush-lockouts
Clears all lockouts and failure counters site-wide. Useful after a mass brute-force event or when resetting the plugin state.
$ wp login-delay-shield flush-lockouts
Success: Flushed 14 lockout entries.
Performance
Login Delay Shield uses WordPress transients to track failed attempts and lockout state. By default, transients are stored in the database.
For busy sites or sites under frequent attack, adding a persistent object cache (Redis, Memcached) cuts database load:
- Transient reads/writes go to memory instead of the database
- Reduces database queries from ~6 per failed attempt to ~2
- Most managed WordPress hosts (WP Engine, Kinsta, Flywheel) include object caching by default
Popular object cache plugins: Redis Object Cache, W3 Total Cache, LiteSpeed Cache.
Languages
Login Delay Shield is translated into 18 languages. The plugin automatically uses your site’s language setting.
- Arabic (العربية)
- Chinese Simplified (简体中文)
- Czech (Čeština)
- Dutch (Nederlands)
- French (Français)
- German (Deutsch)
- Indonesian (Bahasa Indonesia)
- Italian (Italiano)
- Japanese (日本語)
- Korean (한국어)
- Polish (Polski)
- Portuguese – Brazil (Português do Brasil)
- Russian (Русский)
- Spanish (Español)
- Swedish (Svenska)
- Thai (ไทย)
- Turkish (Türkçe)
- Vietnamese (Tiếng Việt)
Want to help translate? Visit translate.wordpress.org.
FAQ
What versions of WordPress and PHP are supported?
Login Delay Shield supports WordPress 3.5.1+ and PHP 7.4+. It has been tested up to WordPress 6.9 and works with PHP 8.x.
Will Login Delay Shield conflict with other security plugins?
Login Delay Shield uses standard WordPress hooks for login authentication. It is compatible with most security plugins. If another plugin also adds login delays or lockouts, you may want to disable one to avoid double-delays.
What happens if I lock myself out?
Use the “Unlock Current IP” button on the settings page, or run wp login-delay-shield unlock-ip <your-ip> via WP-CLI. You can also wait for the lockout to expire (default: 60 minutes), or whitelist your IP in advance. As a last resort, deactivate the plugin by renaming its folder in wp-content/plugins/ via FTP/SSH.
Does the delay affect successful logins?
No. Delays are applied only to failed login attempts. Successful logins are always instant.
Should I block XML-RPC?
If you don’t use the WordPress mobile app, Jetpack, or remote publishing tools (like Windows Live Writer), blocking XML-RPC authentication removes a common attack vector. Otherwise, use “apply delays” mode for protection without breaking functionality.
Is the admin interface accessible?
Yes. Login Delay Shield follows WCAG 2.1 Level AA guidelines. All settings are keyboard navigable, screen reader compatible, and include proper ARIA attributes. Collapsible sections toggle with Enter or Space keys, and tooltips appear on both hover and keyboard focus.
Where can I see failed login attempts?
A dashboard widget shows the 10 most recent failed login attempts, including the time, username attempted, IP address, and source. On the settings page you can filter the full log by source, IP, username, or date range, and export the results as a CSV file.