Cloudflare Turnstile vs reCAPTCHA
Cloudflare Turnstile launched in September 2022 as a direct response to reCAPTCHA's privacy problem. Both services are free, invisible, and work with a script tag plus server-side token verification. The difference is who benefits from the data: Turnstile processes signals for security only, while reCAPTCHA feeds interaction data into Google's advertising infrastructure.
In 2026 this distinction matters more than it did three years ago. GDPR enforcement is stricter, consent fatigue is real, and developers face pressure to justify every third-party script on their pages. Here's what actually differs — technically and practically — so you can defend your choice.
Side-by-side comparison
| Feature | Cloudflare Turnstile | Google reCAPTCHA v3 |
|---|---|---|
| Developer | Cloudflare | |
| Launch year | 2022 | 2012 |
| User interaction | Invisible — automatic challenge | Invisible — score-based |
| Free tier | Yes — unlimited with Cloudflare account | Yes — rate limits apply |
| Data collection | Minimal — security use only, no ad targeting | Extensive — feeds Google ad network |
| GDPR / Privacy | No consent banner needed in most cases | Requires cookie consent in EU |
| PHP integration difficulty | Easy | Medium — threshold tuning required |
| False positive rate | Low for most sites | Requires threshold tuning |
| CDN dependency | Cloudflare CDN | Google CDN |
Cloudflare Turnstile
Turnstile runs entirely in the browser using IP reputation, browser fingerprint analysis, and JavaScript behaviour checks. No image puzzles, no audio challenges, no visible widget — unless Cloudflare's risk model triggers a brief interactive check, which is rare. Most users see nothing.
Privacy is the headline feature. Cloudflare is an infrastructure company — it charges for network services, not advertising. Turnstile data is used for bot detection only and never shared with ad platforms. Most EU legal teams can classify Turnstile as strictly necessary processing under a DPA, so no consent banner is needed for the CAPTCHA itself.
The free tier is genuinely free: unlimited verifications with a Cloudflare account, no credit card required. You get a site key and secret key from the Cloudflare dashboard, and you're done.
Front-end integration:
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>
<div class="cf-turnstile" data-sitekey="YOUR_SITE_KEY"></div>
Turnstile injects a hidden cf-turnstile-response field into the form on successful challenge. Your PHP reads that token and verifies it server-side:
<?php
function verifyTurnstile(string $token, string $secretKey, string $remoteIp = ''): bool
{
$data = ['secret' => $secretKey, 'response' => $token];
if ($remoteIp) {
$data['remoteip'] = $remoteIp;
}
$context = stream_context_create(['http' => [
'method' => 'POST',
'header' => 'Content-Type: application/x-www-form-urlencoded',
'content' => http_build_query($data),
]]);
$result = file_get_contents(
'https://challenges.cloudflare.com/turnstile/v0/siteverify',
false,
$context
);
$response = json_decode($result, true);
return $response['success'] ?? false;
}
// Usage
if (!verifyTurnstile($_POST['cf-turnstile-response'], 'YOUR_SECRET_KEY', $_SERVER['REMOTE_ADDR'])) {
http_response_code(403);
exit('Bot detected.');
}
Pros: fully invisible, privacy-respecting, no GDPR consent banner for most setups, generous free tier, pass/fail with no threshold tuning.
Cons: hard dependency on Cloudflare; newer dataset than Google's; Cloudflare outages block form submissions.
Google reCAPTCHA v3
reCAPTCHA v3 runs in the background on every page load and scores each interaction from 0.0 (almost certainly a bot) to 1.0 (almost certainly human). Your PHP receives the score and decides what to do — pass, block, or trigger a secondary check. More control, but you must tune a threshold and accept occasionally blocking real users or passing marginal bots depending on where you set it.
<?php
function verifyRecaptchaV3(string $token, string $secretKey, float $threshold = 0.5): bool
{
$url = 'https://www.google.com/recaptcha/api/siteverify?'
. http_build_query(['secret' => $secretKey, 'response' => $token]);
$result = file_get_contents($url);
$response = json_decode($result, true);
return ($response['success'] ?? false) && ($response['score'] ?? 0) >= $threshold;
}
if (!verifyRecaptchaV3($_POST['g-recaptcha-response'], 'YOUR_SECRET_KEY', 0.5)) {
exit('Bot detected or low confidence score.');
}
Google processes every page view through reCAPTCHA and uses that data as a signal in its broader user-profiling infrastructure. Not a conspiracy theory — it's documented in Google's terms of service, and it's why EU data protection authorities consistently require consent banners for reCAPTCHA. If you have EU users, you need a cookie consent banner.
On threshold tuning: 0.5 is a reasonable starting point. Security-sensitive forms (login, password reset, payment) can justify 0.7, but test against real traffic before deploying — too aggressive and you'll block real users. Log raw scores for a week before enforcing to calibrate.
Pros: industry-leading bot detection accuracy backed by Google's search, Gmail, YouTube, and Chrome datasets; 14 years of production use; widely documented.
Cons: data feeds Google's ad network; GDPR consent required in EU; score threshold needs ongoing tuning; privacy-focused browsers may block reCAPTCHA, causing silent failures.
GDPR and privacy in practice
The legal distinction is third-party cookies and data purpose. reCAPTCHA loads scripts from google.com and sets cookies in the .google.com domain. Under the EU's ePrivacy Directive, third-party cookies that contribute to user profiling require consent — even if the primary purpose is security. Multiple EU supervisory authorities have issued guidance specifically naming reCAPTCHA. In practice, nearly every EU-facing site using reCAPTCHA needs a consent banner that gates CAPTCHA loading, degrading UX.
Turnstile's data processing happens under the site owner's DPA with Cloudflare. Cloudflare's sub-processor agreements are structured around infrastructure services, not advertising. Most DPAs allow strictly functional processing (including bot detection) without end-user consent — no commercial profiling occurs. Turnstile-powered sites can load the challenge without a consent gate. You should still disclose it in your privacy policy, but the CAPTCHA itself typically doesn't need one.
Which is harder to bypass?
Honest answer: Google probably has a marginal accuracy edge. reCAPTCHA v3 draws signals from Google's full internet dataset — search behaviour, Gmail, YouTube watch history, Chrome usage patterns. That signal set is unmatched. Sophisticated bot operators who invest in behavioural evasion will find reCAPTCHA harder to fool.
Cloudflare handles over 20% of all internet traffic. Its network-level signals — IP reputation, autonomous system behaviour, global traffic patterns — carry real weight. For most PHP projects (contact forms, registration flows, comment systems, checkout pages), both services stop 99%+ of automated form spam. The difference only matters if adversaries are specifically targeting your site with human-like bot farms.
PHP migration from reCAPTCHA to Turnstile
Both services use the same token-passing pattern. Migration takes four steps:
Step 1: Create a free Cloudflare account at dash.cloudflare.com. Navigate to Turnstile, add your site, and copy the site key and secret key. You do not need to proxy your domain through Cloudflare.
Step 2: Replace the front-end script and widget.
Step 3: Update the server-side verification: change the endpoint URL, POST field name, and remove score threshold logic.
Step 4: Deploy and test with a real browser to confirm the hidden field submits correctly.
Before (reCAPTCHA v3):
<?php
$token = $_POST['g-recaptcha-response'];
$endpoint = 'https://www.google.com/recaptcha/api/siteverify';
$response = json_decode(file_get_contents(
$endpoint . '?' . http_build_query(['secret' => $secret, 'response' => $token])
), true);
$passed = ($response['success'] ?? false) && ($response['score'] ?? 0) >= 0.5;
After (Turnstile):
<?php
$token = $_POST['cf-turnstile-response'];
$endpoint = 'https://challenges.cloudflare.com/turnstile/v0/siteverify';
$context = stream_context_create(['http' => [
'method' => 'POST',
'header' => 'Content-Type: application/x-www-form-urlencoded',
'content' => http_build_query(['secret' => $secret, 'response' => $token]),
]]);
$response = json_decode(file_get_contents($endpoint, false, $context), true);
$passed = $response['success'] ?? false;
// No score threshold — Turnstile is pass/fail
Most developers finish this in under 30 minutes. See PHP Turnstile integration documentation for the full reference.
Related: CAPTCHA alternatives overview · reCAPTCHA vs hCaptcha · PHP Turnstile docs · PHP reCAPTCHA docs