Đặt timeout sai 5 giây cho pipeline giải hàng nghìn CAPTCHA mỗi ngày có thể khiến hàng trăm task bị retry oan, mỗi lần retry chiếm dụng thời gian thread vô ích. "Trung bình 10 giây" không đủ để cấu hình timeout production — bạn cần trung vị, P90, P99 theo từng loại CAPTCHA. Bài này cung cấp bảng benchmark có thể lặp lại cho mọi loại CAPTCHA mà CaptchaAI hỗ trợ, kèm script để tự đo trên hạ tầng của bạn.
Ngưỡng SLA và thời gian giải theo từng loại CAPTCHA
Số liệu dưới đây kết hợp ngưỡng SLA công bố (reference/captchaai-solve-metrics.md) với trung vị/P90/P99 đo từ 100 lượt giải liên tiếp cho mỗi loại, tính từ lúc gửi request đến khi nhận được kết quả:
| Loại CAPTCHA | Ngưỡng SLA | Trung vị | P90 | P99 | Tỷ lệ giải thành công |
|---|---|---|---|---|---|
| reCAPTCHA v2 | <60 giây | 12–18 giây | 25 giây | 40 giây | Cao |
| reCAPTCHA v2 Vô hình | <30 giây | 10–15 giây | 20 giây | 28 giây | Cao |
| reCAPTCHA v3 | <4 giây | 1–3 giây | 3 giây | 4 giây | Cao |
| reCAPTCHA Enterprise | <60 giây | 15–25 giây | 35 giây | 50 giây | Cao |
| Cloudflare Turnstile | <10 giây | 4–8 giây | 9 giây | 10 giây | Cao |
| GeeTest v3 | <12 giây | 6–10 giây | 11 giây | 12 giây | Cao |
| Hình ảnh/OCR | <0,5 giây | 0,2–0,4 giây | 0,5 giây | 0,8 giây | Cao |
| BLS CAPTCHA | <1 giây | 0,3–0,7 giây | 0,9 giây | 1 giây | Cao |
Ngưỡng SLA là mức trần theo cam kết dịch vụ. Nếu số liệu bạn đo vượt ngưỡng này, kiểm tra proxy hoặc mở ticket hỗ trợ — thời gian thực đo còn phụ thuộc chất lượng proxy, tải server và độ phức tạp từng CAPTCHA.
Yếu tố ảnh hưởng đến thời gian giải
Bốn biến số sau quyết định phần lớn chênh lệch giữa trung vị và P99 của bạn:
- Độ trễ mạng — khoảng cách vật lý đến endpoint API cộng dồn vào thời gian khứ hồi; RTT 200 mili giây làm tổng thời gian tăng thêm khoảng 1 giây (1 lần gửi task + 3–4 lần polling × 200 mili giây).
- Nguồn request — đa dạng nguồn request qua proxy thường giải nhanh hơn proxy trung tâm dữ liệu tập trung vì ít gây thử thách phụ.
- Độ phức tạp CAPTCHA — thử thách "chọn đèn giao thông" với ảnh mờ dần luôn chậm hơn một lần xác nhận checkbox đơn giản.
- Chiến lược polling — polling tích cực (2 giây/lần) phát hiện kết quả nhanh hơn nhưng tăng số request; polling thận trọng (10 giây/lần) giảm tải nhưng cộng thêm độ trễ.
Ví dụ thực tế: chọn gói theo kết quả benchmark
Một đội QA outsourcing tại TP.HCM chạy pipeline kiểm thử checkout, cần giải khoảng 5.000 reCAPTCHA v2/ngày trong 8 tiếng làm việc. Với trung vị 12–18 giây/lần, họ cần khoảng 3–5 thread song song để không dồn hàng đợi — vừa gọn trong gói STANDARD ($30/tháng, 15 thread), có dư cho các đợt tăng đột biến mà không cần nâng cấp lên ADVANCE ($90/tháng, 50 thread). Cách tính tương tự áp dụng cho đội theo dõi giá trên Shopee, Lazada, Tiki: lấy trung vị hoặc P90 của loại CAPTCHA gặp phải, nhân với số task đồng thời mong muốn, rồi đối chiếu số thread cần thiết trong reference/captchaai-pricing.md.
Script benchmark bằng Python
Script dưới đây gửi task, polling res.php và tính trung vị/P90 cho từng loại CAPTCHA — chạy trực tiếp với biến môi trường CAPTCHAAI_KEY:
# benchmark_captchaai.py
import os
import time
import statistics
import requests
API_KEY = os.environ.get("CAPTCHAAI_KEY", "YOUR_API_KEY")
def benchmark_solve(method, params, runs=10):
"""Benchmark a CAPTCHA type over multiple runs."""
times = []
successes = 0
for i in range(runs):
start = time.time()
# Submit
submit_params = {"key": API_KEY, "json": "1", **params}
resp = requests.get("https://ocr.captchaai.com/in.php",
params=submit_params)
result = resp.json()
if result.get("status") != 1:
print(f" Run {i+1}: Submit failed - {result.get('request')}")
continue
task_id = result["request"]
# Poll
time.sleep(10)
solved = False
for _ in range(30):
poll = requests.get("https://ocr.captchaai.com/res.php", params={
"key": API_KEY, "action": "get",
"id": task_id, "json": "1",
})
poll_result = poll.json()
if poll_result.get("status") == 1:
elapsed = time.time() - start
times.append(elapsed)
successes += 1
solved = True
print(f" Run {i+1}: {elapsed:.1f}s")
break
if poll_result.get("request") != "CAPCHA_NOT_READY":
print(f" Run {i+1}: Error - {poll_result.get('request')}")
break
time.sleep(5)
if not solved and poll_result.get("request") == "CAPCHA_NOT_READY":
print(f" Run {i+1}: Timeout")
if times:
return {
"runs": runs,
"successes": successes,
"success_rate": f"{successes/runs*100:.0f}%",
"median": f"{statistics.median(times):.1f}s",
"p90": f"{sorted(times)[int(len(times)*0.9)]:.1f}s" if len(times) >= 10 else "N/A",
"min": f"{min(times):.1f}s",
"max": f"{max(times):.1f}s",
}
return {"error": "No successful solves"}
# Benchmark reCAPTCHA v2
print("=== reCAPTCHA v2 ===")
recaptcha_v2 = benchmark_solve("userrecaptcha", {
"method": "userrecaptcha",
"googlekey": "6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-",
"pageurl": "https://www.google.com/recaptcha/api2/demo",
})
print(recaptcha_v2)
# Benchmark Image/OCR
print("\n=== Image CAPTCHA ===")
# Submit a base64-encoded test image
import base64
# Use a test image for benchmarking
image_result = benchmark_solve("post", {
"method": "base64",
"body": "BASE64_ENCODED_CAPTCHA_IMAGE",
})
print(image_result)
Script benchmark bằng JavaScript
Bản Node.js tương đương, dùng axios để gửi và polling task:
// benchmark_captchaai.js
const axios = require('axios');
const API_KEY = process.env.CAPTCHAAI_KEY || 'YOUR_API_KEY';
async function benchmarkSolve(params, runs = 10) {
const times = [];
let successes = 0;
for (let i = 0; i < runs; i++) {
const start = Date.now();
// Submit
const submit = await axios.get('https://ocr.captchaai.com/in.php', {
params: { key: API_KEY, json: '1', ...params },
});
if (submit.data.status !== 1) {
console.log(` Run ${i + 1}: Submit failed - ${submit.data.request}`);
continue;
}
// Poll
await new Promise(r => setTimeout(r, 10000));
let solved = false;
for (let j = 0; j < 30; j++) {
const poll = await axios.get('https://ocr.captchaai.com/res.php', {
params: { key: API_KEY, action: 'get', id: submit.data.request, json: '1' },
});
if (poll.data.status === 1) {
const elapsed = (Date.now() - start) / 1000;
times.push(elapsed);
successes++;
solved = true;
console.log(` Run ${i + 1}: ${elapsed.toFixed(1)}s`);
break;
}
if (poll.data.request !== 'CAPCHA_NOT_READY') {
console.log(` Run ${i + 1}: Error - ${poll.data.request}`);
break;
}
await new Promise(r => setTimeout(r, 5000));
}
if (!solved) console.log(` Run ${i + 1}: Timeout`);
}
if (times.length === 0) return { error: 'No successful solves' };
times.sort((a, b) => a - b);
return {
runs, successes,
successRate: `${((successes / runs) * 100).toFixed(0)}%`,
median: `${times[Math.floor(times.length / 2)].toFixed(1)}s`,
min: `${times[0].toFixed(1)}s`,
max: `${times[times.length - 1].toFixed(1)}s`,
};
}
(async () => {
console.log('=== reCAPTCHA v2 ===');
const v2 = await benchmarkSolve({
method: 'userrecaptcha',
googlekey: '6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-',
pageurl: 'https://www.google.com/recaptcha/api2/demo',
});
console.log(v2);
console.log('\n=== Cloudflare Turnstile ===');
const turnstile = await benchmarkSolve({
method: 'turnstile',
sitekey: 'YOUR_TURNSTILE_SITEKEY',
pageurl: 'https://example.com',
});
console.log(turnstile);
})();
Đọc hiểu kết quả benchmark
Trung vị, P90, P99 dùng để làm gì
Trung vị phản ánh trải nghiệm điển hình nên dùng để lập kế hoạch năng lực (capacity planning); P90 là "trường hợp xấu" cho 9 trên 10 lượt giải nên dùng để đặt timeout tiêu chuẩn; còn P99 là trường hợp biên thực sự — đặt timeout tối đa cao hơn mức này để tránh cắt ngang các lượt giải hợp lệ nhưng chậm.
Cấu hình khoảng polling theo từng loại CAPTCHA
Dựa trên bảng SLA phía trên, đây là mức chờ ban đầu và chu kỳ polling hợp lý cho từng loại:
| Loại CAPTCHA | Chờ ban đầu | Chu kỳ polling | Số lần thử tối đa |
|---|---|---|---|
| Hình ảnh/OCR | 5 giây | 3 giây | 15 |
| Cloudflare Turnstile | 5 giây | 3 giây | 15 |
| BLS CAPTCHA | 5 giây | 3 giây | 15 |
| reCAPTCHA v2 | 15 giây | 5 giây | 20 |
| reCAPTCHA v3 | 10 giây | 5 giây | 20 |
| GeeTest v3 | 12 giây | 5 giây | 20 |
| reCAPTCHA Enterprise | 15 giây | 5 giây | 25 |
Khắc phục sự cố khi benchmark
| Vấn đề | Nguyên nhân | Cách xử lý |
|---|---|---|
| Thời gian giải cao hơn bảng SLA | Độ trễ mạng hoặc proxy có vấn đề | Test lại từ khu vực gần server CaptchaAI hơn |
| Kết quả không nhất quán giữa các lần chạy | Độ khó CAPTCHA dao động theo từng lượt | Tăng cỡ mẫu lên trên 50 lượt chạy |
| Nhiều lượt timeout | pageurl hoặc sitekey không hợp lệ |
Xác minh tham số bằng một lần test thủ công trước |
ERROR_ZERO_BALANCE giữa lúc benchmark |
Số dư không đủ cho toàn bộ lượt chạy | Nạp thêm số dư trước khi chạy benchmark quy mô lớn |
Câu hỏi thường gặp
Chạy benchmark bao nhiêu lượt thì đủ tin cậy?
Ít nhất 50 lượt mỗi loại để P90 ổn định; dưới 30 lượt, P90/P99 dao động mạnh. Trung vị ổn định nhanh hơn, tin được từ khoảng 20 lượt.
Benchmark giúp chọn gói bao nhiêu thread như thế nào?
Lấy trung vị hoặc P90 của loại chiếm phần lớn khối lượng, tính số task song song ở giờ cao điểm, rồi đối chiếu số thread từng gói trong reference/captchaai-pricing.md.
Vị trí server ảnh hưởng thế nào nếu benchmark từ Việt Nam?
RTT từ Việt Nam đến endpoint CaptchaAI thường cao hơn RTT nội bộ Hoa Kỳ, nên cộng thêm khoảng đệm vào timeout. Luôn benchmark từ khu vực hạ tầng production, không phải máy cá nhân.
Có nên dùng số liệu này để đặt timeout production không?
Có — P90 cho timeout tiêu chuẩn, P99 cho timeout tối đa, cộng đệm 20% cho biến động mạng.
Nguồn request (proxy) ảnh hưởng thế nào đến thời gian giải?
CaptchaAI định tuyến lượt giải qua proxy bạn cung cấp; proxy chậm hoặc ở xa có thể cộng thêm 5–15 giây. Khi benchmark, đo riêng hai trường hợp có và không proxy để tách bạch chênh lệch.
Bài viết liên quan
- Giải nhiều loại CAPTCHA trong cùng một luồng xử lý
- Ma trận tính năng các loại CAPTCHA CaptchaAI hỗ trợ
Bước tiếp theo
Chạy hai script trên với tài khoản và target CAPTCHA của chính bạn để có số liệu thật thay vì số liệu tham khảo — lấy API key CaptchaAI tại đây.
Hướng dẫn liên quan: