Skip to content

Rate Limits ​

Orphnet Logging applies rate limiting at multiple levels to protect the service and ensure fair usage. Rate limits are enforced via KV-backed counters.

Rate Limit Tiers ​

Auth Endpoints ​

All routes under /auth/* use the AUTH preset:

SettingValue
Limit5 requests per minute
IdentifierClient IP address
Window60 seconds (sliding)

This protects against brute-force login attempts and credential stuffing.

API Endpoints ​

Routes under /logger/*, /projects/*, and /workspaces/* use the API_DEFAULT preset:

SettingValue
LimitConfigurable per workspace
IdentifierAPI key or JWT user ID
Window60 seconds (sliding)

Workspace administrators can configure custom rate limits through the cascading configuration system.

Playground Sandbox ​

The playground sandbox has restricted limits to prevent abuse:

ResourceLimit
Log ingestion100 logs per hour
Log queries20 queries per hour
Demo API keysk_demo_playground (18-char prefix)

The sandbox is reset every 6 hours via a scheduled cron trigger, re-seeding demo data and recreating the demo API key.

Rate Limit Headers ​

Every response includes rate limit headers:

X-RateLimit-Limit: 60
X-RateLimit-Remaining: 58
X-RateLimit-Reset: 1709812800
HeaderDescription
X-RateLimit-LimitMaximum requests allowed in the current window
X-RateLimit-RemainingRequests remaining in the current window
X-RateLimit-ResetUnix timestamp (seconds) when the window resets

Rate Limited Response ​

When a rate limit is exceeded, the API returns:

json
{
  "success": false,
  "data": null,
  "error": {
    "code": "RATE_LIMITED",
    "message": "Too many requests"
  },
  "meta": {
    "timestamp": "2026-03-07T12:00:00.000Z"
  }
}

HTTP Status: 429 Too Many Requests

Cascading Configuration ​

API rate limits use a cascading match system with explicit priority:

PriorityMatchDescription
1 (highest)Exact method + exact pathe.g., POST /logger/:id/log
2Wildcard method + exact pathe.g., * /logger/:id/log
3Workspace defaultPer-workspace custom limit
4 (lowest)Preset defaultAPI_DEFAULT preset

The RateLimitService resolves the applicable limit using this cascade. If no custom configuration exists for a workspace, the preset defaults apply.

Rate Limit Implementation ​

Rate limits are tracked in KV with the following pattern:

  • Key format: rate:{identifier}:{window}
  • Value: Current request count
  • TTL: Equals the window duration in seconds

The checkRateLimit function takes { key, limit, windowSeconds } and returns whether the request is allowed. The resolveIdentifier function determines the identifier (IP for auth, API key/user for API).

Client IP Resolution ​

The getClientIp function extracts the client IP from request headers in this order:

  1. CF-Connecting-IP (Cloudflare)
  2. X-Forwarded-For (first IP)
  3. Falls back to a default

Rate Limit Violations ​

Rate limit violations are logged asynchronously via c.executionCtx.waitUntil() to avoid blocking responses. The RateLimitService.logViolation method records violations to the queue for analysis.

Best Practices ​

Client SDK ​

The client SDK handles rate limits gracefully:

typescript
app.use('*', createLoggingMiddleware({
  apiUrl: 'https://api.logvista.orph.dev',
  apiKey: 'sk_your_key',
  onError: (err) => {
    // Rate limit errors are passed here
    if (err.message.includes('429')) {
      console.warn('Rate limited, logs will be retried on next batch')
    }
  },
}))

BatchTransport ​

Use BatchTransport to reduce request volume and stay within limits:

typescript
const transport = new BatchTransport({
  apiUrl: 'https://api.logvista.orph.dev',
  apiKey: 'sk_your_key',
  maxBatchSize: 50,        // Batch more entries per request
  flushIntervalMs: 10000,  // Flush less frequently
})

See Also ​

LogVista — Edge-native structured logging API