Skip to content

13 — logs_transacoes: a tabela que cresce mais rápido que tudo

Pergunta: o sistema de logging em si é auto-escalável? logs_transacoes é a tabela com maior taxa de inserção da plataforma — quando ela vira o gargalo?

Por que isso é diferente das outras

logs_transacoes recebe um INSERT por CUD em qualquer parte da plataforma (cf. mem://architecture/observability-and-logging-standard). Crescimento real:

  • 1 escola média: ~500 CUDs/dia → ~15k/mês.
  • 100 escolas: 1.5M/mês → 18M/ano.
  • Sem retenção/particionamento, a tabela ultrapassa 50M em < 3 anos.

Quem lê

10 edge functions diferentes consultam logs_transacoes:

admin-dashboard       admin-cron-monitor       maintenance-cron
admin-comunicacao     verify-password          user-profile
admin-logs            healthcheck-cron         admin-financeiro

A tela admin-logs é o consumer mais intenso (filtros por módulo + intervalo de data + escola + usuário).

Riscos por camada

Escrita (fire-and-forget)

Padrão atual (cf. mem) é EdgeRuntime.waitUntil(insert). Bom — não bloqueia Response. Mas:

  • Sob pico de CUD (importação de 5k alunos), gera 5k INSERTs em poucos segundos.
  • pg_stat_statements vai mostrar INSERT INTO logs_transacoes como o top query.
  • Hipótese: já estamos perto do limite de I/O de write em escolas de pico.

Leitura

  • admin-logs filtra por (escola_id, created_at desc) + modulo — precisa índice composto, ver 09.
  • Filtros JSONB em payload/diff são caros — confirmar GIN index se forem usados.

Retenção

Não há job de retenção/arquivamento visível. Toda linha vive para sempre.

  • LGPD: logs com PII (já mascarada — cf. mem://security/pii-log-masking-standard) ainda assim devem ter TTL.
  • Performance: particionar por mês (PARTITION BY RANGE (created_at)) reduz custo de scan e permite DROP PARTITION antigo barato.

Hipóteses

  • H1: admin-logs em prod já demora >2s para abrir — não por falta de índice em si, mas por size of relation (table bloat sem retenção).
  • H2: Inserções em pico de importação contribuem para latência fora do Resultados, percebida como "geral lenta" — efeito sistêmico.
  • H3: A próxima crise de performance vai ser admin-logs, não Resultados.

Padrão recomendado (proposta, sem implementar)

  1. Particionamento mensal de logs_transacoes por created_at (estratégia pg_partman ou nativa).
  2. Retenção de 12 meses online + arquivamento (S3/storage) para meses anteriores.
  3. Índice composto (escola_id, modulo, created_at desc).
  4. Quota por escola opcional (não emitir log de cada PATCH trivial — gatilhar só CUD com impacto).
  5. Sampling em ações de altíssima frequência (page_view, heartbeat) — não logar 100%.

Próximas etapas (auditoria, não fix)

  • Medir tamanho atual da tabela: select pg_size_pretty(pg_total_relation_size('public.logs_transacoes')).
  • Top 10 ações por contagem em 30 dias: select acao, count(*) from logs_transacoes where created_at > now() - interval '30 days' group by 1 order by 2 desc limit 10.
  • Verificar se há índice em created_at simples (não composto): select indexdef from pg_indexes where tablename = 'logs_transacoes'.