“Quanta dívida técnica temos?”

Parece uma pergunta importante. Normalmente, é vaga demais para ser útil.

Todo sistema maduro contém concessões, escolhas desatualizadas, abstrações imperfeitas e código que poderia melhorar. Nem tudo isso merece uma ação.

A dívida técnica se torna estrategicamente importante quando muda a economia ou a viabilidade de uma decisão de negócio.

A pergunta útil, portanto, é:

Quais partes do sistema limitam nossa capacidade de mudar, operar, proteger ou crescer?

Isso transforma a dívida técnica de um julgamento moral sobre a qualidade do código em um problema de decisão.

Dívida é uma metáfora para consequências

A metáfora da dívida é útil porque separa duas coisas:

  • tomar um atalho;
  • pagar continuamente pelas consequências desse atalho.

Um atalho pode ser racional.

Uma startup pode escolher um único banco de dados porque isso reduz o tempo de entrega. Um time pode aceitar implantação manual durante um protótipo inicial. Uma empresa pode integrar um fornecedor diretamente, em vez de construir uma abstração, porque chegar ao mercado no momento certo importa mais do que a portabilidade.

A decisão se torna problemática quando a organização esquece a consequência.

Dívida não é “código ruim”.

Dívida é uma escolha estrutural cujo custo futuro de manutenção importa.

Os juros aparecem como custo da mudança

A dívida técnica frequentemente se torna visível por meio de atritos.

Uma pequena funcionalidade exige mudanças em muitos módulos. As entregas exigem grandes ciclos de regressão. Pessoas engenheiras têm receio de mexer em um subsistema. Uma atualização de dependência leva meses. Uma integração não pode ser alterada sem indisponibilidade para clientes.

O pagamento dos juros aparece como aumento do custo da mudança.

Indicadores úteis incluem:

  • tempo de entrega das mudanças;
  • coordenação necessária por versão;
  • taxa de defeitos em um subsistema;
  • dificuldade de reversão;
  • tempo para diagnosticar incidentes;
  • frequência de trabalho emergencial;
  • tempo de integração de novas pessoas;
  • dependência de especialistas difíceis de encontrar;
  • duração dos testes;
  • esforço manual de liberação de versões.

O código ainda pode “funcionar”.

O negócio paga por meio de mudanças mais lentas e arriscadas.

Parte da dívida afeta a confiabilidade

A dívida também pode criar restrições operacionais.

Exemplos incluem:

  • observabilidade insuficiente;
  • domínios de falha compartilhados;
  • etapas manuais de recuperação;
  • tarefas agendadas frágeis;
  • comportamento inadequado de novas tentativas;
  • configuração inconsistente;
  • backups não testados;
  • limites ocultos de recursos.

Esses problemas não necessariamente atrasam o desenvolvimento de funcionalidades todos os dias. Eles mudam o custo esperado de uma falha.

Um sistema com episódios recorrentes de falta de memória pode continuar entregando funcionalidades rapidamente até que a pressão sobre a capacidade cause um incidente em produção. Nesse momento, uma dívida antes invisível se transforma em interrupção do negócio.

A dívida de confiabilidade importa quando a organização aceita risco operacional sem avaliar conscientemente seu custo.

A dívida de segurança tem uma curva de risco diferente

Algumas dívidas se acumulam gradualmente. A dívida de segurança pode causar consequências abruptas.

Uma dependência obsoleta pode parecer inofensiva durante anos e depois se tornar uma vulnerabilidade crítica.

Um modelo de permissões amplo demais pode ser conveniente operacionalmente até que uma conta comprometida exponha dados de vários clientes.

A ausência de uma trilha de auditoria pode não importar até que a organização precise reconstruir uma ação regulada.

Isso torna a priorização mais difícil.

Os times não devem tratar toda dívida de segurança como urgente, mas devem avaliar exposição, probabilidade, impacto e controles compensatórios, em vez de classificá-la junto com refatorações comuns.

O modelo de decisão precisa refletir as consequências, não o incômodo de quem desenvolve.

A carga cognitiva é um custo econômico

Alguns sistemas são difíceis não porque algum componente específico esteja quebrado, mas porque entendê-los exige contexto demais.

Uma pessoa desenvolvedora que faz uma pequena alteração pode precisar entender vários serviços, processos de implantação, fluxos de dados não documentados e convenções dos times.

Essa carga cognitiva aumenta:

  • o tempo de integração de novas pessoas;
  • o esforço de revisão;
  • a probabilidade de defeitos;
  • a dependência de pessoas experientes;
  • a hesitação em alterar áreas pouco conhecidas.

A pesquisa DORA sobre times pouco acoplados conecta a arquitetura técnica e organizacional ao desempenho de entrega. Times têm mais capacidade de entrega contínua quando conseguem fazer, testar e implantar mudanças com menos coordenação externa.

Essa é uma forma importante de pensar sobre dívida.

Uma estrutura técnica que exige coordenação constante está criando um custo organizacional.

A dívida pode estar nos dados, na infraestrutura e nos fornecedores

O código recebe a maior parte da atenção porque é visível para quem desenvolve.

A dívida estratégica frequentemente está em outros lugares.

Dívida de dados pode incluir responsabilidade pouco clara, identificadores inconsistentes, histórico ausente, fontes de verdade duplicadas e esquemas que codificam premissas de negócio obsoletas.

Dívida de infraestrutura pode incluir ambientes de execução sem suporte, provisionamento manual, divergência entre ambientes, recuperação de desastres frágil e modelos caros de escala.

Dívida de integração pode incluir contratos não documentados, acoplamento direto aos esquemas de fornecedores, consultas periódicas frágeis, ausência de idempotência e semântica de falha pouco definida.

Dívida de fornecedores pode incluir dependências proprietárias caras de substituir, estruturas de preço que deixaram de corresponder ao uso ou produtos que impedem capacidades necessárias.

Um inventário útil de dívida técnica deve, portanto, descrever restrições, não repositórios.

A priorização precisa considerar impacto e valor das opções

Um backlog de dívida ordenado pela preferência de desenvolvedores terá dificuldade para competir com o trabalho de produto.

O negócio precisa entender por que a ação importa.

Um item de dívida mais sólido se parece com isto:

Restrição:
O pipeline compartilhado exige que todos os serviços sejam liberados juntos.

Impacto observado:
O tempo mediano de liberação aumenta em 3 dias por causa da regressão coordenada.

Efeito no negócio:
Correções prioritárias para clientes não podem ser implantadas de forma independente.

Correção:
Separar a responsabilidade de implantação de dois domínios com mudanças frequentes.

Opção que se espera criar:
Os times podem liberar esses domínios sem coordenação de todo o portfólio.

O campo importante é a opção criada.

Corrigir dívida é valioso quando muda o que a organização pode fazer a seguir.

Dívida que pode permanecer

Nem todo componente antigo deve ser modernizado.

Um subsistema estável, com poucas mudanças, baixa taxa de incidentes e condições aceitáveis de segurança pode ser feio e economicamente inofensivo.

Reescrevê-lo pode destruir valor.

É nesse ponto que a disciplina de engenharia exige contenção.

O fato de um time projetar algo de outra forma hoje não significa que sua substituição se justifique.

Uma decisão útil pergunta:

  • Com que frequência esta área muda?
  • Qual é o custo da mudança?
  • Quais falhas ela cria?
  • Qual capacidade futura ela bloqueia?
  • Há uma razão plausível para acreditar que essas capacidades serão necessárias?
  • Qual é o risco de migração?
  • O que mais poderíamos fazer com a mesma capacidade de engenharia?

Dívida sem consequências relevantes pode continuar sendo dívida.

Dívida que exige ação

A dívida se torna uma candidata mais forte à ação quando vários fatores se combinam:

SinalPor que importa
Alta frequência de mudançasO custo de manutenção é pago repetidamente
Grande alcance de impactoFalhas afetam muitos usuários ou sistemas
Exposição de segurançaAs consequências podem surgir abruptamente
Plataforma obsoletaAumentam os riscos de suporte e contratação
Bloqueio de uma capacidade estratégicaO custo de oportunidade se torna visível
Trabalho operacional repetitivoA capacidade de engenharia é consumida
Dependência de conhecimento raroO risco de continuidade aumenta
Impedimento à entrega independenteO custo de coordenação se acumula

A prioridade não é “a arquitetura mais limpa primeiro”.

É “a maior restrição evitável em relação ao custo de correção e à direção do negócio”.

A dívida técnica pode ser racional

Às vezes, os times falam de dívida técnica como prova de que alguém falhou.

Essa abordagem desencoraja discussões honestas sobre concessões.

Parte da dívida é assumida intencionalmente para aprender mais rápido, cumprir um prazo ou evitar abstração prematura.

As práticas importantes são:

  1. tornar a concessão visível;
  2. entender a consequência esperada;
  3. definir o que justificaria a correção;
  4. revisitar a decisão quando o contexto mudar.

Isso é economia de engenharia aplicada ao dia a dia.

O erro não é escolher velocidade em vez de elegância.

O erro é fingir que a escolha não tem custo futuro.

A modernização deve atacar restrições

Essa perspectiva muda a estratégia de modernização.

Em vez de perguntar “Qual tecnologia antiga devemos substituir?”, pergunte “Quais restrições mais limitam as mudanças futuras?”.

Esse é o centro de Modernização sem uma substituição de uma só vez.

Às vezes, a resposta é atualizar o ambiente de execução. Às vezes, é cobertura de testes. Às vezes, é extrair uma fronteira de domínio. Às vezes, é substituir um fornecedor. Às vezes, é não mudar nada.

O objetivo não é pureza arquitetural.

É melhorar a capacidade.

Traduza a dívida para a linguagem das decisões

Lideranças seniores de engenharia precisam traduzir a dívida técnica em termos que outras áreas consigam analisar.

Em vez de:

A base de código está bagunçada.

Diga:

Mudanças nesta área exigem alterações coordenadas em cinco módulos e um ciclo completo de regressão, fazendo com que até mudanças de baixo risco para clientes levem vários dias.

Em vez de:

Precisamos refatorar o banco de dados.

Diga:

Três fluxos escrevem diretamente nas mesmas tabelas sem fronteiras de responsabilidade. Isso torna o histórico de auditoria pouco confiável e nos impede de alterar um fluxo de maneira independente.

Em vez de:

Precisamos de infraestrutura mais nova.

Diga:

O ambiente de execução atual nos mantém em um conjunto de dependências sem suporte e bloqueia as atualizações de segurança necessárias para o próximo segmento de clientes.

Essa tradução não é uma técnica de venda. É precisão.

Gerencie consequências, não estética

A dívida técnica é inevitável porque software é construído sob incertezas e restrições.

A questão estratégica é se as consequências estão visíveis e são gerenciadas.

Uma organização madura pode carregar dívida intencionalmente quando seu custo é aceitável.

Também pode investir muito quando a dívida bloqueia uma opção importante de negócio.

Isso exige ir além da distinção binária entre “código bom” e “código ruim”.

O modelo mais útil é:

Condição técnica
  ↓
Consequência operacional ou de entrega
  ↓
Restrição de negócio
  ↓
Valor das opções criadas pela correção
  ↓
Decisão de prioridade

A dívida se torna acionável quando a organização consegue enxergar essa cadeia.

O objetivo não é eliminar a imperfeição.

É impedir que restrições técnicas ocultas tomem decisões de negócio em nome da organização.

Referências

  1. DORA. Loosely coupled teams. https://dora.dev/capabilities/loosely-coupled-teams/
  2. Microsoft. Cost Optimization design principles. Azure Well-Architected Framework. https://learn.microsoft.com/en-us/azure/well-architected/cost-optimization/principles
  3. Microsoft. Cost Optimization tradeoffs. Azure Well-Architected Framework. https://learn.microsoft.com/en-us/azure/well-architected/cost-optimization/tradeoffs
← Todos os Insights