Skip to content

Case study

When the website was up and the business had stopped.

A UK recruitment firm placing candidates across the charity and not-for-profit sector. A WordPress site with a live job board integrated into their applicant tracking system. March to September 2026, ongoing.

38 min Report to diagnosis 09:57 to 10:35
15:01 Stable, same day No data loss
18 Cloudflare tasks Around fifteen hours
~30,000 Crawler visits a month Measured, then acted on

Anonymized at this stage. We have not asked for attribution yet and will not publish the client’s name without it.

01 · The morning it started

The site was not down. That was the small problem.

09:57

The client reports the website is down

It was not. Overnight, while mitigating unusual traffic, we had blocked a range of IP addresses generating abnormal request volumes. One of those blocks had caught the client own office.

10:35

Confirmed and unblocked

Thirty-eight minutes to establish that, confirm the IP, and unblock it. The site was still slow, and slow looked like the whole story for about half an hour.

11:12

The real failure surfaces

The connection to the applicant tracking system had dropped and stopped syncing. The public site was still loading. Job listings still displayed. Application forms still rendered. But no new roles could be published and no applications could be actioned. Every consultant in the firm was blocked, and nothing visible on the website suggested anything was wrong.

15:01

Site stable, same business day

The cause was bot-driven DDoS and brute force traffic consuming the server resource allocation.

09:36

Next morning, confirmed

Site speed back to normal, ATS sync working. No candidate or client data was compromised. Applications submitted during the incident had been captured locally throughout and synced once the load dropped.

The client’s own summary: it “stops business.”

02 · What was happening

The order the server shed work in is the entire story.

The site was on a host where autoscaling had been deliberately switched off, a reasonable decision taken to avoid an uncapped bill during exactly this kind of event.

The consequence was that the server hit a hard resource ceiling instead of scaling, and when it did, it started shedding work. It kept the public-facing pages alive and dropped the third-party API calls first.

So the symptom everyone could see, a slow website, was the least important thing happening. The symptom nobody could see, the ATS sync silently failing, was the one costing money.

03 · The decision

Autoscaling was the faster fix and the wrong one.

Two options were on the table within hours: turn autoscaling back on, or put a security layer in front of the site.

Turning it back on meant choosing, permanently, between a potential four-figure bill during an attack and a hard ceiling that takes the ATS down. Neither is a position a business should have to hold.

The recommendation was to migrate hosting and deploy Cloudflare Pro properly, as one piece of work. The honest framing given to the client CEO was that this was a one-off cost covering migration, firewall integration and a set of rules that would let us act quickly during the next attack, because there would be a next attack.

Twelve days later the client own team flagged a fresh wave of bot registrations, the same pattern seen in the weeks before the original incident. That validated the decision to harden rather than stop at the site is stable.

04 · The work

Migration, then Cloudflare, then the things nobody expected.

01

Hosting migration

Traffic history pulled first: peak around 120,000 monthly visits, typical range 60,000 to 70,000. The plan was sized against the peak rather than the average.

Every DNS record inventoried before anything moved, including the MX and TXT records that break email rather than websites when they go wrong. Registrar credentials handled properly: password changed before being shared, changed again afterwards to revoke access.

The old environment was kept live and functional throughout, so if the new one had behaved unexpectedly the domain could point back and the site would be exactly as it was. The migration ran in a defined 90-minute window outside peak hours. That is our standard hosting migration process.

02

Cloudflare Pro deployment

Around fifteen hours across eighteen discrete tasks: DNS transfer, SSL set to Full (Strict) with TLS 1.2 minimum and HSTS, Cloudflare and OWASP managed rulesets with a false positive pass before anything moved from log to block, rate limiting on login, admin and API endpoints, custom rules covering malicious and empty user agents, sensitive file extensions, XML-RPC and suspicious URI patterns, geographic policy, cache rules with explicit bypasses, security headers, image optimization, a firewall analytics baseline, and full functional testing. The full task list is on the Cloudflare setup page.

03

The caching problem nobody expected

Within a week of the new infrastructure going live, candidates started reporting that job applications were failing with a security token error. The baseline was one or two reports every few months. It became six candidates over a single weekend, then more each day. The client could not reproduce it. Neither could we, initially, because we were testing logged in and caching layers serve logged-in users fresh pages.

The cause was full-page caching serving the same one-time form token to every visitor. Cache disabled on job pages at the CDN, and reports dropped sharply. Still not zero: investigation with the host revealed a second, server-level page cache, not visible anywhere in the WordPress admin. Disabled on job pages too. The next morning, no reports. A week later, one from the registration page instead. Same fix applied there, at both layers.

One isolated case remained afterwards, which turned out to be a genuinely expired token from a form left open for hours. That is WordPress security working correctly and there is no configuration that removes it. We escalated to the plugin vendor to ask whether the error message could at least be made comprehensible to a candidate, and were explicit that we would not accept a workaround that weakened the token.

04

The bill that would not stop growing

By summer, a different problem. The hosting plan monthly visit allowance was being exceeded every month, and the overage was being paid every month. The obvious response was to upgrade the plan. Before doing that, we measured what was consuming the allowance.

AI crawlers accounted for roughly 7,000 hits over seven days. Extrapolated, around 30,000 visits a month, billed against a plan priced by visit count, none of them a potential candidate or client.

The client asked directly whether increasing bot protection would help. The answer was no: a blanket increase catches search engine crawlers along with everything else, and for a job board, search visibility is how candidates arrive. Instead we identified the specific crawlers, presented the list with what blocking each one would cost, got written approval, then blocked by name. Two aggressive regional crawlers with no audience overlap with a UK recruitment business, and one SEO tool crawler that was repeatedly requesting pages that did not exist. That approach became our bot and AI crawler control service.

RuleSearch engines and the AI assistants that send referral traffic stayed fully accessible.

05

The finding that invalidated the rest

The blocks went in. The traffic barely moved. The reason was DNS: not all traffic was routing through Cloudflare, so a portion of requests were reaching the origin server without passing through a single security rule. Every rule written over the preceding months was working perfectly on the traffic it could see, which was not all of it.

The DNS change was scheduled with the client, then moved back a day at their request so more of their team would be in the office to test. It ran at 05:56 to minimize disruption. By 09:29 the same morning the client confirmed the site was fine from the office and, critically, that new roles were still pulling through from the ATS. Under four hours from cutover to verified, with no reported issues.

RuleThis is the step that gets skipped, and it silently invalidates everything upstream of it.

05 · The SLA

The document that came out of a question.

Buried in the original project scope was a one-hour line item: write emergency response procedures. The client took it seriously and pushed back when the first version was not good enough. What they wanted was not a list of Cloudflare settings but a procedure.

Then a harder question. What happens if you are not available? On holiday? What do your other clients do? The honest answer at the time was that no such process existed. That was said in writing, along with a commitment to build one properly. It took about two months.

Priorities

Written against this business

A failed ATS connection is a critical incident even though the website is up, because in recruitment it stops operations.

Protocol

One monitored channel

With a subject line convention so a critical incident is visible in an inbox rather than sitting between two newsletters. Explicitly not phone, text or messaging apps, because a partially monitored channel creates false confidence.

Response

Times by priority and time of day

Including weekends and bank holidays, stated as time to acknowledgement rather than time to resolution.

Escalation

On both sides

Up to CEO level on the client side, plus an honest last-resort route to another qualified developer for the scenario where nobody on our side is reachable.

Runbook

Step by step, screen by screen

Enable Under Attack mode, verify it in a private browser window, identify the source in security analytics, block by IP or by country. Written for a marketing manager, not a developer. The client was asked to rehearse the first step once while nothing was wrong.

Limits

Stated, not discovered

Third-party platform failures, server uptime and requests sent outside the protocol are explicitly outside the guarantee.

The client edited the document directly and it was signed off as jointly owned. That was the right outcome. An SLA one party wrote alone is one the other party will not follow. The structure is now what we deliver as emergency DDoS response.

06 · Where it stands

The relationship continued past the security work.

Into an ongoing maintenance retainer, and into the next piece: a full audit of what the site is collecting about candidates, which turned up fourteen separate tracking and third-party components firing before anyone had consented to anything, on pages where candidates upload their CVs.

That is a different case study. Everything above is available as our WordPress security service.

07 · Honestly

What we would say about this honestly.

What went well

Contained same day, correct root cause

No data loss. The root cause was correctly identified as resource exhaustion rather than a breach, which meant the right fix was implemented rather than a panic response. The bot analysis saved a hosting upgrade that would have been permanent and would not have addressed the cause. The DNS finding caught something that would otherwise have quietly undermined months of work.

What we would do differently

The two-week traffic review was never completed

Which means the before-and-after numbers that would prove the commercial impact are still sitting in two dashboards, unclaimed. That is an unforced error. A measurement that is not reported back is a measurement that did not happen.

What we cannot claim

That this site will not be attacked again

It will. What changed is that the next time it happens, there is a measured response instead of an improvised one, and the client own team can act in the first five minutes.

The work on this page is delivered as four separate services: Cloudflare setup, bot and AI crawler control, emergency DDoS response and hosting migration, with the ongoing relationship running through maintenance.

Keep reading

If any of this sounds familiar.

Twenty minutes with Ali. We will tell you whether what you are seeing is the same pattern, and what we would check first.

Book a scoping call
Ali Demirci
Ali Demirci
Founder
Is the site slow, or is it shedding work
Two very different problems.
Is anything monitored besides uptime
Usually not the integration.
What we would do in week one
Measurement before configuration.