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-ForandX-Real-Ipcarry the visitor's address.X-Forwarded-Protoishttps,X-Forwarded-Hostis the address the visitor asked for, andX-Forwarded-Portis443.
Tokay removes these before your app sees the request.
- Any header starting with
X-Tokay-. Identity headers such asX-Tokay-Actor-Idreach 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
Authorizationheader 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, withRetry-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.