Construindo Aplicações Movidas por Agentes com Next.js, Supabase & Cron em 2026

Passei o último semestre mergulhado na construção de três aplicações movidas por agentes para clientes. Duas estão totalmente ao vivo, processando autonomamente milhares de tarefas todos os dias. Então, o que está alimentando esses projetos? É a combinação formidável do Next.js implantado no Vercel, Supabase para persistência e necessidades em tempo real, e a boa e velha orquestração baseada em cron para manter os agentes alinhados e evitar excesso de taxas de API. Isso não é apenas teoria--vou decompor o que funciona, as armadilhas, e todos os insights que gostaria de ter tido antes de mergulhar.

Building Agent-Powered Apps with Next.js, Supabase & Cron in 2026

Como as Aplicações Movidas por Agentes Realmente Se Parecem em 2026

Quando falo sobre "aplicações movidas por agentes", não estou apenas discutindo um chatbot repetindo um prompt de sistema. Pense em software que lida autonomamente com tarefas multi-etapas, toma decisões orientadas por dados em tempo real, e funciona em um cronograma, tudo sem incentivo humano.

Aqui está um gostinho do que está funcionando em produção:

  • Pipelines de conteúdo que verificam feeds RSS, geram resumos, rascunham posts em redes sociais, e os colocam na fila para revisão. Este ciclo se repete a cada 30 minutos como um relógio.
  • Agentes de reconciliação de dados que se conectam a múltiplas APIs todas as noites, farejam inconsistências, tentam correções automáticas, e escalam problemas que não conseguem resolver.
  • Agentes de onboarding de clientes acionados por webhooks de novo cadastro. Esses agentes provisionam recursos, enviam sequências personalizadas, e se adaptam conforme aprendem comportamentos dos usuários.

O fio condutor? Eles precisam de persistência de estado, execução agendada, acesso a ferramentas, e uma forma de humanos espiarem e intervirem quando necessário. Esse é o ponto ideal para a stack que estamos investigando.

Por Que Essa Stack Funciona

Brinquei com outras configurações. Há LangChain emparelhado com um backend Python, Temporal para orquestração, e sistemas customizados de filas AWS. Embora todos façam o trabalho, vêm com uma montanha de complexidade operacional que a maioria dos times simplesmente não consegue lidar em 2026.

Aqui está minha comparação direta:

Stack Tempo de Setup Sobrecarga Operacional Custo em 10K tarefas/dia Melhor Para
Next.js + Supabase + Vercel Cron 1-2 dias Baixa ~$85-150/mês Maioria das apps de agentes
Python + Celery + Redis + AWS 3-5 dias Alta ~$200-400/mês Tarefas computacionais pesadas
Temporal + Custom Workers 5-10 dias Muito Alta ~$300-600/mês Fluxos de trabalho complexos
Inngest + Next.js 1-2 dias Baixa-Média ~$100-200/mês Agentes orientados por eventos

A combinação Next.js vence fácil em velocidade. Você obtém funções serverless, uma UI de dashboard, bancos de dados, autenticação, atualizações em tempo real, e execução cronometrada sem se preocupar com infraestrutura. Para a vasta maioria de nós construindo apps de agentes, isso é mais do que suficiente.

Visão Geral da Arquitetura

Vamos pintar uma imagem da arquitetura que foi um sucesso em todos os projetos:

┌─────────────────┐     ┌──────────────────┐
│   Vercel Cron    │────▶│  Next.js API Route │
│  (Scheduler)     │     │  (Agent Runner)    │
└─────────────────┘     └────────┬───────────┘
                                 │
                    ┌────────────┼────────────┐
                    ▼            ▼             ▼
              ┌──────────┐ ┌─────────┐ ┌───────────┐
              │ Supabase  │ │ LLM API │ │ External  │
              │ (State +  │ │ (OpenAI/│ │ Tools &   │
              │  Queue)   │ │ Claude) │ │ APIs      │
              └──────────┘ └─────────┘ └───────────┘
                    │
                    ▼
              ┌──────────┐
              │ Supabase  │
              │ Realtime  │──▶ Dashboard UI
              └──────────┘

Os trabalhos cron chegam a uma rota de API do Next.js, que depois extrai tarefas do Supabase, executa lógica de agente, escreve resultados de volta, e encerra. Enquanto isso, seu dashboard está de olho na ação com Supabase Realtime entregando atualizações ao vivo.

Sim, simples o suficiente, mas o diabo prospera nos detalhes.

Building Agent-Powered Apps with Next.js, Supabase & Cron in 2026 - architecture

Configurando a Fundação com Next.js e Vercel

Quando você está construindo apps de agentes em 2026, Next.js 15 com o App Router é essencial. Ele oferece os padrões de execução mais limpos graças às suas Server Actions e Route Handlers. Na Social Animal, aperfeiçoamos essa habilidade Next.js, e deixe-me dizer, o App Router amadureceu esplendidamente para projetos intensivos de backend.

Iniciar um projeto é direto:

pnpx create-next-app@latest agent-app --typescript --tailwind --app
cd agent-app
pnpm add @supabase/supabase-js ai @ai-sdk/openai

Estou utilizando o Vercel AI SDK graças à sua interface unificada em diferentes provedores de LLM. Em 2026, a versão 4.x do pacote ai suporta saídas estruturadas, chamadas de ferramentas, e streaming fora da caixa – LangChain quem?

Agora seu vercel.json precisa de sua configuração de cron assim:

{
  "crons": [
    {
      "path": "/api/agents/run",
      "schedule": "*/15 * * * *"
    },
    {
      "path": "/api/agents/cleanup",
      "schedule": "0 2 * * *"
    }
  ]
}

O primeiro cron executa o agente a cada 15 minutos. O segundo arruma a casa todas as noites. Lembre-se, Vercel Pro ($20/mês) suporta jobs cron com frequência de até 1 minuto. Mas se você estiver no plano Hobby, você é limitado a crons diários, o que simplesmente não será adequado para a maioria das necessidades movidas por agentes.

Configuração de Função Vercel

Tarefas de agentes podem ser mais longas que um filme de verão (OK, não exatamente), mas precisam de mais de 10 segundos para executar por padrão. Configure sua rota assim:

// app/api/agents/run/route.ts
export const maxDuration = 300; // 5 minutos no plano Pro
export const dynamic = 'force-dynamic';

export async function GET(request: Request) {
  // Verificar secret de cron para evitar acesso não autorizado
  const authHeader = request.headers.get('authorization');
  if (authHeader !== `Bearer ${process.env.CRON_SECRET}`) {
    return new Response('Unauthorized', { status: 401 });
  }

  // A lógica do agente vai aqui
  return Response.json({ success: true });
}

Esse maxDuration? É crucial. Até 300 segundos no Pro, e 900 segundos se você estiver nadando nas águas Enterprise. Qualquer tarefa de rotina que ultrapasse 5 minutos? Hora de segmentá-la ou repensar seu modelo de execução.

Supabase como o Cérebro do Seu Agente

Supabase--uma potência aqui. Funciona como sua fila de tarefas, armazenador de estado, registro de auditoria, e seu notificador para atualizações em tempo real. Aqui está o schema que aperfeiçoei ao longo do tempo:

-- Fila de tarefas de agente
CREATE TABLE agent_tasks (
  id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
  agent_type TEXT NOT NULL,
  status TEXT NOT NULL DEFAULT 'pending'
    CHECK (status IN ('pending', 'running', 'completed', 'failed', 'cancelled')),
  priority INTEGER DEFAULT 0,
  payload JSONB NOT NULL DEFAULT '{}',
  result JSONB,
  error TEXT,
  attempts INTEGER DEFAULT 0,
  max_attempts INTEGER DEFAULT 3,
  locked_until TIMESTAMPTZ,
  scheduled_for TIMESTAMPTZ DEFAULT NOW(),
  started_at TIMESTAMPTZ,
  completed_at TIMESTAMPTZ,
  created_at TIMESTAMPTZ DEFAULT NOW(),
  updated_at TIMESTAMPTZ DEFAULT NOW()
);

-- Índice para a query de polling da fila
CREATE INDEX idx_agent_tasks_queue ON agent_tasks (
  agent_type, status, priority DESC, scheduled_for
) WHERE status = 'pending';

-- Logs de execução de agente para observabilidade
CREATE TABLE agent_logs (
  id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
  task_id UUID REFERENCES agent_tasks(id),
  level TEXT NOT NULL DEFAULT 'info',
  message TEXT NOT NULL,
  metadata JSONB DEFAULT '{}',
  created_at TIMESTAMPTZ DEFAULT NOW()
);

-- Persistência de estado do agente (para agentes multi-etapa)
CREATE TABLE agent_state (
  id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
  agent_type TEXT NOT NULL,
  agent_instance_id TEXT NOT NULL,
  state JSONB NOT NULL DEFAULT '{}',
  updated_at TIMESTAMPTZ DEFAULT NOW(),
  UNIQUE(agent_type, agent_instance_id)
);

Essa coluna locked_until? É chave. Ela imita um bloqueio distribuído caseiro. Isso significa que quando um trabalho cron pega uma tarefa, ela define locked_until para frente por 5 minutos. Se o processo quebra, o bloqueio expira, e outro ciclo pode dar outra volta.

A Query de Coleta de Tarefas

A joia da coroa. Este é seu bilhete de ouro para capturar tarefas sem reprocessamento:

import { createClient } from '@supabase/supabase-js';

const supabase = createClient(
  process.env.SUPABASE_URL!,
  process.env.SUPABASE_SERVICE_ROLE_KEY!
);

async function claimTasks(agentType: string, limit: number = 5) {
  const { data: tasks, error } = await supabase
    .rpc('claim_agent_tasks', {
      p_agent_type: agentType,
      p_limit: limit,
      p_lock_duration: '5 minutes'
    });

  if (error) throw error;
  return tasks;
}

E a função Postgres correspondente:

CREATE OR REPLACE FUNCTION claim_agent_tasks(
  p_agent_type TEXT,
  p_limit INTEGER,
  p_lock_duration INTERVAL
)
RETURNS SETOF agent_tasks AS $$
BEGIN
  RETURN QUERY
  UPDATE agent_tasks
  SET
    status = 'running',
    locked_until = NOW() + p_lock_duration,
    started_at = NOW(),
    attempts = attempts + 1,
    updated_at = NOW()
  WHERE id IN (
    SELECT id FROM agent_tasks
    WHERE agent_type = p_agent_type
      AND status = 'pending'
      AND scheduled_for <= NOW()
      AND (locked_until IS NULL OR locked_until < NOW())
      AND attempts < max_attempts
    ORDER BY priority DESC, scheduled_for ASC
    LIMIT p_limit
    FOR UPDATE SKIP LOCKED
  )
  RETURNING *;
END;
$$ LANGUAGE plpgsql;

O FOR UPDATE SKIP LOCKED é o herói desconhecido aqui. Garante que nenhuma invocação concorrente pisa nos dedos da outra. Acredite em mim, descobrir e corrigir processamento duplo não foi uma gargalhada.

Orquestração de Agente Baseada em Cron

Vercel Cron é o batimento constante de toda essa operação. A cada 15 minutos, seu agent runner salta em ação, agarra tarefas, processa-as, e depois adormece até a próxima chamada.

Aqui está como a rota completa do agent runner se parece:

// app/api/agents/run/route.ts
import { claimTasks, completeTask, failTask, logAgent } from '@/lib/agents';
import { runContentAgent } from '@/lib/agents/content';
import { runReconciliationAgent } from '@/lib/agents/reconciliation';

export const maxDuration = 300;

const AGENT_RUNNERS: Record<string, (task: AgentTask) => Promise<any>> = {
  'content-pipeline': runContentAgent,
  'data-reconciliation': runReconciliationAgent,
};

export async function GET(request: Request) {
  const authHeader = request.headers.get('authorization');
  if (authHeader !== `Bearer ${process.env.CRON_SECRET}`) {
    return new Response('Unauthorized', { status: 401 });
  }

  const results = { processed: 0, failed: 0, skipped: 0 };

  for (const [agentType, runner] of Object.entries(AGENT_RUNNERS)) {
    const tasks = await claimTasks(agentType, 5);

    for (const task of tasks) {
      try {
        await logAgent(task.id, 'info', `Starting ${agentType} task`);
        const result = await runner(task);
        await completeTask(task.id, result);
        results.processed++;
      } catch (error) {
        const message = error instanceof Error ? error.message : 'Unknown error';
        await failTask(task.id, message);
        await logAgent(task.id, 'error', message);
        results.failed++;
      }
    }
  }

  return Response.json(results);
}

Observe o processamento sequencial por tipo de agente, com um limite de 5 tarefas por tipo por execução. Isso ajuda a manter os tempos de execução da função sob controle. Tem uma pilha de 50 tarefas pendentes? Distribua-as ao longo de vários ciclos de cron. Sem pressa, sem problema.

Quando Cron Não É Suficiente

Às vezes, a vida vem rápido, e cron simplesmente não corta. Nesses casos, integro cron com Webhooks de Banco de Dados Supabase ou Edge Functions--eles disparam acionados por mudanças de banco de dados:

-- Disparar uma edge function quando uma tarefa de alta prioridade é criada
CREATE OR REPLACE FUNCTION notify_urgent_task()
RETURNS TRIGGER AS $$
BEGIN
  IF NEW.priority > 5 THEN
    PERFORM net.http_post(
      url := 'https://your-app.vercel.app/api/agents/urgent',
      headers := jsonb_build_object(
        'Authorization', 'Bearer ' || current_setting('app.webhook_secret')
      ),
      body := jsonb_build_object('task_id', NEW.id)
    );
  END IF;
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

Essa configuração permite misturar processamento previsível baseado em cron com resposta rápida para tarefas urgentes.

Construindo o Loop do Agente

Aqui é onde a mágica acontece. Uma implementação de agente de exemplo usando o chamamento de ferramenta do Vercel AI SDK:

// lib/agents/content.ts
import { generateText, tool } from 'ai';
import { openai } from '@ai-sdk/openai';
import { z } from 'zod';
import { supabase } from '@/lib/supabase';

export async function runContentAgent(task: AgentTask) {
  const { sourceUrl, targetPlatform } = task.payload;

  const { text, toolCalls, usage } = await generateText({
    model: openai('gpt-4o-mini'),
    system: `You are a content processing agent. Fetch the source content,
    analyze it, and generate appropriate social media content for ${targetPlatform}.
    Use the provided tools to complete your task.`,
    prompt: `Process this source: ${sourceUrl}`,
    tools: {
      fetchContent: tool({
        description: 'Fetch content from a URL',
        parameters: z.object({ url: z.string().url() }),
        execute: async ({ url }) => {
          const res = await fetch(url);
          const html = await res.text();
          // Strip HTML, extract main content
          return extractMainContent(html);
        },
      }),
      saveContent: tool({
        description: 'Save generated content for review',
        parameters: z.object({
          title: z.string(),
          body: z.string(),
          platform: z.string(),
          suggestedPostTime: z.string(),
        }),
        execute: async (content) => {
          const { data, error } = await supabase
            .from('generated_content')
            .insert({
              ...content,
              task_id: task.id,
              status: 'pending_review',
            })
            .select()
            .single();

          if (error) throw error;
          return { saved: true, id: data.id };
        },
      }),
    },
    maxSteps: 5, // Permitir até 5 rodadas de chamamento de ferramenta
  });

  return {
    summary: text,
    toolCallCount: toolCalls.length,
    tokensUsed: usage.totalTokens,
  };
}

Configurar maxSteps para 5 permite que o LLM chame ferramentas, avalie resultados, e processe adequadamente--como uma pequena abelha trabalhadora fazendo seu trabalho. A maioria das tarefas de conteúdo termina em 3–4 dessas chamadas.

Monitoramento de Agentes em Tempo Real com Supabase Realtime

Agentes autônomos são ótimos, mas mantê-los sob controle é fundamental. Supabase Realtime alimenta um dashboard que se atualiza em tempo real conforme os agentes fazem as coisas:

// components/AgentDashboard.tsx
'use client';

import { useEffect, useState } from 'react';
import { createClient } from '@supabase/supabase-js';

const supabase = createClient(
  process.env.NEXT_PUBLIC_SUPABASE_URL!,
  process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
);

export function AgentDashboard() {
  const [tasks, setTasks] = useState<AgentTask[]>([]);
  const [logs, setLogs] = useState<AgentLog[]>([]);

  useEffect(() => {
    // Inscrever em mudanças de tarefas
    const taskChannel = supabase
      .channel('agent-tasks')
      .on(
        'postgres_changes',
        { event: '*', schema: 'public', table: 'agent_tasks' },
        (payload) => {
          setTasks(prev => {
            const updated = [...prev];
            const idx = updated.findIndex(t => t.id === payload.new.id);
            if (idx >= 0) updated[idx] = payload.new as AgentTask;
            else updated.unshift(payload.new as AgentTask);
            return updated.slice(0, 50);
          });
        }
      )
      .subscribe();

    // Inscrever no fluxo de logs
    const logChannel = supabase
      .channel('agent-logs')
      .on(
        'postgres_changes',
        { event: 'INSERT', schema: 'public', table: 'agent_logs' },
        (payload) => {
          setLogs(prev => [payload.new as AgentLog, ...prev].slice(0, 100));
        }
      )
      .subscribe();

    return () => {
      supabase.removeChannel(taskChannel);
      supabase.removeChannel(logChannel);
    };
  }, []);

  // Renderizar sua UI de dashboard...
}

Isso entrega um fluxo ao vivo de atividade do agente. Comumente, eu adicionaria indicadores, contagens de tarefas, visuais de taxa de erro, e até um botão "executar agora" para testes. Supabase Realtime está incluído no tier gratuito--nenhum custo extra necessário.

Lidando com Falhas e Casos Extremos

Prepare-se--algo vai explodir. APIs desaparecem, limites de taxa o acertam na cara, ou serviços apenas enviam de volta nonsense. Aqui está o que aprendi sobre fazer sistemas que sobrevivem.

Retry com Backoff Exponencial

As colunas attempts e max_attempts que incorporamos lidam com retentativas. Se uma tarefa falha, ela fica em status 'failed' mas pode ser definida para tentar novamente manualmente ou automaticamente depois:

async function failTask(taskId: string, error: string) {
  const { data } = await supabase
    .from('agent_tasks')
    .select('attempts, max_attempts')
    .eq('id', taskId)
    .single();

  const shouldRetry = data && data.attempts < data.max_attempts;

  await supabase
    .from('agent_tasks')
    .update({
      status: shouldRetry ? 'pending' : 'failed',
      error,
      locked_until: null,
      // Backoff exponencial: 1min, 4min, 9min...
      scheduled_for: shouldRetry
        ? new Date(Date.now() + Math.pow(data.attempts, 2) * 60000).toISOString()
        : undefined,
      updated_at: new Date().toISOString(),
    })
    .eq('id', taskId);
}

Disjuntores para APIs Externas

Quando APIs externas falham, retentativas imediatas comem retentativas rápido. Acompanhe as taxas de falha em Supabase, e você pode parar os agentes se as coisas parecerem sombrias:

async function checkCircuitBreaker(service: string): Promise<boolean> {
  const fiveMinutesAgo = new Date(Date.now() - 300000).toISOString();

  const { count } = await supabase
    .from('agent_logs')
    .select('*', { count: 'exact', head: true })
    .eq('level', 'error')
    .ilike('message', `%${service}%`)
    .gte('created_at', fiveMinutesAgo);

  return (count ?? 0) < 10; // Disparar se mais de 10 erros em 5 min
}

Análise de Custo e Otimização

Aqui é onde falamos sério. Quanto custa uma app de agente em produção em 2026?

Componente Tier Gratuito Produção Típica Uso Pesado
Vercel Pro - $20/mês $20/mês + uso
Supabase Pro - $25/mês $25/mês + uso
OpenAI (GPT-4o-mini) - $30-80/mês $200+/mês
Anthropic (Claude 3.5 Haiku) - $20-50/mês $150+/mês
Total ~$0 (dev) $95-175/mês $395+/mês

Essas taxas de LLM? Elas dirigem o show. Aqui está como você as mantém sob controle:

  1. Use modelos menores onde possível. GPT-4o-mini e Claude 3.5 Haiku lidam com a maioria das tarefas a uma fração do custo de seus parentes maiores.
  2. Cache antes de alcançar a API. Supabase pode guardar respostas de LLM, reduzindo novas chamadas de API.
  3. Lote, lote, lote. Em vez de uma chamada de API por tarefa, lote tarefas similares e envie-as juntas.
  4. Limites de token? Sim, por favor. Sempre defina maxTokens durante suas chamadas do AI SDK--prevenha geração desenfreada.

Padrões de Implantação em Produção

Uma vez que você esteja se preparando para implantação, várias coisas são críticas:

Separação de ambientes. Aproveite o branching do Supabase (Pro necessário) para manter bancos de dados discretos para staging e produção. Combine implantações de preview do Vercel com branches do Supabase para isolamento total.

Monitoramento. A observabilidade do Vercel fornece histórico de execução de cron e logs de funções. Combine isso com uma verificação de saúde do Supabase:

SELECT
  agent_type,
  status,
  COUNT(*) as count,
  AVG(EXTRACT(EPOCH FROM (completed_at - started_at))) as avg_duration_seconds
FROM agent_tasks
WHERE created_at > NOW() - INTERVAL '24 hours'
GROUP BY agent_type, status
ORDER BY agent_type, status;

Gerenciamento de secrets. Proteja suas chaves de API com variáveis de ambiente do Vercel, nunca as codifique. Use a chave de função de serviço apenas no lado do servidor com Supabase, mantendo a chave anon no lado do cliente.

Se você precisar de assistência configurando sistemas como esse, nosso time entregou múltiplas aplicações movidas por agentes usando exatamente essa stack. Confira nossas capacidades de desenvolvimento de headless CMS e desenvolvimento Next.js, ou entre em contato para conversar sobre seu projeto.

FAQ

O Vercel Cron pode lidar com tarefas de agente de alta frequência?


Vercel Cron pode gerenciar intervalos tão curtos quanto 1 minuto no plano Pro. A maioria das tarefas de agente se adequam a ciclos de 5-15 minutos. Precisa mais rápido? Considere Webhooks de Banco de Dados Supabase ou mude para Inngest para ações orientadas por eventos.

Como evito processamento duplicado de tarefas com cron?


É aí que o FOR UPDATE SKIP LOCKED do PostgreSQL brilha em sua query de reivindicação de tarefas. É sua rede de segurança mesmo se os timings de cron se sobrepuserem, garantindo que cada tarefa seja reivindicada unicamente. locked_until adiciona uma camada de segurança se desastres de execução em andamento ocorrem.

Supabase é confiável para cargas de trabalho de agentes em produção?


Absolutamente. Supabase Pro funciona em instâncias Postgres dedicadas com backups automatizados e um SLA de uptime de 99,9%. Na verdade, para esse sistema de fila de tarefas, Postgres é mais que qualificado--capaz de lidar com acesso concorrente e queries complexas facilmente.

Quanto custa executar agentes de IA em produção?


Tipicamente, processar 5.000-10.000 tarefas diárias custará entre $95-175/mês (Vercel Pro + Supabase Pro) mais $30-80/mês para chamadas de API de LLM usando modelos como GPT-4o-mini. A camada variável é seu custo de LLM--dependendo da complexidade da tarefa e uso de tokens.

Devo usar LangChain ou o Vercel AI SDK para lógica de agente?


Em 2026, o Vercel AI SDK (v4.x) cobre a maioria das necessidades de agentes nativamente--uso de ferramentas, raciocínio multi-etapa, saídas estruturadas, e streaming. LangChain se torna útil quando você se aprofunda em padrões avançados de cadeia de pensamento, configurações de RAG, ou integrações especializadas de ferramentas. Para essa stack, menos complexidade com o AI SDK reina suprema.

Posso usar Astro em vez de Next.js para esse padrão?


Astro pode lidar com rotas de API acionadas por cron, mas você perde as otimizações do Vercel, incluindo configuração de cron e timeouts mais longos. Se seu dashboard prefere conteúdo-pesado, baixa interatividade, Astro se adequa ao frontend. Fique com Next.js para seu backend de agente.

Como monitoro desempenho de agentes e falhas?


Mescle três camadas: logs do Vercel para insight no nível de execução, a tabela agent_logs em Supabase para rastreamento de logs de aplicação, e Supabase Realtime para monitoramento de dashboard dinâmico. Estabeleça verificações de saúde para falhas, tempos de execução, e comprimento da fila. Vercel sincroniza perfeitamente com serviços de alertas como PagerDuty e Slack.

O que acontece quando minhas tarefas de agente excedem o timeout de função do Vercel?


No Vercel Pro, você tem um teto de 300 segundos. Se tarefas frequentemente ultrapassam isso, considere quebrá-las em subtarefas pequenas em ciclos de cron. Por exemplo, divida um processo de conteúdo em tarefas de "buscar", "analisar", e "gerar". Ou, explore Supabase Edge Functions para execuções estendidas--elas têm um limite de 150 segundos e podem ser acionadas conforme necessário.