Back-End

26 mar, 2026

Event-driven architecture na prática: onde dá ruim

Publicidade

Event-driven architecture é linda no papel. Desacoplada, escalável e reativa.

Na prática? Nem sempre. Porque o problema não é publicar eventos. É lidar com o que acontece depois.

O fluxo que parece simples

Você tem um fluxo clássico: Pedido criado, pagamento processado e notificação enviada.

Em arquitetura orientada a eventos, isso vira algo assim:

await eventBus.publish('order_created', order);

E aí:

Payment-service consome, notification-service consome e analytics consome

Perfeito.

Até dar problema.

O primeiro choque: você perdeu o controle do fluxo

No monólito, o fluxo é explícito. Em event-driven, ele é implícito.

Você dispara um evento. E… torce.

Não existe mais garantia de ordem clara. Não existe mais caminho único.

E quando algo quebra… Você não sabe exatamente onde.

Debugging deixa de ser técnico

Vira investigativo. Você começa com um bug: “Pedido não foi cobrado”

Agora precisa descobrir: Evento foi publicado? Foi consumido? Falhou? Reprocessou? Duplicou?

Exemplo real:

consumer.run({
  eachMessage: async ({ message }) => {
    const order = JSON.parse(message.value);

    await processPayment(order);
  }
});

Parece simples. Mas se processPayment falhar? Você não sabe se o evento vai ser reprocessado, se vai ser perdido ou vai gerar efeito duplicado.

Agora você não está debugando código. Você está reconstruindo uma linha do tempo.

Inconsistência de dados deixa de ser exceção

Vira padrão. Exemplo clássico:

// order-service
await db.insert(order);
await eventBus.publish('order_created', order);

E no outro lado:

// payment-service
consumer.run({
  eachMessage: async ({ message }) => {
    const order = JSON.parse(message.value);

    await charge(order);
  }
});

Agora imagina:

Evento chega antes da base estar consistente, serviço lê dado incompleto ou falha no meio do processamento

Resultado: Estado inconsistente. E isso não é bug raro. É comportamento esperado.

Idempotência: o retrabalho obrigatório

Se você usa eventos, você precisa aceitar uma coisa: Eventos podem ser processados mais de uma vez.

Então você precisa fazer isso:

async function processPayment(order) {
  const alreadyProcessed = await db.findPayment(order.id);

  if (alreadyProcessed) return;

  await paymentGateway.charge(order);
}

Funciona. Mas agora você adicionou mais query, mais lógica e mais pontos de falha. Tudo isso para lidar com duplicidade. E isso vai se repetir em vários serviços.

Ordem de eventos: a armadilha silenciosa

Você assume que eventos chegam na ordem certa. Mas nem sempre chegam.

Exemplo:

order_created
order_cancelled

Agora imagina chegar assim:

order_cancelled
order_created

Seu sistema pode: cobrar um pedido cancelado ou até reativar algo que não deveria

E aí? Você precisa de controle de versão.

if (event.version < currentVersion) return;

Mais complexidade. Mais estado. Mais chance de erro.

Latência invisível

Event-driven adiciona latência. Você publica. E espera o processamento. Exemplo:

await createOrder(order);

// depende de evento para continuar fluxo

O usuário não vê imediatamente. Ou vê comportamento inconsistente.

E aí começa: “Mas no meu sistema funciona…”

Até não funcionar.

O efeito dominó

Um serviço falha. Fila acumula. Outro serviço atrasa. E de repente: Sistema inteiro degradado.

Você não tem mais falha isolada. Tem falha distribuída.

Ou seja, observabilidade não é opcional. Sem isso, esquece.

Você precisa de: Correlation ID, Tracing distribuído e Logs centralizados

Exemplo:

const event = {
  id: uuid(),
  correlationId,
  type: 'order_created',
  payload: order
};

Sem isso… Você está cego.

O custo que ninguém considera

Event-driven não é só arquitetura. É operação contínua.

Você precisa manter:

  • Broker
  • Consumers
  • Monitoramento
  • Retries
  • Dead letter queues

E cada item desses pode falhar.

Quando faz sentido de verdade

Event-driven funciona bem quando:

  • Você tem alto volume de eventos
  • Múltiplos consumidores independentes
  • Processamento assíncrono real
  • Necessidade de desacoplamento forte

Tipo: Streaming, Analytics e Sistemas altamente distribuídos

Fora disso… Pode ser exagero.

O ponto que ninguém fala

Event-driven não simplifica. Ele troca tipo de complexidade. Sai o fluxo explícito e entra o comportamento emergente. E comportamento emergente é mais difícil de controlar.

Ou seja, Event-driven architecture funciona. Mas cobra caro em debugging, em consistência e em complexidade.

E se você não precisa disso ainda… Provavelmente está pagando esse custo sem necessidade. Porque no fim…

Publicar evento é fácil. Difícil é viver com ele em produção.