How public traffic reaches your app

Every request from the internet passes through Tokay's gateway and your Service's proxy before it reaches your app. Here is what that path guarantees, what it changes on the way, and the limits it applies.

Last updated

AI agent? Start with llms.txt.

One proxy in front of your app

Tokay ends HTTPS at its gateway and forwards each request to your app. As far as your app can tell, there is exactly one proxy in front of it. Configure one trusted proxy hop, for example Express app.set('trust proxy', 1) or Flask ProxyFix(x_for=1), and your framework reports the visitor's address.

The visitor's address arrives as the only X-Forwarded-For entry and as X-Real-Ip. Behind a custom domain proxied by Cloudflare, that is the real visitor, taken from Cloudflare's CF-Connecting-IP and trusted only from Cloudflare's published address ranges. Behind any other CDN, it is the CDN's edge address.

What Tokay sets and removes

Tokay replaces these headers on every request, whatever the client sent.

  • X-Forwarded-For and X-Real-Ip carry the visitor's address.
  • X-Forwarded-Proto is https, X-Forwarded-Host is the address the visitor asked for, and X-Forwarded-Port is 443.

Tokay removes these before your app sees the request.

  • Any header starting with X-Tokay-. Identity headers such as X-Tokay-Actor-Id reach your app only from Tokay, so a client cannot forge them. See Know who is signed in.
  • Tokay's own sign in cookies, and an Authorization header that carries a Tokay credential.
  • Forwarded.

Every other header and cookie reaches your app as the client sent it.

Limits for web apps

Limit Value
Request body Up to 1 GB. Tokay receives the whole body before passing it on, so a slow upload never holds your app.
Request headers Up to 16 KB for one header and 64 KB for all of them, received within 30 seconds.
Waiting on your app Up to an hour between two reads or writes. A long poll, event stream, or slow download keeps going as long as bytes keep moving.
One request About an hour from start to finish.
Idle connection Kept open for 3 minutes between requests.
Responses Streamed as your app writes them, so event streams and streamed AI output reach the visitor right away.
WebSockets Supported. A deploy closes open WebSockets when the old version stops, so clients should reconnect.

A function must start its response within 300 seconds of a request, or the caller receives 504 Gateway Timeout. See Webhooks.

The flood shield

Tokay protects every app from floods with a very generous ceiling, counted per client address and per hostname.

  • More than 2,000 requests in 10 seconds from one address to one hostname are answered 429 Too Many Requests, with Retry-After: 10. A client that uses many apps is never counted across them. Behind Cloudflare, an IPv6 visitor counts by its /64.
  • Past 5,000 open connections from one address, new connections are refused with no HTTP response, so the client sees a reset rather than a 429. Cloudflare's addresses are exempt, since many visitors share them.

A WebSocket, an event stream, or an upload counts as one request. The ceiling is set far above real traffic, scanners included. It is not a rate limit for your app. Limits that depend on your app, such as logins per minute or API calls per key, belong in your app.

Paths Tokay answers itself

Every request reaches your app except Tokay's paths under /.tokay/ and the files Tokay serves itself, such as a static site or a framework's build output. See Web apps.