Skip to content

14 — Realtime e jobs background: custo silencioso

Pergunta: subscriptions realtime e crons rodam o tempo todo. Eles custam quanto? Algum está mal-dimensionado?

Realtime: subscriptions ativas

Grep em src/:

  • useRealtimePresence.ts
  • useRealtimeNotificacoes.ts
  • useFeatureLocksRealtime.ts
  • useFeatureFlagSync.ts

Custo:

  • Cada cliente abre WebSocket persistente → carga linear no Realtime do Supabase.
  • postgres_changes exige tabela na supabase_realtime publication + REPLICA IDENTITY FULL (cf. core memory). Validar:
    • feature_locks, notificacoes, feature_flags — confirmadas na publication?
  • Risco: tabela na publication com REPLICA IDENTITY FULL paga overhead em toda escrita (registra row completo no WAL). Não usar em tabelas de alto write (logs_transacoes, resultados_aluno).

Hipóteses Realtime

  • H1: Multi-aba aberta (coord trabalhando) abre N WebSockets — somar com 50 coords simultâneos × 3 abas = 150 conexões persistentes. Plano Realtime suporta — confirmar limite no plano atual.
  • H2: Algum hook está reconectando em loop (sem cleanup correto no useEffect) — checar via browser--list_network_requests com filtro wss.
  • H3: Notificações realtime estão duplicando refetch que React Query já faria — verificar se a subscription só dispara invalidateQueries ou se também faz fetch direto.

Crons (cron_status + pg_cron)

Funções com sufixo -cron ou jobs agendados:

  • maintenance-cron
  • healthcheck-cron
  • faturamento-cron (gera faturas mensais)
  • process-email-outbox (visto nos logs recentes)
  • admin-cron-monitor (UI)

Custos:

  • Cada job consome connection pool. Pico de horário cheio (00:00) com múltiplos crons simultâneos pode saturar.
  • process-email-outbox roda a cada 1 min (provável). Em escolas pequenas a fila está vazia 99% das vezes — leituras ociosas no banco.

Hipóteses Crons

  • H1: Sobreposição de cron 00:00 (faturamento + retention + healthcheck) gera pico de DB load — escalonar (00:01, 00:05, 00:10).
  • H2: process-email-outbox polling 1 min é OK enquanto o outbox é pequeno; quando passar de 1k, vira N+1 por batch — confirmar se já bulk INSERT/UPDATE.
  • H3: Jobs não têm watchdog — se um deles trava em I/O, o próximo agendamento empilha em vez de pular.

Próximas etapas

  • Listar todos os jobs pg_cron: select jobname, schedule, command from cron.job order by jobname.
  • Medir duração média via cron.job_run_details: select jobname, avg(end_time - start_time) from cron.job_run_details group by 1 order by 2 desc.
  • Validar supabase_realtime publication: select schemaname, tablename from pg_publication_tables where pubname = 'supabase_realtime'.
  • mem://architecture/edge-function-background-task-standard
  • mem://security/realtime-messages-rls-standard
  • Core memory: "Realtime delivery" + "Edge Functions" (testes em __tests__/)