Rate Limits

api
backend
rate-limit
segurança

Sistema de rate limiting, quotas e throttling para proteger a API e garantir uso justo

Nesta Página

Rate Limits e Throttling

O Tarefa AI implementa rate limiting para proteger a infraestrutura e garantir qualidade de serviço para todos os usuários. Este guia explica os limites, como monitorá-los e como lidar com erros de rate limit.

Visão Geral

Por que Rate Limiting?

  • Proteção contra abuso: Previne uso excessivo (intencional ou não)
  • Estabilidade: Garante que a API permaneça responsiva para todos
  • Custos: Controla uso de recursos computacionais e APIs de terceiros (OpenRouter, etc)
  • Segurança: Mitiga ataques de força bruta e DDoS

Tipos de Limites

  1. Rate Limits: Requisições por unidade de tempo
  2. Quotas: Limites totais por período (diário/mensal)
  3. Concurrent Limits: Execuções simultâneas máximas

Rate Limits por Endpoint

Autenticação

EndpointLimiteJanelaEscopo
POST /api/auth/login5 tentativas15 minIP + Email
POST /api/auth/register3 cadastros1 horaIP
POST /api/auth/forgot-password3 requests1 horaIP + Email
POST /api/auth/reset-password5 tentativas1 horaIP + Token
GET /api/auth/session60 requests1 minUsuário

Motivo: Endpoints sensíveis têm limites agressivos para prevenir ataques.

Tarefas

EndpointLimiteJanelaEscopo
POST /api/agent/create-task10 criações1 minUsuário
GET /api/tasks100 requests1 minUsuário
GET /api/tasks/{id}120 requests1 minUsuário
PATCH /api/tasks/{id}20 updates1 minUsuário
DELETE /api/tasks/{id}10 deletes1 minUsuário

Execuções

EndpointLimiteJanelaEscopo
POST /api/agent/process30 requests1 minUsuário
POST /api/tasks/{id}/execute20 execuções1 minUsuário
GET /api/executions100 requests1 minUsuário
GET /api/executions/{id}150 requests1 minUsuário

Upload

EndpointLimiteJanelaEscopo
POST /api/upload10 uploads1 minUsuário
DELETE /api/upload20 deletes1 minUsuário

Limite adicional: Máximo 100MB de storage por usuário.

Integrações

EndpointLimiteJanelaEscopo
POST /api/integrations/*/validate5 validações1 minUsuário
POST /api/coupons/activate5 ativações1 horaUsuário

Admin

EndpointLimiteJanelaEscopo
GET /api/admin/stats60 requests1 minAdmin
GET /api/admin/users100 requests1 minAdmin
POST /api/admin/coupons20 criações1 minAdmin
PATCH /api/admin/users/*30 updates1 minAdmin

Webhooks

EndpointLimiteJanelaEscopo
POST /api/webhooks5 criações1 minUsuário
POST /api/webhooks/*/test10 testes1 minUsuário
Entregas de webhook100 requests1 minWebhook

Quotas Diárias e Mensais

Plano Free (Trial)

RecursoLimite DiárioLimite Mensal
Execuções de tarefas50500
Tokens de IA (input+output)100.0001.000.000
Tarefas ativas10-
Webhooks3-
Upload storage-100MB

Plano Pro (Exemplo)

RecursoLimite DiárioLimite Mensal
Execuções de tarefas50010.000
Tokens de IA (input+output)1.000.00020.000.000
Tarefas ativas100-
Webhooks20-
Upload storage-10GB

Limites de Concorrência

Por Usuário

  • Execuções simultâneas: 5 tarefas rodando ao mesmo tempo
  • Uploads simultâneos: 3 arquivos ao mesmo tempo
  • Sessões ativas: 10 dispositivos/tokens

Global

  • Execuções totais simultâneas: 1000 (sistema completo)
  • Webhooks simultâneos: 500 entregas paralelas

Headers de Rate Limit

Todos os responses incluem headers informativos:

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 85
X-RateLimit-Reset: 1674820800000
X-RateLimit-Window: 60
X-RateLimit-Policy: user

Headers Detalhados

HeaderDescriçãoExemplo
X-RateLimit-LimitLimite máximo de requests na janela100
X-RateLimit-RemainingRequests restantes na janela atual85
X-RateLimit-ResetTimestamp (ms) quando o limite reseta1674820800000
X-RateLimit-WindowDuração da janela em segundos60
X-RateLimit-PolicyPolítica aplicada (user, ip, endpoint)user

Exemplo de Response

curl -I https://api.tarefaai.com/api/tasks \
  -H "Authorization: Bearer {token}"

Response:

HTTP/1.1 200 OK
Content-Type: application/json
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 85
X-RateLimit-Reset: 1674820800000
X-RateLimit-Window: 60
X-RateLimit-Policy: user

Erro de Rate Limit

Response (429 Too Many Requests)

{
  "success": false,
  "error": "Rate limit exceeded",
  "message": "Too many requests. Please try again in 45 seconds.",
  "details": {
    "limit": 100,
    "remaining": 0,
    "reset": 1674820800000,
    "resetIn": 45,
    "retryAfter": 45
  }
}

Headers de Erro

HTTP/1.1 429 Too Many Requests
Content-Type: application/json
Retry-After: 45
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1674820800000

Estratégias de Tratamento

1. Backoff Exponencial

async function fetchWithRetry(url: string, options: RequestInit, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    const response = await fetch(url, options);
 
    if (response.status !== 429) {
      return response;
    }
 
    // Ler Retry-After do header
    const retryAfter = parseInt(response.headers.get('Retry-After') || '60');
 
    // Exponential backoff: 1s, 2s, 4s, 8s...
    const delay = Math.min(retryAfter * 1000, Math.pow(2, i) * 1000);
 
    console.log(`Rate limited. Retrying in ${delay}ms...`);
    await new Promise(resolve => setTimeout(resolve, delay));
  }
 
  throw new Error('Max retries exceeded');
}
 
// Uso
try {
  const response = await fetchWithRetry('https://api.tarefaai.com/api/tasks', {
    headers: { Authorization: `Bearer ${token}` }
  });
  const data = await response.json();
} catch (error) {
  console.error('Failed after retries:', error);
}

2. Cliente com Rate Limit Awareness

class TarefaAIClient {
  private remaining: number = 100;
  private resetAt: number = Date.now() + 60000;
 
  async request(endpoint: string, options: RequestInit) {
    // Aguardar reset se necessário
    if (this.remaining <= 0) {
      const waitTime = this.resetAt - Date.now();
      if (waitTime > 0) {
        console.log(`Waiting ${waitTime}ms for rate limit reset...`);
        await new Promise(resolve => setTimeout(resolve, waitTime));
      }
    }
 
    const response = await fetch(endpoint, options);
 
    // Atualizar contadores
    this.remaining = parseInt(response.headers.get('X-RateLimit-Remaining') || '0');
    this.resetAt = parseInt(response.headers.get('X-RateLimit-Reset') || '0');
 
    if (response.status === 429) {
      const retryAfter = parseInt(response.headers.get('Retry-After') || '60');
      await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
      return this.request(endpoint, options); // Retry
    }
 
    return response;
  }
}
 
// Uso
const client = new TarefaAIClient();
const response = await client.request('https://api.tarefaai.com/api/tasks', {
  headers: { Authorization: `Bearer ${token}` }
});

3. Queue de Requisições

class RateLimitedQueue {
  private queue: Array<() => Promise<any>> = [];
  private processing = false;
  private requestsPerMinute = 100;
  private delay = 60000 / this.requestsPerMinute; // ~600ms entre requests
 
  async enqueue<T>(fn: () => Promise<T>): Promise<T> {
    return new Promise((resolve, reject) => {
      this.queue.push(async () => {
        try {
          const result = await fn();
          resolve(result);
        } catch (error) {
          reject(error);
        }
      });
 
      this.process();
    });
  }
 
  private async process() {
    if (this.processing || this.queue.length === 0) return;
 
    this.processing = true;
 
    while (this.queue.length > 0) {
      const task = this.queue.shift()!;
      await task();
      await new Promise(resolve => setTimeout(resolve, this.delay));
    }
 
    this.processing = false;
  }
}
 
// Uso
const queue = new RateLimitedQueue();
 
for (let i = 0; i < 200; i++) {
  queue.enqueue(async () => {
    const response = await fetch('https://api.tarefaai.com/api/tasks');
    return response.json();
  });
}

Monitoramento de Uso

Dashboard de Quotas

Acesse Configurações > Uso & Quotas para ver:

  • Requisições por endpoint (últimas 24h)
  • Tokens de IA consumidos
  • Storage utilizado
  • Progresso em relação aos limites
  • Histórico de rate limits atingidos

API de Usage

curl -X GET https://api.tarefaai.com/api/usage \
  -H "Authorization: Bearer {token}"

Response:

{
  "success": true,
  "usage": {
    "period": "2025-01-17",
    "executions": {
      "used": 35,
      "limit": 50,
      "remaining": 15,
      "percentage": 70.0
    },
    "tokens": {
      "used": 45000,
      "limit": 100000,
      "remaining": 55000,
      "percentage": 45.0
    },
    "storage": {
      "usedBytes": 25000000,
      "limitBytes": 104857600,
      "usedMB": 23.8,
      "limitMB": 100,
      "percentage": 23.8
    },
    "rateLimits": {
      "hitToday": 3,
      "endpoints": [
        {
          "endpoint": "/api/agent/process",
          "hits": 2,
          "lastHit": "2025-01-17T14:30:00.000Z"
        }
      ]
    }
  }
}

Alertas de Quota

Configure alertas quando atingir % do limite:

curl -X POST https://api.tarefaai.com/api/usage/alerts \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "threshold": 80,
    "notifyEmail": true,
    "notifyWebhook": true
  }'

Quando atingir 80%:

  • Email enviado
  • Webhook disparado (se configurado)
  • Notificação no dashboard

Exceções e Allowlist

Requisições Isentas

Alguns endpoints não contam para rate limits:

  • GET /api/health - Health check
  • GET /api/docs/* - Documentação
  • GET / - Landing page
  • Assets estáticos (/images/*, /styles/*)

Requisitar Aumento de Limite

Para planos personalizados ou necessidades especiais:

  1. Acesse Configurações > Planos
  2. Clique em Solicitar Plano Enterprise
  3. Preencha formulário com suas necessidades
  4. Nosso time responde em até 24h

Ou via email: enterprise@tarefaai.com

Best Practices

1. Implemente Caching

// ✅ BOM: Cache de dados que não mudam frequentemente
const cache = new Map<string, { data: any; expiresAt: number }>();
 
async function getTasks() {
  const cached = cache.get('tasks');
  if (cached && cached.expiresAt > Date.now()) {
    return cached.data;
  }
 
  const response = await fetch('https://api.tarefaai.com/api/tasks');
  const data = await response.json();
 
  cache.set('tasks', {
    data,
    expiresAt: Date.now() + 60000 // Cache 1 min
  });
 
  return data;
}

2. Use Webhooks ao invés de Polling

// ❌ RUIM: Polling constante
setInterval(async () => {
  const executions = await fetch('/api/executions');
  // Consome rate limit desnecessariamente
}, 5000);
 
// ✅ BOM: Configure webhook
// Você recebe notificação quando algo muda
app.post('/webhook', (req, res) => {
  const { event, data } = req.body;
  if (event === 'task.completed') {
    handleTaskCompleted(data);
  }
  res.status(200).send('OK');
});

3. Batch Operations

// ❌ RUIM: Múltiplas requisições individuais
for (const task of tasks) {
  await fetch(`/api/tasks/${task.id}`); // 100 requests
}
 
// ✅ BOM: Uma requisição batch
const response = await fetch('/api/tasks', {
  method: 'POST',
  body: JSON.stringify({ ids: tasks.map(t => t.id) })
});

4. Monitore Headers

// ✅ BOM: Sempre verifique headers
const response = await fetch('https://api.tarefaai.com/api/tasks');
 
const remaining = parseInt(response.headers.get('X-RateLimit-Remaining') || '0');
const limit = parseInt(response.headers.get('X-RateLimit-Limit') || '100');
 
if (remaining < limit * 0.1) {
  console.warn(`Rate limit baixo: ${remaining}/${limit}`);
  // Reduzir velocidade de requisições
}

5. Graceful Degradation

// ✅ BOM: Falhe graciosamente
async function fetchData() {
  try {
    const response = await fetch('https://api.tarefaai.com/api/tasks');
 
    if (response.status === 429) {
      // Usar cache antigo ou dados estáticos
      return getCachedData();
    }
 
    return await response.json();
  } catch (error) {
    // Fallback para dados locais
    return getLocalFallbackData();
  }
}

Códigos de Erro Relacionados

CódigoDescriçãoAção
429Rate limit excedidoAguardar Retry-After
402Quota excedida (upgrade)Fazer upgrade do plano
503Sistema sobrecarregadoRetry com backoff exponencial

Ferramentas de Debug

Visualizar Rate Limits

# Ver limites atuais
curl -I https://api.tarefaai.com/api/tasks \
  -H "Authorization: Bearer {token}" | grep -i ratelimit

Output:

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 85
X-RateLimit-Reset: 1674820800000

Simular Rate Limit (Dev)

Para testar como sua aplicação lida com rate limits:

# Fazer muitas requisições rápidas
for i in {1..150}; do
  curl https://api.tarefaai.com/api/tasks \
    -H "Authorization: Bearer {token}" &
done
wait

Próximos Passos


Documentação de Rate Limiting: As políticas podem mudar. Sempre consulte os headers dos responses para informações atualizadas. Referência: Implementação em /src/middleware/rate-limit.ts