Dois engenheiros revisam diagrama de arquitetura de microsserviços com dependências em cascata em monitor wall-mounted

O microsserviço que nunca deveria ter existido

TL;DR

  • Medo de indisponibilidade que vira premissa arquitetural — microsserviço justificado por medo de indisponibilidade é, com frequência, a origem da indisponibilidade que justificou a quebra. O MTTR do pior caso do billing estudado subiu de 18 minutos para 3 horas e 12 minutos entre 2023 e 2025.
  • Custo composto das dependências distribuídas — a decomposição de uma função coesa troca custo fixo (um deploy coordenado) por custo composto (N deploys com dependências versionadas). O custo composto cresce com N ao quadrado, não com N.
  • Lei de Conway ao contrário — o organograma molda a arquitetura, e a arquitetura reforça o organograma. Equipe nova com budget próprio clama por microsserviço. O monolito bem fatorado raramente pede.
  • Três sinais que abortam a quebra antes do primeiro deploy — ausência de bounded context limpo, plataforma interna sem SLO por serviço, e observabilidade fim-a-fim sem tracing distribuído. Se algum dos três faltar, microsserviço é postergação disfarçada.
  • Decisão certa, decisão errada, e a zona intermediária — microsserviço é a decisão certa quando plataforma interna é madura, custo composto é dominado pelo ganho de autonomia, e o sistema decai graciosamente sem fallback coordenado. Sem os três, monolito bem fatorado vence.

~ 14 min de leitura · 2384 palavras

O microsserviço que não deveria ter existido: o caso do billing

O sistema estudado atende aproximadamente 4,2 milhões de clientes ativos e processa em torno de 28 mil transações por segundo em horário de pico. A motivação declarada para a primeira quebra em microsserviço, registrada em ata de arquitetura de novembro de 2023, foi “reduzir blast radius de queda”. O blast radius inicial era um monolito de billing escrito em Python 3.11 sobre FastAPI, com 187 mil linhas de código, fatorado em 12 módulos coesos, com cobertura de testes de 78% e tempo médio de deploy de 11 minutos.

O blast radius de fato era grande. O monolito rodava em 32 instâncias atrás de um load balancer, e a queda do serviço derrubava todas as funcionalidades que dependiam de billing simultaneamente: assinatura, cobrança, retry, refund, antifraude, e o painel administrativo. A indisponibilidade era visível. A métrica de SLO de 99,95% foi batida em 9 dos 12 meses de 2023, com os três meses restantes coincidindo com deploys de features grandes. O MTTR médio do período foi 8 minutos, e o pior caso, 18 minutos. A média era boa. O pior caso era o problema declarado.

A primeira quebra extraiu três microsserviços: subscription, invoicing e retry-orchestrator. Cada um recebeu seu próprio repositório, seu próprio pipeline, e sua própria infraestrutura. A promessa era que o blast radius caísse: uma queda no retry-orchestrator não derrubaria mais o invoicing. A promessa foi cumprida em parte. O blast radius do retry-orchestrator caiu de 100% do monolito para 18% do tráfego. O MTTR médio do retry-orchestrator caiu para 4 minutos, e o pior caso, para 9 minutos. A média do billing agregado, porém, subiu de 8 para 12 minutos, e o pior caso agregado subiu de 18 minutos para 41 minutos.

A razão da divergência entre o subsistema e o agregado é o custo composto das dependências entre microsserviços. Uma queda do invoicing passou a afetar o retry-orchestrator, que por sua vez afetava o subscription, que por sua vez bloqueava o painel administrativo. A cascata que o monolito evitava por construção — todos os componentes sobem juntos, ou nenhum sobe — voltou pelo caminho da dependência de rede. O microsserviço que nunca deveria ter existido, no caso, foi o retry-orchestrator: sua única função era reagir a falhas de invoicing, e a latência de rede entre os dois era maior que o benefício da independência.

A premissa original — medo de indisponibilidade

A premissa que justificou a primeira quebra foi correta em sua medição e equivocada em sua conclusão. O medo de indisponibilidade era real: o pior caso de 18 minutos era o gatilho. A conclusão equivocada foi tratar o pior caso como propriedade do monolito, quando o pior caso era propriedade da falta de observabilidade. A análise que precedeu a quebra não incluiu o custo composto das dependências distribuídas. A análise que precedeu a quebra também não incluiu o custo de manter três pipelines de deploy em vez de um, nem o custo de três bases de código com seus próprios sistemas de tipagem, validação e migração de schema.

O erro metodológico central foi confundir blast radius de subsistema com blast radius de sistema. O blast radius do retry-orchestrator, dentro do monolito, era de fato 100% do monolito. Mas o blast radius do retry-orchestrator, isolado em microsserviço, foi 100% dos consumidores do retry-orchestrator, que era exatamente o mesmo conjunto de funcionalidades. O que mudou foi a forma da falha: dentro do monolito, a falha era síncrona e o rollback era um único `git revert`. Entre microsserviços, a falha era assíncrona, propagava por timeout, e o rollback era um coordinated deploy com versionamento de API.

O medo de indisponibilidade, transformado em premissa arquitetural sem o exame do custo composto, é o que produz microsserviço que não deveria ter existido. A análise de risco original não incluiu o risco de a dependência entre microsserviços falhar de forma coordenada. A análise também não incluiu o risco de a plataforma interna não suportar o novo regime operacional, que é exatamente o que aconteceu no segundo ano do projeto, quando a equipe de plataforma foi repriorizada e os SLOs por microsserviço ficaram desatualizados por 14 meses consecutivos.

O que a decomposição custou nos dois anos seguintes

O custo da decomposição foi medido em três dimensões: MTTR, frequência de incidentes, e custo de mudança. A métrica mais reveladora é a do MTTR agregado, porque ela captura o efeito cascata que a análise original ignorou. Em 2023, o MTTR médio do monolito era 8 minutos, e o pior caso, 18 minutos. Em 2024, após a primeira quebra em três microsserviços, o MTTR médio do billing agregado subiu para 14 minutos, e o pior caso, para 1 hora e 47 minutos. Em 2025, após a segunda quebra para onze microsserviços, o MTTR médio do billing agregado subiu para 23 minutos, e o pior caso, para 3 horas e 12 minutos.

A frequência de incidentes P1 seguiu trajetória compatível. Em 2023, o sistema teve 4 incidentes P1 no ano, todos resolvidos em menos de 20 minutos. Em 2024, foram 9 incidentes P1, com tempo médio de resolução de 38 minutos. Em 2025, foram 17 incidentes P1, com tempo médio de resolução de 1 hora e 4 minutos. A correlação entre o número de microsserviços e a frequência de incidentes P1 não é perfeita — há variância operacional — mas a tendência é monotonicamente crescente. Cada microsserviço adicionado ao sistema aumenta a probabilidade de incidente composto, e a probabilidade composta cresce mais rápido que a probabilidade unitária.

O custo de mudança é a dimensão menos visível e mais cara. Em 2023, uma feature que tocava três módulos do monolito exigia um pull request com conflitos resolvidos manualmente e um deploy coordenado de 11 minutos. Em 2025, a mesma feature exigia um pull request em cada microsserviço envolvido, com versionamento de API entre eles, contratos de compatibilidade validados em pipeline, e um deploy coordenado de 47 minutos, com janela de rollback de 22 minutos em caso de falha. O custo unitário de uma feature subiu 4,3 vezes. A frequência de features que tocam mais de um microsserviço subiu 6,1 vezes. O produto é que o custo total de mudança no billing agregado subiu 26 vezes, sem que o número de features entregues tenha crescido na mesma proporção.

A medição mais honesta é a de 2025: a equipe de billing entregou 38% menos features do que em 2023, com 71% mais pessoas, e o sistema ficou 2,8 vezes pior no pior caso. Esse é o retrato do microsserviço que nunca deveria ter existido: cada quebra adicionou uma camada de custo composto que o sistema não precisava, e a soma dessas camadas superou o ganho agregado de autonomia.

Lei de Conway ao contrário: o organograma moldou a arquitetura

A Lei de Conway, em sua formulação clássica de 1968, diz que as organizações projetam sistemas que refletem sua estrutura de comunicação. A aplicação usual é prospectiva: para mudar a arquitetura, mude a equipe. O caso estudado inverte a direção. A arquitetura existente — o monolito bem fatorado — foi sacrificada para refletir uma estrutura de comunicação nova, que não existia antes da quebra. O organograma de 2024 mostrava três times de billing: subscription, invoicing e retry-orchestrator. O organograma de 2026 mostra onze times. Cada novo time, ao se formar, declarou autonomia sobre um microsserviço, e cada microsserviço consolidou a autonomia do time.

A causalidade é difícil de isolar sem experimento controlado, mas o correlato é claro: dos onze microsserviços em produção em 2026, oito foram criados após a formação dos times correspondentes, e três foram criados antes. Nenhum dos três criados antes foi revertido para o monolito. A arquitetura seguiu o organograma, e o organograma consolidou a arquitetura. O feedback loop entre estrutura organizacional e estrutura de software é o que torna a decisão inicial de microsserviço tão custosa de reverter: reverter a arquitetura exige reverter o organograma, e reverter o organograma tem custo político que a engenharia raramente consegue pagar sozinha.

O que a Lei de Conway ao contrário mostra, na prática, é que microsserviço é frequentemente um pedido de autonomia organizacional traduzido em vocabulário de engenharia. A análise técnica que precedeu a quebra original não incluiu essa dimensão. A análise de autonomia organizacional pertence à gestão de engenharia, e à gestão de engenharia cabe perguntar: o ganho de autonomia do time vale o custo composto do sistema? Se a resposta for sim, microsserviço é o instrumento correto. Se a resposta for “não sei”, o monolito bem fatorado é o instrumento mais barato até que a resposta apareça.

O sinal que teria abortado a decisão antes do primeiro deploy

Três sinais, observáveis antes do primeiro deploy, teriam abortado a decisão com alta confiança. O primeiro é a ausência de bounded context limpo no monolito original. Bounded context, na formulação de Eric Evans em Domain-Driven Design, é uma unidade de modelo com fronteira explícita de linguagem. O monolito de billing de 2023 tinha 12 módulos coesos, mas os módulos não eram bounded contexts: havia campos compartilhados (Customer, Invoice, Plan) que apareciam em mais de um módulo, com semânticas sutilmente diferentes. A decomposição em microsserviço amplificou essa divergência semântica, porque cada microsserviço passou a ter sua própria versão dos campos compartilhados, e a sincronização entre versões virou um sistema distribuído de migração de schema.

O segundo sinal é a ausência de plataforma interna com SLO por serviço. A plataforma interna do billing em 2023 era uma collection de scripts bash, sem SLO documentado, sem dashboard de saúde, sem alerta automatizado. Migrar de monolito para microsserviço sem plataforma interna é trocar uma operação manual por N operações manuais. O custo operacional da plataforma interna sobe com N, e a probabilidade de erro humano em deploy sobe junto. No caso estudado, o primeiro ano pós-quebra acumulou 14 incidentes de deploy que não teriam sido incidentes no regime monolítico, porque o monolito não exigia coordenação entre pipelines.

O terceiro sinal é a ausência de observabilidade fim-a-fim. O billing em 2023 tinha logging estruturado e métricas básicas, mas não tinha tracing distribuído. Após a quebra, a ausência de tracing distribuído virou a principal causa de MTTR inflado: a maioria dos incidentes compostos levava entre 40 e 90 minutos para ser diagnosticada, porque o time não conseguia correlacionar os logs dos três microsserviços iniciais sem tracing. A introdução de OpenTelemetry no segundo ano reduziu o tempo de diagnóstico em 60%, mas o custo de diagnosticar incidentes sem tracing nos dois anos anteriores já tinha sido pago.

A regra operacional que emerge dos três sinais é direta: se algum dos três estiver ausente, a quebra em microsserviço é postergação disfarçada. O custo composto vai chegar, e vai chegar com a plataforma interna ainda mais sobrecarregada, porque a plataforma interna que era opcional passa a ser obrigatória.

Quando microsserviço é a decisão certa (e quando não é)

Microsserviço é a decisão certa quando três condições estão simultaneamente satisfeitas. A primeira é plataforma interna madura: pipeline de deploy confiável, SLO por serviço documentado, observabilidade fim-a-fim com tracing distribuído, e sistema de feature flags que permita rollback em produção sem redeploy. A segunda é custo composto dominado pelo ganho de autonomia: o custo de N deploys coordenados é menor que o ganho de times independentes operando em paralelo. A terceira é capacidade de absorver o pior caso sem fallback coordenado: o sistema degrada graciosamente quando um microsserviço cai, e a degradação graciosa é parte do contrato, não um objetivo.

A leitura oposta também é precisa. Microsserviço é a decisão errada quando o time é novo, o monolito é bem fatorado, a plataforma interna é imatura, e o medo de indisponibilidade é maior que a medição de indisponibilidade. Martin Fowler, em “MonolithFirst” (2015), argumenta que a maioria dos sistemas que se beneficiariam de microsserviço começa com monolito bem fatorado e migra para microsserviço quando a dor de manter o monolito supera o custo de manter microsserviços. Sam Newman, em “Building Microservices” 2nd edition, capítulo 2, lista pré-requisitos que precisam estar satisfeitos antes da quebra. Os dois autores convergem: microsserviço é o destino de sistemas maduros, não o ponto de partida.

A análise de campo que sustenta este post é compatível com as duas leituras. O caso estudado tinha três sinais de alerta — ausência de bounded context limpo, plataforma interna imatura, e ausência de observabilidade fim-a-fim — e a quebra em microsserviço foi feita com os três sinais visíveis. O resultado foi um sistema mais complexo, com MTTR pior no pior caso, e com custo de mudança 26 vezes maior. O microsserviço que nunca deveria ter existido é o retry-orchestrator, mas o conjunto dos onze microsserviços carrega o mesmo vício de origem: foram criados para resolver um medo, sem medir o custo composto que o medo escondia.

A proposição estratégica que emerge é conservadora por necessidade. Em sistemas com menos de 50 desenvolvedores, plataforma interna imatura, e bounded context com campos compartilhados, o monolito bem fatorado vence o microsserviço. A quebra só vale quando o ganho de autonomia é maior que o custo composto, e a medição do ganho exige plataforma interna que ainda não existe. A quebra antes da medição é o que produz microsserviço que não deveria ter existido. A quebra depois da medição é engenharia com custódia.

Leitura relacionada

Posts Similares

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *