Skip to main content

Rate limits

deepface.dev applies rate limiting and queue controls at the gateway.

Enforcement points

  • Per-account requests per minute within the configured limiter scope
  • Maximum inflight compute requests
  • Queue depth
  • Queue timeout

Account tiers

The allowance is shared across all API keys for an account within the configured limiter scope. Paid tiers use lifetime USD value added to the wallet, not API usage or the remaining balance. Free credits, failed or pending payments, card-setup payments, sandbox payments and test payments do not count. After the coordinated gateway release, anonymous accounts are limited to one active inference request, with no waiting queue. The two-per-minute limit is shared across gateway Machines and all keys for the account. Anonymous accounts cannot enqueue batch comparisons; create a full account first. The homepage displays saved examples, so browsing them uses no API quota. Live testing requires a signed-in account and follows its limits. Thresholds are strict: exactly $50 receives 100/minute; the 200/minute tier starts above $50. Tiers refresh when a verified live payment is credited to the wallet. Paid wallets with active auto top-up and a valid live saved card receive up to 20% off: auto top-up lowers the starting rate, and volume discounts approach the same minimum. Priority doubles the discounted standard rate. Queued comparisons use standard pricing. New requests lose the auto top-up benefit when it is disabled or the card is revoked. Monthly invoice contracts use their agreed tariff.

Request priority

Send optional X-Request-Priority on synchronous POST /verify, POST /represent and POST /compare, with JSON or multipart uploads. It lets a request jump your own account’s normal waiting queue, across all of that account’s API keys, on one gateway process. A positive value also selects a higher global scheduling group. The global waiting queue on each gateway process uses strict precedence:
  1. Enterprise with an explicitly positive priority.
  2. Non-enterprise with an explicitly positive priority.
  3. Enterprise normal.
  4. Non-enterprise normal.
Only eligible calls compete: an account at its in-flight limit is skipped. Within a group, accounts retain their queue positions; lower positive values can jump that account’s own waiting calls, with FIFO ties. Numeric values do not rank different accounts. The old 4:1 rotation and aging override are removed. Sustained higher-group traffic can delay lower groups until their original queue timeout; active work is never preempted. This ordering is per gateway process. Every finite positive value requests own-queue priority, with no upper limit of 1. Lower positive numbers run first: 0.5, then 1, then 10, then 100, then requests with no priority. Equal effective values keep arrival order. Omitted, null, and 0 use normal FIFO order; zero is handled normally without rejecting the request. They add no per-request priority surcharge. For REST, send literal null for a null header or omit the header. Numbers use double precision and JSON spelling, including scientific notation. Negative, blank, repeated, comma-separated, nonfinite, overflowing and underflowing values return 400 invalid_priority before admission. Close decimals may round equal. Write 0.79, not .79, +0.79, or 00.79. Own-queue priority does not interrupt running work, reorder model-server work, reserve capacity, bypass RPM/concurrency/upload limits or extend queue deadlines. A full queue can still reject a priority request. Sustained priority traffic can delay normal requests until their original timeout. Ordering is per gateway process and does not guarantee latency. For MCP, use optional priority on verify_faces, represent_face or compare_inputs; null/omitted means no header, and zero is accepted as normal. REST priority is header-only. Experimental async compare rejects a positive header with 400 unsupported_priority.

Billing and audit

Completed calls with any explicitly positive own-queue priority cost 2×, even when the queue is idle. Under the default billing policy, enterprise lane access also costs 2×; both together cost 2× once. Negotiated request_only contracts include enterprise access at the standard rate. Completed no-face results are billable; failures are free. The gateway records the requested value, whether a header was supplied, whether own-queue priority applied, the global_tier_and_own_account_queue scope, actual enterprise lane, and scheduling transitions. Each event freezes schedulerPolicy: four_tier_v1 and schedulingClass, with per-group queue counts at scheduling decisions. Billing receipts freeze request_priority_scheme, contract policy and multiplier. Historical below_one_v1 receipts retain their original interpretation; optional_positive_v2 uses the optional scheme above. Existing financial and scheduling history is not reinterpreted.

Retry behavior

Gateway 429 rate_limited responses include:
  • Retry-After
  • RateLimit-Limit
  • RateLimit-Remaining
  • RateLimit-Reset
These headers describe the limiter that enforced the request. With a configured shared Redis limiter, gateways share the account counter. Without Redis, each gateway process has its own in-memory counter; multiple gateway Machines do not provide one strict fleet-wide RPM allowance. A configured required shared limiter fails closed when unavailable. Concurrency and queue admission remain local to each gateway process, with account overrides within its global limits. 503 queue_full, 503 queue_timeout, and 503 request_body_budget_full indicate temporary capacity pressure. Treat them as retryable with bounded backoff unless your own SLA policy says otherwise. A body-budget rejection is zero-rated, does not dispatch inference, and includes Retry-After: 5. 503 gateway_draining also rejects before compute and includes x-request-id. Rate-limit headers may be absent. For explicit model 503 model_not_ready, model_busy, and model_queue_timeout responses, the gateway already retries admission with jittered backoff within one 240-second upstream deadline. These retries do not consume another account RPM token or create a separate billing request. A client’s new HTTP request passes through admission and rate limiting again. Generic 502, connection loss, and 504 upstream_timeout do not prove that compute failed to run: preserve the request ID and investigate before replaying. See Errors for request-ID and timeout behavior. The complete JS/Python examples intentionally perform no automatic compute retry. A retry delay or generic 5xx status alone does not prove that replay is safe. Use production outcomes, cost and retries to distinguish confirmed precompute rejection from uncertain completion.

Capacity planning

If you need higher sustained throughput, dedicated queue capacity, or custom limits, contact the deepface.dev team before scaling traffic abruptly.

MCP and OAuth request admission

The public MCP adapters additionally admit at most 600 requests per minute per process and 60 per source. OAuth token/revoke share a 300-per-process and 30-per-source minute budget. These fixed-window limits supplement the gateway account quotas; they are not shared across hosting instances. Source headers provide a best-effort partition; rotating them does not bypass the process limit. Admission rejection uses JSON 429 rate_limited and Retry-After: 60, without the gateway RateLimit-* headers. MCP also bounds streamed request bodies and aggregate request bytes; see MCP transport errors.