Increase rate limits
Browse files
README.md
CHANGED
|
@@ -89,7 +89,7 @@ Go to **Space Settings → Repository Secrets** and add:
|
|
| 89 |
```
|
| 90 |
|
| 91 |
```json
|
| 92 |
-
{"error": "Rate limit exceeded. Max
|
| 93 |
```
|
| 94 |
|
| 95 |
```json
|
|
@@ -105,7 +105,7 @@ Go to **Space Settings → Repository Secrets** and add:
|
|
| 105 |
| `STRIX_API_TOKEN` | *(none)* | Required in production. If unset, runs in open/dev mode. |
|
| 106 |
|
| 107 |
### Rate Limiting
|
| 108 |
-
- **
|
| 109 |
- In-memory, resets on Space restart
|
| 110 |
|
| 111 |
### Prediction Length (Adaptive)
|
|
|
|
| 89 |
```
|
| 90 |
|
| 91 |
```json
|
| 92 |
+
{"error": "Rate limit exceeded. Max 240 requests per 300s window.", "retry_after": 300}
|
| 93 |
```
|
| 94 |
|
| 95 |
```json
|
|
|
|
| 105 |
| `STRIX_API_TOKEN` | *(none)* | Required in production. If unset, runs in open/dev mode. |
|
| 106 |
|
| 107 |
### Rate Limiting
|
| 108 |
+
- **240 requests** per **5-minute** sliding window per caller (override: `STRIX_RATE_LIMIT_MAX`)
|
| 109 |
- In-memory, resets on Space restart
|
| 110 |
|
| 111 |
### Prediction Length (Adaptive)
|
app.py
CHANGED
|
@@ -46,8 +46,29 @@ logger = logging.getLogger("strix-chronos")
|
|
| 46 |
# ---------------------------------------------------------------------------
|
| 47 |
API_TOKEN = os.environ.get("STRIX_API_TOKEN") # Set in HF Space secrets
|
| 48 |
|
| 49 |
-
|
| 50 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 51 |
|
| 52 |
VALID_TIMEFRAMES = {"15m", "1h", "1d", "1wk", "1mo"}
|
| 53 |
TICKER_PATTERN = re.compile(r"^[A-Z0-9\.\-\^=]{1,15}$")
|
|
|
|
| 46 |
# ---------------------------------------------------------------------------
|
| 47 |
API_TOKEN = os.environ.get("STRIX_API_TOKEN") # Set in HF Space secrets
|
| 48 |
|
| 49 |
+
# Rate limit — sized from MEASURED capacity, not intuition.
|
| 50 |
+
#
|
| 51 |
+
# Measured against this Space (Chronos-2 120M, CPU, float32), sequential
|
| 52 |
+
# forecasts from the Strix server: ~8.7s on the first call (cold start / model
|
| 53 |
+
# warm-up), then a steady state of ~1.75-1.8s round-trip. That round-trip
|
| 54 |
+
# INCLUDES the caller's network hop and Gradio overhead, so it is a conservative
|
| 55 |
+
# proxy: serial capacity is therefore at least ~0.55 req/s, i.e. ~165 requests
|
| 56 |
+
# per 300s window at full duty.
|
| 57 |
+
#
|
| 58 |
+
# The old ceiling of 60/300s was 0.2 req/s — roughly a THIRD of what the Space
|
| 59 |
+
# can actually serve, so it was rejecting traffic the hardware was idle for. It
|
| 60 |
+
# bit in normal single-operator use because one MAX Market Intelligence scan
|
| 61 |
+
# issues ~20 forecasts, so two scans in five minutes tripped it.
|
| 62 |
+
#
|
| 63 |
+
# 240/300s = 0.8 req/s leaves the limiter as an abuse ceiling rather than a
|
| 64 |
+
# throughput cap, while staying within what a free CPU Space can sustain. The
|
| 65 |
+
# client also caches, de-duplicates and serialises its calls, so real demand is
|
| 66 |
+
# well under this.
|
| 67 |
+
#
|
| 68 |
+
# Override without a redeploy by setting STRIX_RATE_LIMIT_MAX / _WINDOW in the
|
| 69 |
+
# Space secrets.
|
| 70 |
+
RATE_LIMIT_MAX = int(os.environ.get("STRIX_RATE_LIMIT_MAX", "240"))
|
| 71 |
+
RATE_LIMIT_WINDOW = int(os.environ.get("STRIX_RATE_LIMIT_WINDOW", "300"))
|
| 72 |
|
| 73 |
VALID_TIMEFRAMES = {"15m", "1h", "1d", "1wk", "1mo"}
|
| 74 |
TICKER_PATTERN = re.compile(r"^[A-Z0-9\.\-\^=]{1,15}$")
|