# Rate Limits & Quotas Synapse has a simple, predictable rate limit policy designed to prevent abuse while not getting in the way of legitimate usage. ## Rate Limit Policy | Auth Method | Limit | Scope | |-------------|-------|-------| | Mind Key (`Authorization: Bearer`) | 120 req/min (external IPs; unlimited for trusted internal networks) | Per-identity | | Mind Key (`?key=`) **(deprecated)** | 60 req/min | Per-IP | | JWT (`Authorization: Bearer`) | 120 req/min (external IPs; unlimited for trusted internal networks) | Per-user | | Public endpoints | **None** | Global | > [!TIP] > **Always use the `Authorization: Bearer` header** when possible. External > Bearer clients get 120 req/min per identity, and trusted internal networks > (Docker overlay, VPN, loopback) are unlimited. Use `?key=` only as a legacy > fallback for tools that can't set custom headers. ## Rate Limit Headers When you use `?key=` auth, responses include rate limit headers: ``` X-RateLimit-Limit: 60 X-RateLimit-Remaining: 42 X-RateLimit-Reset: 1782567840 ``` When you exceed the limit: ``` HTTP/1.1 429 Too Many Requests X-RateLimit-Limit: 60 X-RateLimit-Remaining: 0 Retry-After: 42 Content-Type: application/json { "error": "rate_limited", "message": "Too many requests with query-param auth. Slow down or use Authorization header." } ``` ## When You Hit a Rate Limit If you get a 429: 1. **Switch to Authorization header** (recommended): ```bash # Don't: ?key=YOUR_MIND_KEY (60/min limit) curl ".../memory/recall?key=YOUR_MIND_KEY" # Do: Authorization header (unlimited) curl -H "Authorization: Bearer YOUR_MIND_KEY" .../memory/recall ``` 2. **Or wait `Retry-After` seconds** and retry. ## Why the ?key= Limit Exists The `?key=` query parameter is convenient for URL-only tools (browsers, `open` commands), but it is deprecated and gated server-side by `AUTH_QUERY_KEY_MODE` (`deny` by default; `allow` re-enables query-param auth). It has security and performance implications: - **Security:** Query parameters are logged in server access logs, browser history, and Referer headers. Limiting usage reduces exposure. - **Performance:** Query-parameter auth requires an IP-based rate limiter (Redis lookup per request), which adds latency. Header auth skips this. - **Abuse prevention:** A leaked `?key=` URL could be shared and hammered. The IP limit contains the blast radius. ## Recommended Patterns ### LLM agents ```python # Always use header auth headers = {"Authorization": f"Bearer {MIND_KEY}"} response = requests.get(f"{URL}/memory/recall", headers=headers) ``` ### Browser-based tools If your tool can only open URLs: ```bash # Legacy fallback (deprecated, 60/min per IP, gated by AUTH_QUERY_KEY_MODE). # Never share or bookmark such URLs — the key lands in logs and history. open "https://synapse.schaefer.zone/memory/recall?key=YOUR_MIND_KEY" # Preferred: switch to a tool that supports headers curl -H "Authorization: Bearer YOUR_MIND_KEY" .../memory/recall ``` > [!WARNING] > A Mind Key inside a URL leaks into server access logs, browser history and > `Referer` headers. If that happens, rotate the key immediately. ### MCP server MCP servers always use header auth via `SYNAPSE_MIND_KEY` env var — no rate limit applies. ### Bulk imports For bulk operations (e.g. importing 1000 memories), always use header auth. Bulk imports via `?key=` will hit the rate limit within 1 minute. ## Quotas (Mind-Level) There are currently no per-mind quotas on storage size or memory count. All limits are at the auth/IP level, not the data level. This may change in the future for multi-tenant fairness. ## Monitoring Your Usage ```bash # Rate limit headers are attached to ?key= responses (legacy path): curl -i "https://synapse.schaefer.zone/memory/stats?key=YOUR_MIND_KEY" | grep -i ratelimit # Output: # X-RateLimit-Limit: 60 # X-RateLimit-Remaining: 58 # X-RateLimit-Reset: 1782567840 ``` ## Next Steps - [Authentication](/docs/getting-started/authentication) - [Errors & Error Handling](/docs/api/errors)