How a link gets checked politely
Checking external links means pointing a robot at several hundred other people’s servers every week. Doing that carelessly gets you blocked, which breaks the checker, and it is also just rude. This post is about doing it properly, and about the status codes that lie.
Key takeaways
- One request per unique URL per run, with the result shared by every page linking to it.
- HEAD first, GET only if HEAD is refused. Many servers dislike HEAD.
- Rate limit per host, not globally. One slow host must not stall the run.
- 403 and 429 usually mean ’not to a robot’, not ’broken’.
- A soft 404 — a 200 that says the page is gone — needs its own check.
The request
- Database
- App integration
- Machine learning
- Networking
- Management
- Analytics
Rate limiting per host
A global rate limit is the obvious implementation and it has the wrong shape: it either hammers a single small host that happens to be linked forty times, or it slows the whole run to the speed of the slowest server.
Per-host limits — say one request a second to any single host, with several hosts in flight — solve both. It also means one unresponsive server delays only its own links, and a timeout budget per host keeps a dead domain from consuming the run.
Status codes that lie
| Code | Looks like | Usually means |
|---|---|---|
| 403 | Forbidden | The server does not serve robots. Not broken. |
| 429 | Too many requests | You went too fast. Back off and retry. |
| 405 | Method not allowed | HEAD is refused. Try GET. |
| 999 | Nonsense | One large social network’s way of saying no. Not broken. |
| 503 | Unavailable | Often temporary, sometimes a bot wall. Retry next run. |
| 200 | Fine | Sometimes a soft 404. Check the content. |
The first four are the reason a naive checker produces a report full of links that are perfectly fine. A 403 from a site that blocks automated requests is not a broken link and reporting it teaches whoever reads the report that the report is wrong.
So those codes are recorded as unverifiable rather than broken. They appear in a separate short section of the report, once, with an explanation — because a person checking one by hand is a perfectly reasonable resolution and telling them twenty times is not.
Soft 404s
A page that returns 200 and says “this page no longer exists” is broken in every way that matters to a reader and invisible to a status check. They are common on sites that have been migrated, where the new platform serves a friendly page instead of a 404.
- Machine learning
- Management
- Analytics
Checking for soft 404s means fetching the body rather than just a HEAD, which costs more. So it is done only for external links that have redirected, and for internal links always — where it is cheap and where a migrated site is most likely to have them.
Next: the three-run rule, which is what keeps the report short.
All posts