Skip to content

Rate Limiting

TSKit includes per-route rate limiting to protect against abuse. The rate limiter uses an in-memory driver by default, which works well for single-server deployments.

Five rate-limiting rules are defined in config/rate-limit.ts:

RuleMax requestsWindow
auth1201 minute
api1001 minute
upload101 minute
admin601 minute
default601 minute

Add rate limiting to a server function using createRateLimitMiddleware:

import { createRateLimitMiddleware } from '#/middleware/rate-limit'
const uploadRateLimit = createRateLimitMiddleware('upload')
export const uploadFile = createServerFn({ method: 'POST' })
.middleware([uploadRateLimit, authMiddleware])
.handler(async ({ context }) => {
// handler runs only if the rate limit allows it
})

The middleware extracts the client’s IP address and checks it against the rule. If the limit is exceeded, it throws a “Too many requests” error.

The default MemoryRateLimitDriver uses an in-memory map to track request timestamps in a sliding window. When a request comes in, it counts how many previous requests from the same IP fall within the window.

This works well for development and single-server production setups. For multi-server deployments, you would need a persistent driver backed by something like Redis. See the Adding a Driver reference for how to create one.

Outside of middleware, you can use the rateLimiter facade from lib/facades/rate-limit.ts:

import { rateLimiter } from '#/lib/rate-limit'
const result = await rateLimiter.check('custom-key')
if (!result.allowed) {
throw new Error('Rate limited')
}

Use a specific rule:

const result = await rateLimiter.use('upload').check(key)
FilePurpose
config/rate-limit.tsRate limit rules and driver config
lib/facades/rate-limit.tsRateLimiter facade
middleware/rate-limit.tsMiddleware factory
core/drivers/rate-limit/memory.tsIn-memory driver
core/drivers/rate-limit/types.tsRateLimitDriver interface