Rate Limits
Crawlbase erzwingt Concurrency-Limits pro Token, keine Requests pro Minute. Senden Sie so schnell Sie wollen — halten Sie nur die parallel laufenden Requests unter Ihrer Obergrenze.
Standard-Limits
Jedes Konto startet mit denselben großzügigen Standardwerten. Sie müssen diese nicht anfragen: sie sind ab dem Moment Ihrer Anmeldung auf jedem Token aktiv.
| Limit | Standard | Geltungsbereich |
|---|---|---|
| Parallele Requests | 20 | pro Token |
| Requests pro Sekunde | ~ 20 (abgeleitet) | pro Token |
| Gesamte monatliche Requests | bis zu 51,000,000 | pro Token |
| Timeout pro Request | 90 Sekunden | pro Request |
| Crawler-Queue-Größe | 100,000 URLs | pro Crawler |
«Parallel» bedeutet zeitgleich in Bearbeitung. Wenn jeder Crawl 2 Sekunden dauert und Sie 20 parallel laufen lassen, schaffen Sie etwa 10 Req/s im Dauerbetrieb: das ergibt rechnerisch ca. 864.000 Requests pro Tag und Token.
Versuchen Sie nicht, auf «X Requests pro Sekunde» zu drosseln: begrenzen Sie einfach Ihren Worker-Pool auf 20 und lassen Sie die Request-Latenz den Durchsatz bestimmen. Das ist simpler und entspricht der Funktionsweise des Limits auf Serverseite.
Was passiert, wenn Sie das Limit erreichen
Überschreiten Sie die Parallelitätsgrenze, antwortet Crawlbase mit HTTP 429 Too Many Requests. Der Request wird abgelehnt, nicht in eine Queue gestellt, also sollten Sie mit Backoff erneut versuchen.
// HTTP/1.1 429 Too Many Requests
// Retry-After: 1
// X-Crawlbase-Concurrency: 20
{ "error": "Concurrency limit reached", "limit": 20 }Der Retry-After-Header gibt Ihnen die Mindestwartezeit in Sekunden vor dem nächsten Versuch an. Halten Sie sich immer daran.
Rate Limits sauber handhaben
Das richtige Pattern ist exponentielles Backoff mit Jitter. Die meisten HTTP-Clients haben das eingebaut; hier ist das absolute Minimum, falls Sie es selbst implementieren müssen.
import time, random
from crawlbase import CrawlingAPI
api = CrawlingAPI({'token': 'YOUR_TOKEN'})
def crawl_with_retry(url, attempts=5):
for i in range(attempts):
res = api.get(url)
if res['status_code'] != 429:
return res
wait = (2 ** i) + random.random()
time.sleep(wait)
raise RuntimeError('Rate limit exhausted')const { CrawlingAPI } = require('crawlbase');
const api = new CrawlingAPI({ token: 'YOUR_TOKEN' });
async function crawlWithRetry(url, attempts = 5) {
for (let i = 0; i < attempts; i++) {
const res = await api.get(url);
if (res.statusCode !== 429) return res;
const wait = (2 ** i) * 1000 + Math.random() * 1000;
await new Promise(r => setTimeout(r, wait));
}
throw new Error('Rate limit exhausted');
}Für Workloads, die ständig an die Obergrenze stoßen, verwenden Sie einen Worker-Pool statt Fire-and-Forget. Begrenzen Sie den Pool auf Ihr Concurrency-Limit und Sie werden nie ein 429 sehen.
Über die Standardwerte hinaus skalieren
Drei Optionen, wenn 20 parallel nicht ausreichen:
Best Practices
- Begrenzen Sie Worker-Pools auf Ihr Token-Limit. Überbuchen Sie nicht und verlassen Sie sich nicht auf 429er: Der abgelehnte Request kostet trotzdem einen Round-Trip.
- Verwenden Sie
async=truefür langsame Ziele. Lang laufende, JS-gerenderte Crawls blockieren einen Concurrency-Slot für die gesamte Request-Dauer. Der async-Modus gibt den Slot sofort frei und liefert das Ergebnis per Webhook. - Halten Sie sich immer an
Retry-After. Ignorieren erzeugt nur weitere 429s und verbrennt Netzwerk-Round-Trips. - Fügen Sie Jitter zu Retries hinzu. Wenn 50 Worker nach einem kurzen Spike alle exakt nach 1s erneut versuchen, werden Sie nur den nächsten Spike erzeugen.
- Alarmieren Sie bei dauerhaft hoher 429-Rate. Ein gelegentliches 429 ist okay. Eine anhaltende Rate von 5 % oder mehr bedeutet, dass Sie höhere Concurrency oder besseres Scheduling brauchen.