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