Limitly
Examples

Basic Usage

Simple examples of using Limitly in your application. Learn the fundamentals with practical code examples.

Basic Usage

Simple, practical examples for common use cases.

Simple Rate Limiting

Recommended: Use your own Redis

import { createClient } from 'limitly-sdk';

// Recommended for production
const client = createClient({
  redisUrl: process.env.REDIS_URL || 'redis://localhost:6379',
  serviceId: 'my-app'
});

async function handleRequest(userId: string) {
  const result = await client.checkRateLimit(userId);
  
  if (!result.allowed) {
    throw new Error('Rate limit exceeded');
  }
  
  return { success: true, remaining: result.remaining };
}

Without Redis URL (development/testing):

// ⚠️ Shares hosted Redis - may collide with other users
const client = createClient({ serviceId: 'my-app' });

Response Structure

interface LimitlyResponse {
  allowed: boolean;
  limit?: number;
  remaining?: number;
  reset?: number;
  message?: string;
}

Custom Limits

const result = await checkLimit({
  identifier: 'user-123',
  capacity: 50,
  refillRate: 5
});

Per-User Limiting

// Recommended: Use your own Redis
const client = createClient({
  redisUrl: process.env.REDIS_URL,
  serviceId: 'user-api'
});

async function handleUserRequest(userId: string) {
  const result = await client.checkRateLimit(userId);
  
  if (!result.allowed) {
    return { error: 'Rate limit exceeded' };
  }
  
  return { success: true, remaining: result.remaining };
}

IP-Based Limiting

const ip = request.headers.get('x-forwarded-for')?.split(',')[0] || 'unknown';
const result = await client.checkRateLimit(ip);

if (!result.allowed) {
  return Response.json({ error: 'Too many requests' }, { status: 429 });
}

Endpoint-Specific Limits

const endpointLimits = {
  '/api/login': { capacity: 5, refillRate: 0.1 },
  '/api/search': { capacity: 100, refillRate: 10 }
};

const result = await client.checkRateLimit({
  identifier: `${userId}:${endpoint}`,
  ...endpointLimits[endpoint]
});

Error Handling

try {
  const result = await client.checkRateLimit(userId);
  if (!result.allowed) {
    return { error: 'Rate limit exceeded' };
  }
  return { success: true };
} catch (error) {
  // Fail open
  return { success: true, rateLimitError: true };
}

HTTP Headers

const headers = new Headers();
if (result.limit) headers.set('X-RateLimit-Limit', result.limit.toString());
if (result.remaining !== undefined) {
  headers.set('X-RateLimit-Remaining', result.remaining.toString());
}

if (!result.allowed) {
  return Response.json({ error: 'Rate limit exceeded' }, { status: 429, headers });
}

Service Isolation

// Recommended: Use your own Redis for each service
const apiClient = createClient({
  redisUrl: process.env.REDIS_URL,
  serviceId: 'api-service'
});

const authClient = createClient({
  redisUrl: process.env.REDIS_URL,
  serviceId: 'auth-service'
});