AeroModel

AeroModel

Documentation

DDoS and rate limiting

The API runs on Cloudflare Workers, which provides built-in layer 3/4/7 DDoS protection.

Automatic protection

Cloudflare automatically blocks:

  • SYN, ACK, UDP floods (layer 3/4).
  • Volumetric HTTP attacks.
  • Bots known to the Cloudflare database.
  • Vulnerability scans.

No action on your part — it's bundled with the Workers plan.

Application rate limiting

The API does not (yet) have an explicit per-key rate limit. But Cloudflare applies global limits (burst control) preventing a single caller from saturating one datacenter.

If you need strict guarantees (X req/sec), contact the admin to enable a Cloudflare WAF rate limit rule on your key.

Client-side best practices

1. Cache your results

Images are cacheable for 24h browser-side (cache-control: public, max-age=86400). Reuse the HTTP cache rather than re-firing the same URLs.

2. Use a CDN

If you proxy via your backend, put a CDN in front. The same URL repeated 1M times should hit the API at most once per datacenter.

3. Prefer slugs

Slugs are stable → cache hit. Plain-text names can produce several distinct URLs for the same image (Air France vs air france vs air-france depending on your normalization).

4. Avoid polling

Images don't change multiple times per second. If you build a dashboard, refresh at most every hour.

Quotas

The current Cloudflare Workers Paid plan includes:

  • 10M requests/month included.
  • 30s CPU/req max (largely sufficient for compositions).
  • R2 reads free up to a certain volume (see Cloudflare R2 pricing).

If you expect more than 10M req/month, ask the admin to prepare a scaling plan.

What if you get blocked (429 / 1015)

CodeMeaningAction
429 Too Many RequestsYou exceeded the Cloudflare rate limit.Wait Retry-After seconds.
1015 (Cloudflare HTML)IP block by WAF.Contact the admin.
503 Service UnavailableWorker down or in maintenance.Retry with exponential backoff.

Client-side backoff

async function fetchWithBackoff(url, init, retries = 3) {
  for (let i = 0; i < retries; i++) {
    const r = await fetch(url, init);
    if (r.status !== 429 && r.status !== 503) return r;
    const wait = Number(r.headers.get("retry-after")) || 2 ** i;
    await new Promise((rs) => setTimeout(rs, wait * 1000));
  }
  throw new Error("max retries reached");
}

See also