Nesta página

Criar um Cron Worker

Você cria um cron worker a partir do dashboard de qualquer projeto. Abra o projeto, clique em Criar novo e escolha Cron Worker. O wizard te leva por três etapas curtas.

O wizard

  1. Schedule e timezone. Dê um nome ao worker (1–100 caracteres), digite uma expressão cron e escolha o timezone em que o schedule deve rodar.

  2. Destino. Escolha um dos seis tipos de destino e preencha sua configuração específica.

  3. Payload, timeout e retentativas. Forneça um payload JSON opcional, defina o timeout por tentativa em segundos e escolha quantas retentativas as tentativas falhas devem receber.

Ao clicar em Criar, o worker fica ativo imediatamente e o primeiro disparo agendado acontece no próximo slot.

Etapa 1 — Schedule e timezone

O campo de schedule aceita a sintaxe cron padrão — cinco campos (minuto hora dia-do-mês mês dia-da-semana). O wizard valida a expressão enquanto você digita e mostra logo abaixo o próximo disparo programado.

ExemploSignificado
0 * * * *Toda hora cheia
*/15 * * * *A cada 15 minutos
0 9 * * *Todo dia às 9:00
0 9 * * 1-5Dias úteis às 9:00
30 3 1 * *No dia 1 de todo mês às 3:30
0 0 * * 0Aos domingos à meia-noite

O timezone é um identificador da base IANA (por exemplo, America/Sao_Paulo, UTC, Europe/Lisbon). O wizard valida o valor e sugere correções para erros comuns como Sao_Paulo.

Etapa 2 — Destino

Escolha um dos seis tiles. Cada destino tem sua configuração própria — veja Tipos de destino para a referência completa.

Etapa 3 — Payload, timeout e retentativas

Payload

O payload é um objeto JSON opcional, enviado tal qual em todo disparo. Vazio ({}) é permitido.

{
  "job": "rotate-uploads",
  "max_age_hours": 24,
  "dry_run": false
}

Limites:

  • Precisa ser um objeto JSON (não um array, não um valor primitivo).
  • Tamanho máximo: 64 KiB serializado.
  • O wizard mostra a contagem de bytes em tempo real e avisa quando você se aproxima do limite.

Timeout

O tempo máximo que uma única tentativa pode rodar antes de ser considerada falha. Faixa: 5–300 segundos, padrão 30 segundos. O timeout vale por tentativa individual — cada retentativa ganha a janela completa.

Escolha um valor que comporte bem o tempo típico de processamento do destino. Se o seu endpoint HTTP normalmente responde em 2 segundos, um timeout de 30 segundos te dá folga para a execução ocasional mais lenta sem deixar requisições realmente travadas segurando o slot.

Máximo de retentativas

Quantas vezes uma tentativa que falhou deve ser refeita antes de desistir. Faixa: 1–5, padrão 3. As retentativas usam backoff exponencial com jitter para evitar sincronizar com outros clientes.

Depois de criar

Você cai na página de detalhe do worker com:

  • Um badge de status (active, suspended ou deleted).
  • Um contador ao vivo até o próximo disparo agendado.
  • Um resumo da última execução.
  • A tabela completa de histórico de execuções (mais novo primeiro, paginada).
  • Botões de ação: Disparar agora, Pausar / Retomar, Editar destino, Excluir.

Veja Monitoramento e execuções para o que cada um deles faz e como investigar falhas.

Pela CLI

O comando guara crons create -f <file> aceita um arquivo de spec YAML ou JSON com a mesma forma do body da API. Passe -f spec.yaml (ou .json) e a CLI valida localmente antes de enviar — qualquer 400 com issues de Zod por campo é impresso de forma amigável, com a chave problemática em negrito.

guara crons create -f cron.yaml
guara crons create -f cron.yaml --project meu-projeto --json
guara crons update hourly -f patch.yaml

O destination_ref é uma união discriminada — os campos obrigatórios variam conforme o destination_type. O serviceEndpointId (HTTP) e o catalogServiceId (todos os outros) são UUIDs que você consegue via guara services list --json e guara services info --json no serviço alvo.

HTTP

name: Hourly cleanup job
schedule: '0 * * * *'
timezone: UTC
destination_type: http
destination_ref:
  type: http
  serviceEndpointId: 1d6e9a0a-2c7b-4a1c-b8a9-2f6d4f7b6e10
  path: /jobs/cleanup-stale-uploads
  headers:
    X-Job-Source: cron
    X-Tenant: acme
payload_template:
  job: rotate-uploads
  max_age_hours: 24
  dry_run: false
timeout_seconds: 30
max_retries: 3

O cron worker sempre faz POST com o payload JSON no corpo e Content-Type: application/json. A plataforma define Traceparent e Tracestate automaticamente; headers reservados (Authorization, Cookie, Host, etc.) não podem ser sobrescritos — veja Tipos de destino → HTTP.

NATS

name: Daily digest publisher
schedule: '0 7 * * *'
timezone: America/Sao_Paulo
destination_type: nats
destination_ref:
  type: nats
  catalogServiceId: 9b2f0a5e-3d4c-4f8b-a0c1-7e6d5b4a3c20
  subject: jobs.daily-digest
payload_template:
  template: monthly-summary
  audience: all-users
timeout_seconds: 30
max_retries: 3

Redis

name: Cache warm-up
schedule: '*/15 * * * *'
timezone: UTC
destination_type: redis
destination_ref:
  type: redis
  catalogServiceId: 5a8d7c6b-1e2f-4a3d-9c8b-7f6e5d4c3b21
  channel: cache:warmup
payload_template:
  keys:
    - homepage
    - pricing
    - docs-index
timeout_seconds: 15
max_retries: 2

Valkey

name: Session sweep
schedule: '*/10 * * * *'
timezone: UTC
destination_type: valkey
destination_ref:
  type: valkey
  catalogServiceId: 7c9b1a2d-4e5f-6a7b-8c9d-0e1f2a3b4c52
  channel: sessions:sweep
payload_template:
  before_age_minutes: 60
timeout_seconds: 15
max_retries: 2

RabbitMQ

name: Reports kick-off
schedule: '0 4 * * *'
timezone: UTC
destination_type: rabbitmq
destination_ref:
  type: rabbitmq
  catalogServiceId: 4d8e1c2b-3a5f-4b6c-9d8e-1f2a3b4c5d63
  exchange: reports
  routingKey: reports.daily
  requireRoutable: true
payload_template:
  report: daily-revenue
  format: parquet
timeout_seconds: 60
max_retries: 3

Use requireRoutable: true para fazer a execução falhar de forma explícita quando nenhuma fila estiver bound ao exchange/routing key. Omita (ou use false) para um fan-out fire-and-forget.

Postgres NOTIFY

name: Job queue ping
schedule: '*/5 * * * *'
timezone: UTC
destination_type: postgres
destination_ref:
  type: postgres
  catalogServiceId: 2e6f8a1b-9c0d-4e1f-8a2b-3c4d5e6f7a84
  channel: jobs_pending
payload_template:
  hint: scan-now
timeout_seconds: 10
max_retries: 1

A plataforma envolve o payload JSON em um pequeno envelope _meta com o ID do run e um traceparent W3C antes de executar o NOTIFY — os listeners recebem esse envelope como string. Veja Tipos de destino → Postgres NOTIFY para a forma exata do wrapper e o limite de 8 KB do Postgres.