A scan that knocks your checkout offline at 2 p.m. on a Tuesday does more damage than the vulnerabilities it was meant to find. Anyone running automated security testing against production has to settle on a scan scheduling strategy that covers enough of the site without straining the server. This article explains how scan scheduling affects coverage and server load, how to estimate the real cost of a scan, and how to build a schedule that holds up as the site grows.
What a Security Scan Actually Costs the Server
A passive check is cheap. Reading TLS configuration, security headers, DNS records and cookie flags takes a few dozen requests, and no hosting plan will notice them.
Active testing is where the load comes from. To test for SQL injection, XSS, SSRF and email injection, a scanner sends many payload variations to every parameter it finds. A site with 400 crawlable URLs and an average of six parameters per page can easily produce 15,000-40,000 requests in one active pass. The phases of an automated security scan each load the server differently. The crawl is light, the injection phase is heavy and fingerprinting falls somewhere in between.
Request count is only part of the cost. What hurts is which requests get sent. A search endpoint that runs an uncached full-text query, a WooCommerce cart endpoint that bypasses page caching, or a GraphQL resolver that fans out into 30 database calls can each cost 50-200 times as much as a cached static page. An experienced AppSec engineer starts by finding these expensive endpoints before setting any scan schedule.
The Myth That Scans Should Only Run at 3 a.m.
A common assumption is that the safest time to scan is the middle of the night. That isn’t always true.
Night-time scans often collide with the heavy jobs a server already runs on schedule. These include database backups, WP-Cron batches, log rotation, search index rebuilds and nightly ERP or PIM imports into the store. When a backup with mysqldump locks tables and the scanner sends thousands of requests at the same moment, the result can be worse than at midday. The night window also tends to have nobody on call when something breaks.
Audience matters too. For a Finnish online store whose customers are in Helsinki, 3 a.m. is genuinely quiet. For a SaaS service with customers in Europe and North America, 3 a.m. UTC is evening on the US West Coast. The right time comes from the access logs, not the clock. Look at the 24-hour request distribution over the past 30 days and pick the window with the least real traffic and the fewest scheduled jobs.
Balancing Coverage and Load in Practice
Coverage and load are not a straight trade-off. The goal is to spread the load over time instead of cutting tests out. A layered model works well in practice:
Daily: light checks such as certificates, security headers, malware signatures, changes to known files, and subdomain DNS records.
Daily or every other day: active tests on a rotating subset of URLs, for example 1/7 of the attack surface per day.
Weekly: a full active pass across all forms, API endpoints and parameters.
After every release: a targeted scan of the changed routes.
Quarterly: manual penetration testing for business logic, which automated tools miss anyway.
With rotation, every URL still gets tested within a week, but the daily peak is about 85% lower than a full daily pass. The right scan frequency also depends on how often the site changes. A brochure site updated four times a year has different needs from a store whose plugins update every week.
Rate limiting is the second lever. OWASP ZAP’s active scan has settings for threads per host and a delay between requests. In Burp Suite Professional, resource pools control concurrent requests. Nuclei has a -rate-limit flag with a default of 150 requests per second, which is far too aggressive for a small shared hosting plan. On a typical WordPress site on a 2 vCPU VPS, 5-10 requests per second with 2-4 concurrent connections is a safe starting point. Measure from there.
Step by Step: Building a Load-Aware Schedule
A seasoned security auditor goes through roughly this order:
First, gather a baseline. Pull 30 days of p95 response times and CPU usage from your APM tool, such as New Relic, Datadog or the hosting provider’s own dashboard. Without a baseline you can’t tell whether a slowdown came from the scan or from normal fluctuation.
Second, map the scheduled jobs. Check the crontab, WP-Cron events (WP Crontrol shows them), backup timing and any CDN purges. Mark them on the same 24-hour chart as your traffic.
Third, run one test scan at a low rate in a staging environment or in the quietest production window, and watch the server metrics live. If p95 rises more than 30-50% above the baseline, lower concurrency before raising the rate.
Fourth, coordinate with the WAF. Cloudflare, Sucuri or ModSecurity with the OWASP Core Rule Set will block scanner traffic or, worse, partly block it. A partial block gives misleadingly clean results. Allowlist the scanner’s IP addresses for a limited scope only, and document it.
Fifth, set up an alert for when the scan exceeds the load budget, and review the schedule every quarter or whenever the infrastructure changes.
Common Mistakes in Scan Timing
The first common mistake is using the same settings everywhere. A profile tuned for an AWS environment behind an auto-scaling group gets copied to a customer’s shared hosting plan, where 20 concurrent connections fill PHP-FPM’s worker pool within seconds. The site returns 503 errors, and the hosting provider may suspend the account for suspected abuse.
The second is reading a clean report without checking whether the scan actually ran. If the WAF or a rate limiter returned 429 or 403 responses to half the requests, the scanner logged them as “no finding”. The report looks good while coverage was poor. Response code distributions should be checked whenever the totals change suspiciously. The same mechanism that protects an API, rate limiting on API endpoints, also quietly limits what the scanner sees.
The third is only reacting after an incident. The schedule gets tightened after a breach and loosened again once the site slows down a few weeks later. A schedule has to be designed so it can stay in place permanently.
When the Standard Advice Doesn’t Apply
Some environments need exceptions. In regulated industries such as finance and healthcare, scanning production can require a change management process and notice to a named contact, so the schedule has to be agreed in advance. For PCI DSS, quarterly ASV scans are a separate requirement and do not replace daily monitoring.
Teams of fewer than ten people often have no staging environment that matches production. In that case, gentle daily scanning of production plus a heavier weekly pass is more realistic than an ideal model nobody maintains. Air-gapped or on-premises systems need an internal scanner, and only the public interface can be tested from outside.
Serverless and auto-scaling infrastructure turns the problem around. Load doesn’t cause outages, but it does create costs. A Lambda-based API that scales automatically under 40,000 requests can produce an unexpected invoice.
FAQ
Can a security scan crash a website?
Yes, if concurrency is set too high for the server’s capacity. Small shared hosting plans and sites with heavy, uncached endpoints are the most vulnerable. A low request rate and testing first in a quiet window almost always prevent it.
How often should a full active scan be run?
For most sites, a weekly full pass combined with daily light checks and rotating active tests gives good coverage. Sites with frequent releases should also run a targeted scan after each deployment.
Should the scanner be allowlisted in the WAF?
Partly. Without an allowlist, results become distorted. With a full allowlist, you are no longer testing the protection users actually rely on. A good compromise is to allowlist the scanner’s IP addresses only for specific paths and time windows, and to run a separate test with the WAF active occasionally.
Summary: Spread the Load, Not the Gaps
Good scan scheduling is based on measurement, not habit. Find the expensive endpoints, pick the time window from real traffic data, rotate active tests across the week and tune concurrency to what the server can handle. Check the response code distribution in every report so a clean result really means a clean site. A schedule that the server tolerates and the team trusts will still be running a year from now.
