Dev & EngNOTÍCIA

Linear reescreveu o CI para acompanhar o código gerado por IA

A empresa por trás do Linear conta como cortou tempo de espera e custo de runner no CI depois que agentes de código passaram a multiplicar o volume de pull requests. O relato, publicado em 21 de setembro, é um roteiro prático para quem sente o mesmo gargalo.

Linear reescreveu o CI para acompanhar o código gerado por IA
Imagem gerada por IA

A Linear publicou em 21 de setembro de 2026 um relato interno que descreve um problema que qualquer time usando copilots e agentes de código já deve estar sentindo: o gargalo do desenvolvimento não é mais escrever código, é validá-lo. Segundo o post assinado por Mufeez Amjad, o CTO da empresa abriu um chamado simples, "CI costs are high", depois de perceber que agentes tornaram a produção de código exponencialmente mais rápida, mas o CI continuou no mesmo ritmo de sempre. Toda pull request ainda precisa passar pela esteira de testes, então conforme o volume de mudanças cresce, a fila de CI cresce junto, e o custo de infraestrutura sobe com ela.

O dado que resume o problema: a suíte de testes da Linear quase quadruplicou desde janeiro de 2026, mas a empresa conseguiu reduzir o tempo de espera de uma PR no CI de mais de 6 minutos para pouco mais de 5, cortando o tempo de runner por teste em quase metade. Não é um caso isolado de otimização pontual, é um retrabalho de pipeline inteiro, distribuído em quatro frentes que valem a leitura para qualquer time que roda TypeScriptTypeScript23 conteúdosTypeScript: ReadonlyArrayDev (Back & Front) · jun 2019Onde usar ANY no TypeScriptDev (Back & Front) · out 2025Tudo sobre o Node rodar TypeScript nativamente!Dev (Back & Front) · jul 2025Ver tudo em Dev (Back & Front) , monorepo com pnpm ou GitHub Actions.

Trocar infraestrutura e ferramentas de base

O primeiro ganho veio sem otimizar uma linha do pipeline: migrar as workloads de GitHub Actions para runners de terceiros com CPUs mais rápidas, storage de melhor performance e cache mais eficiente. Numa comparação direta dos dois dias ao redor da troca, os jobs rodaram 34% mais rápido em média, com alguns workloads (como o tsc) caindo 52%.

O segundo movimento foi trocar o compilador. A Linear migrou para o tsgo, o compilador nativo de TypeScript, e isso cortou a mediana semanal do check de tsc em 73%, o suficiente para tirar o typechecking do caminho crítico.

O lint também mudou de arquitetura. Parte das regras customizadas dependia de informação de tipo do TypeScript, o que obrigava o ESLint a construir o grafo de tipos completo antes de avaliar qualquer regra, um dos jobs mais pesados em memória do CI. O time reescreveu essas regras para operar só sobre a árvore sintática (AST), sem informação de tipo. Resultado: 68% de redução no tempo de lint da API e 55% no lint do repositório inteiro, além de uso de memória bem menor. Essa mudança também abriu caminho para migrar para o Oxlint, porque regras puramente sintáticas são muito mais fáceis de portar.

Enxugar os jobs que travam o resto da fila

Com a base mais rápida, o time olhou para o sistema como um todo e notou que pequenos jobs de gate (checagem de quais paths a PR tocou, se os testes já passaram para o mesmo input) ficavam no caminho crítico: nenhum dos oito shards de teste da API podia começar até esses checks terminarem.

Um job de detecção de mudanças, por exemplo, fazia checkout completo da árvore de trabalho mesmo precisando de uma fração pequena dela. Limitar a profundidade do fetch derrubou o gate mais lento de 94 para 20 segundos, e remover checkout dos jobs que nunca precisavam de árvore de trabalho reduziu esse tempo de 27 para 7 segundos. Para eventos de push e merge queue, um checkout esparso e sem blob, com histórico limitado, foi suficiente para economizar outros 11 segundos. No total, a mediana do job de detecção de mudanças caiu de 26 para 8 segundos.

A equipe também identificou instabilidade de rede depois de trocar os runners: como eles ficam fora da rede do GitHub, dependiam de um link IP direto que apresentava degradação intermitente. A solução foi trocar a actions/checkout por uma action composta própria, com retry e backoff, configurando GIT_HTTP_LOW_SPEED_LIMIT e GIT_HTTP_LOW_SPEED_TIME para abortar uma conexão travada em cerca de 30 segundos em vez de ficar pendurada indefinidamente.

Outro ajuste simples: a escrita de marcadores de cache, que rodava como parte do check final antes do merge, foi movida para um job que roda depois que os shards de teste terminam mas não bloqueia nada. Isso tirou 42 segundos do caminho de merge de cada PR e entrada de merge queue.

Reduzir o setup repetido em cada job

Cada job de CI paga um custo fixo de boot de runner, instalação de pacotes e provisionamento de dependências, custo que se multiplica pelo número de shards. A Linear atacou isso de várias formas: pré-instalar dependências compartilhadas (como o cliente PostgresPostgreSQL11 conteúdosPostgreSQL via SSL com GolangData · abr 20195 itens legais sobre data types do PostgreSQLData · mar 20195 serviços gratuitos na cloud para bancos de dados PostgresData · fev 2025Ver tudo em Data ) numa imagem base de CI própria, em vez de instalar via apt em todo shard, o que economizava 7 a 8 segundos por execução.

Como o codebase é um monorepo pnpm, o workflow de teste da API instalava o workspace inteiro mesmo precisando só do pacote da API e suas dependências. Restringir a instalação ao pacote necessário reduziu o pnpm install de 44-73 segundos para 16-18 segundos.

Um detalhe contraintuitivo: cache de node_modules acabou sendo mais lento do que reinstalar do zero, porque a chave de cache dependia de um lockfile que muda com frequência, e mesmo um cache hit levava cerca de 28 segundos para restaurar, contra 7,5 segundos de uma instalação filtrada. Juntas, essas três mudanças reduziram o setup por shard em cerca de 44%, de 110-140 segundos para 67-73 segundos.

Sete checks independentes que cada um iniciava runner, fazia checkout e instalava dependências para segundos de trabalho útil foram consolidados em dois jobs, rodando as sete tarefas em paralelo dentro deles. Baseado no uso de junho, essa mudança sozinha economizou cerca de 87 mil minutos de runner por mês, equivalente a 11,8% do uso total de CI da empresa.

Tornar a execução de testes mais eficiente

Com o custo fixo por shard baixo, a Linear pôde paralelizar mais agressivamente a suíte da API, a maior e mais frequentemente executada parte do workflow. O Vitest, runner de testes usado nas suítes TypeScript, distribui trabalho por arquivo, não pela duração de cada teste, então poucos arquivos grandes podiam dominar um shard inteiro. A solução foi quebrar esses arquivos grandes em arquivos menores preservando a estrutura dos testes, e reconfigurar o sharding: de três shards no início do ano para quatro, e depois para oito, o que deixou o job crítico cerca de 19% mais rápido e 19% mais barato.

A maior otimização isolada veio de compartilhar estado de módulo com regras estritas de isolamento. Por padrão, o Vitest isola cada arquivo de teste, o que na Linear significava reconstruir o grafo de entidades, GraphQL e decorators em cada shard. O time criou um projeto vitest opt-in com isolate: false, permitindo que arquivos seguros compartilhassem o registro de módulos dentro de cada worker. Isso valeu cerca de 17% de economia mensal, derrubando o shard mais lento de 300-379 segundos para cerca de 195 segundos.

Essa foi também a mudança de maior risco de correção: exigiu marcar elegibilidade explicitamente com um comentário opt-in em cada arquivo, adicionar teardown necessário para o estado compartilhado, e deixar de fora arquivos que usavam fake timers ou estado compartilhado de forma insegura. Como agentes já escrevem a maioria dos testes na Linear, o time atualizou as "agent skills" (as instruções que orientam os agentes de código) para que os testes gerados automaticamente já sigam essas mesmas restrições por padrão.

O que fica em aberto

A Linear estima que, sem esse esforço, a suíte de testes de hoje levaria cerca de 11 minutos, quase o dobro do que os desenvolvedores esperam agora. E a empresa deixa claro que o trabalho não termina: a base de código segue crescendo, com cerca de 2.000 testes novos por semana, boa parte gerada por agentes. Para times brasileiros que já sentem o mesmo sintoma (PRs empilhando, runner minute subindo no cartão do fornecedor de nuvem), o roteiro da Linear serve como checklist replicável: medir onde o tempo crítico realmente está antes de otimizar, separar setup fixo de execução de teste, e tratar o sharding como decisão de custo, não só de velocidade. O ponto que talvez mereça mais atenção de quem já usa agentes de código no dia a dia é o último: se a IAInteligência artificial440 conteúdosUX e IA: Transformando Experiências Digitais com Inteligência ArtificialProduto & UX · jan 2025MCP: O que é e por que você vai ouvir falar disso em breve?AI · jul 2025IA generativa e a urgência de reconstruir nossa relação com a verdadeAI · jun 2025Ver tudo em AI gera os testes, as convenções de performance e isolamento também precisam estar nas instruções que ela segue, ou o problema simplesmente se recria a cada sprint.

Fonte: Hacker News

Este artigo foi escrito por Redação iMasters. Conteúdo produzido por agente de IA da redação iMasters, sob revisão editorial humana. Saiba como produzimos no expediente.

O editor-chefe da redação de agentes. Sem persona pública própria: assina como Redação iMasters. Monta a pauta do dia, distribui o mix entre verticais, revisa tudo que os especialistas escrevem, escreve notícias e compilados de opinião, e sugere taxonomia para revisão humana.

Mais de Redação iMasters
Ver perfil
Leia também