#desenvolvimento-de-software
#fundadores
#produto
Opinião

Migrar um pouco por sprint ou trocar tudo de uma vez: o que cada caminho cobra do seu roadmap

Versão nova da mesma tecnologia se migra um pouco por sprint. Tecnologia diferente vira projeto, e mesmo ele anda em fatias. O custo de cada caminho e onde a regra falha.

Por Victhor Araújo

Fundador da Revin. Engenheiro de formação, especialista em desenvolvimento de software e produtos digitais.

O card de atualização que nunca entra na sprint é o que vira trimestre parado

O card de atualização que nunca entra na sprint é o que vira trimestre parado

Se a mudança é de versão, migre um pouco por sprint e trate isso como trabalho normal do time. Versão aqui quer dizer a linguagem, o framework, a biblioteca de pagamento, a imagem base do container ou o banco que sobe do 14 para o 16. Se a mudança é de natureza, como outro banco, outra nuvem ou outro serviço de autenticação, aí existe um projeto. Mesmo esse projeto deve andar em pedaços que convivem com o sistema antigo por semanas. A troca de uma vez, num fim de semana, com tudo congelado antes, costuma ser o caminho que você acabou pegando por não ter escolhido o outro a tempo.

O preço de cada caminho aparece em lugares diferentes. A migração contínua cobra uma fatia fixa e chata de toda sprint, algo como uns 10% a 15% da capacidade do time, e ninguém comemora. A troca grande cobra um trimestre inteiro do seu roadmap. Quem escolhe o momento é o fornecedor que encerrou o suporte, a auditoria ou o incidente. Raramente você.

O assunto voltou esta semana por um caminho curioso. O Simon Willison respondeu, no blog dele, a uma conversa do Lobste.rs sobre os textos que mais mudaram o jeito de cada um pensar. Entre os escolhidos está "Migrations: the sole scalable fix to tech debt", que o Will Larson publicou em 2018. A ideia que o Willison destaca é simples: trocar um serviço por outro, mudar de motor de banco ou subir versão faz parte da vida normal de um sistema, e não de um acidente de percurso. Oito anos depois, boa parte dos roadmaps que chegam na minha mesa ainda trata migração como exceção.

A fatia fixa que a migração contínua cobra

Três versões de framework de uma vez somam as mudanças incompatíveis de cada uma

Três versões de framework de uma vez somam as mudanças incompatíveis de cada uma

Migrar um pouco por sprint significa ter sempre, no board, um card de atualização. Uma dependência que ficou duas versões atrás. O runtime que sai de suporte no ano que vem. A imagem base acumulando alerta de segurança. Nenhum desses cards vira apresentação para o conselho, e é por isso que eles caem primeiro quando o trimestre aperta.

O custo é previsível, e previsível é a melhor coisa que um custo pode ser. Você sabe que uns 10% a 15% da capacidade vão para ali, sabe que a feature da semana sai um pouco menor e sabe que o sistema segue a uma ou duas versões do que o mercado usa. Cada salto é pequeno. O changelog cabe numa leitura, e o teste que quebra aponta para uma causa só.

O custo menos visível é de disciplina. Alguém precisa ser dono dessa fila, segurar o card quando ele é empurrado pela terceira sprint seguida e acompanhar quantas versões o sistema está atrás. Sem dono, a migração contínua vira intenção contínua.

O trimestre que você não escolhe

A troca grande quase nunca começa como decisão. Começa como aviso. O provedor anuncia o fim do suporte da versão do banco. A biblioteca de autenticação para de receber correção. Um cliente grande manda um questionário de segurança perguntando as versões em uso, e a resposta honesta é constrangedora.

Nesse ponto a distância acumulada virou um salto só. Três versões de framework de uma vez, com as mudanças incompatíveis de cada uma somadas. O teste que quebra agora aponta para quatro causas misturadas, e ninguém sabe qual veio de qual versão. A estimativa de umas seis semanas nasce otimista, porque ninguém lê três changelogs grandes e prevê como eles se cruzam no seu código. O jeito como esse número escorrega eu descrevi em a estimativa que ganha o contrato é a que mais atrasa.

E o roadmap para. Naquele trimestre o time não entrega a feature que o comercial prometeu, e a conversa com o CEO vira negociação sobre o que sai do plano. É aqui que a dívida técnica deixa de ser assunto de engenharia e vira linha de receita: a feature atrasada tinha cliente esperando por ela.

"Não tenho folga nem para as features que já prometi"

Na convivência entre o sistema antigo e o novo, cada divergência vira registro antes da virada

Na convivência entre o sistema antigo e o novo, cada divergência vira registro antes da virada

Essa é a objeção honesta, e quem toca produto com três ou quatro pessoas conhece bem. Os 10% parecem luxo quando a lista de pedidos já estoura a sprint.

A resposta é aritmética. A fatia existe de qualquer jeito, e a única escolha é quando pagar. Você paga em parcelas pequenas, no ritmo que decide, ou paga de uma vez, com juros, na data que outra pessoa decidiu. O time que adia a atualização por dois anos não economizou capacidade nesse período: pegou emprestado, e o empréstimo volta como um trimestre parado.

Ajuda também olhar o plano com menos otimismo. Muito cronograma bonito não tem linha nenhuma para manutenção, e o prazo escorrega em silêncio sprint após sprint. Chamei isso de teatro de roadmap: o Gantt mais caprichado costuma ser o que esconde a conta.

Banana prata, banana nanica e maçã

Um cliente me perguntou uma vez se subir o MySQL 5 para o 7 era a mesma coisa que trocar para o Postgres. Expliquei com fruta. O MySQL 5 é banana prata, o 7 é banana nanica e o Postgres é maçã. Todas são frutas, todas são bancos SQL, mas a maçã é outra fruta. Quem troca de banana para banana muda tamanho e sabor, e a receita continua a mesma. Quem troca de banana para maçã refaz a receita.

A conversa parece pedante. Ela decide qual dos dois caminhos você está pegando. Versão nova da mesma coisa é trabalho de sprint: pequeno, frequente, sem cerimônia. Tecnologia diferente é projeto, com orçamento, dono e data de fim. O erro caro é tratar uma coisa como a outra. Quem trata a troca de fruta como atualização de rotina descobre no meio do caminho que metade das queries usa recurso que só existe no banco antigo. Quem trata a atualização de versão como projeto especial deixa ela esperando um trimestre livre que nunca chega.

(O cliente riu da fruta, mas a pergunta dele era boa. O nome no contrato do provedor é parecido, e o que muda embaixo não aparece na nota fiscal.)

Existe ainda um terceiro caso, que confunde muita gente: reescrever o produto. Migrar é trocar uma peça com o resto funcionando. Reescrever joga o resto fora junto. Os motivos pelos quais eu quase nunca recomendo o segundo estão em por que eu quase nunca aprovo reescrever o produto inteiro.

Quando trocar de fruta é inevitável, a troca também anda em pedaços

Mesmo a migração para uma tecnologia diferente não precisa ser um salto no escuro. O caminho que dá menos susto é parecido em quase todo caso: o sistema novo passa a conviver com o antigo, e o tráfego muda de lado aos poucos. Na prática, isso se desdobra em quatro movimentos.

  • Escrever nos dois lugares: toda gravação vai para o banco antigo e para o novo, e o antigo continua sendo a fonte da verdade.
  • Ler dos dois e comparar: uma parte das leituras consulta os dois, e cada divergência vira registro para alguém investigar antes de qualquer virada.
  • Virar por fatia: um tipo de cliente, uma região ou um endpoint passa para o novo, e o resto segue no antigo até a fatia provar que aguenta.
  • Desligar o antigo por último, depois de algumas semanas sem divergência, com a data escrita no plano para a convivência não virar eterna.

A migração fica mais longa no calendário e bem mais curta no susto. E ela exige uma coisa que muito sistema não tem: saber, com dado, quando algo divergiu ou caiu. Se hoje quem descobre o problema é o cliente, resolva isso antes de começar a trocar peças. Migrar sem instrumentação é trocar o motor com o painel apagado.

A troca de infraestrutura tem uma armadilha a mais, que é credencial. Durante a convivência ficam dois ambientes de pé, com dois conjuntos de chaves, e o antigo costuma continuar acessível muito depois de desligado no papel. O caso extremo é o fornecedor anterior que ainda tem acesso à sua produção.

Onde este conselho falha

Migrar um pouco por sprint pressupõe que o sistema vai continuar existindo. Se o produto será descontinuado em seis meses, gastar 10% da capacidade atualizando dependência é hora jogada fora. Congele, isole do que é público e deixe o sistema terminar a vida em paz.

Falha também quando a dependência foi abandonada de vez. Não existe versão nova para subir, então a atualização contínua não tem para onde ir, e o que sobra é substituir. Aí a pergunta volta para a fruta: você está trocando por algo parecido ou por outra coisa?

E tem a data imposta de fora: regulador, fim de contrato com o provedor, cliente grande exigindo. Prazo que outra pessoa fixou não se fatia. O que dá para fazer é começar antes, e esse é o argumento mais forte a favor da fatia fixa. Quem já estava a uma versão de distância quase não sente a data chegar.

A lista para levar à próxima planning

Antes da próxima reunião de planejamento, peça ao time uma tabela curta. Para cada dependência que importa (linguagem, framework, banco, imagem base, SDK de pagamento), em que versão vocês estão, qual é a atual e quando termina o suporte da sua. Leva uma tarde. Quando um squad nosso assume um sistema que veio de outro fornecedor, essa tabela é das primeiras coisas que ele monta, antes de qualquer feature, e quase sempre aparecem uma ou duas linhas vermelhas que ninguém tinha olhado.

Depois, uma pergunta só para você: quantas linhas dessa tabela viraram card na sprint atual? Se a resposta é zero, você já escolheu a troca grande. Só não sabe ainda em que trimestre ela vai cair.

Pronto para elevar o seu negócio?

Agendar uma reunião
Compartilhe
Link de compartilhamento LinkedinLink de compartilhamento XLink de compartilhamento WhatsappLink de compartilhamento Facebook
Você também pode gostar

A cada quinze dias. As decisões técnicas que tomamos, e o que aprendemos.