O problema: IA gera mais código do que o CI consegue processar

Por anos, a integração continua (CI) foi eficiente o suficiente. Um dev abria um pull request por dia, o CI rodava em alguns minutos, e a vida seguia. Mas com a adoção em massa de ferramentas como GitHub Copilot, Cursor, Claude Code e similares, o volume de código sendo gerado explodiu. Times que antes abriam 10 PRs por dia agora abrem 30, 50, 100.

O resultado? O CI tornou-se o novo gargalo. Enquanto a geração de código ficou muito mais rápida, o tempo de feedback do CI ficou para traz. Devs esperando 15, 20 minutos para ver se o build passou. Filas de jobs no GitHub Actions. Custo de CI disparando sem uma relação clara com o valor entregue.

O time de engenharia do Linear, a ferramenta de gestão de projetos, publicou em setembro de 2026 um relato detalhado de como eles enfrentaram exatamente esse problema. As licoes que tiraram são aplicáveis a qualquer time que usa IA para gerar código.

Como o gargalo de CI se forma

O mecanismo e simples: coding agents e assistentes de IA reduzem o custo de escrever código novo. Um dev que antes levava 2 horas para implementar uma feature agora leva 30 minutos com ajuda de IA. Isso e ótimo para produtividade, mas significa que o mesmo dev agora abre 4x mais PRs por dia.

Cada PR dispara uma rodada de CI: lint, type check, testes unitários, testes de integração, build, preview deploy. Se cada suite leva 15 minutos e o time tem 10 devs cada um abrindo 5 PRs por dia, isso são 750 minutos de CI por dia. Com o fluxo antigo de 1 PR por dev, seria 150 minutos.

O problema se agrava porque muitos times não revisitaram a configuração do CI ha anos. Jobs que rodam sequencialmente quando poderiam rodar em paralelo. Testes lentos que ninguém removeu. Cache de dependências que expirou e nunca foi renovado. Uma suite de CI que levava 8 minutos em 2022 leva 20 em 2026 porque o projeto cresceu mas o pipeline não foi atualizado.

⚠️
Atenção

O custo do CI cresce mais rápido do que o time percebe. Se você usa GitHub Actions com runners pagos, rode gh api repos/{owner}/{repo}/actions/cache/usage para ver o tamanho do seu cache e gh run list --limit 100 para medir o tempo médio dos seus workflows nos últimos 100 runs.

As principais causas de CI lento

Antes de otimizar, o time do Linear mapeou as causas reais de lentidão. Os padrões que eles identificaram aparecem em quase todos os times que cresceram rapidamente:

  • Jobs sequenciais desnecessários: lint rodando antes do build quando os dois poderiam rodar em paralelo
  • Cache invalido ou inexistente: node_modules sendo instalado do zero em cada run porque o cache key esta errado ou expirado
  • Testes de integração lentos e redundantes: suites de teste que não foram auditadas em anos e testam o mesmo comportamento de formas diferentes
  • Build completo quando só mudou um módulo: sem cache incremental, qualquer mudança recria o build inteiro
  • Jobs que só falham de vez em quando: testes flakey que forçam re-runs manuais, aumentando o tempo total percebido

A diagnosticação começa por medir. Sem dados, qualquer otimização e chute. O Linear criou um dashboard interno que mostra o tempo médio por job, a taxa de falha por job, e a frequência de re-runs. Isso revelou que 20% dos jobs eram responsáveis por 80% do tempo total de CI.

Como começar: auditoria do seu pipeline atual

O primeiro passo e entender onde esta o tempo. Para pipelines no GitHub Actions:

# Ver os 20 workflows mais recentes
gh run list --limit 20 --json databaseId,conclusion,createdAt,updatedAt

# Ver detalhes de um run específico
gh run view RUN_ID --log

Para identificar quais jobs são mais lentos, o GitHub Actions tem o breakdown por step na UI. Para análise em escala, use a API:

# Listar jobs de um run e duração de cada step
gh api repos/{owner}/{repo}/actions/runs/{run_id}/jobs --jq '.jobs[] | {name: .name, duration: (.completed_at | fromdateiso8601) - (.started_at | fromdateiso8601)}'

Com os dados em mao, procure por: jobs que levam mais de 5 minutos, jobs com taxa de falha acima de 5%, e qualquer job que roda sequencialmente após outro que não depende dele.

Exemplo prático de otimização

Considere um pipeline típico de projeto Node.js/TypeScript que roda tudo em sequência:

# Pipeline ruim: tudo sequencial
jobs:
  ci:
    steps:
      - checkout
      - npm install  # 3 min sem cache
      - npm run lint  # 2 min
      - npm run typecheck  # 2 min
      - npm run test  # 5 min
      - npm run build  # 3 min
# Total: ~15 minutos

A versão otimizada com paralelismo e cache:

# Pipeline otimizado: paralelo com cache
jobs:
  install:
    steps:
      - uses: actions/cache@v4
        with:
          path: node_modules
          key: ${{ runner.os }}-node-${{ hashFiles('package-lock.json') }}
      - run: npm ci --prefer-offline

  lint:
    needs: install
    steps:
      - run: npm run lint

  typecheck:
    needs: install
    steps:
      - run: npm run typecheck

  test:
    needs: install
    steps:
      - run: npm run test

  build:
    needs: [lint, typecheck, test]
    steps:
      - run: npm run build
# Total: ~7 minutos

Com cache de node_modules funcionando, o npm ci leva segundos em vez de minutos. Com lint, typecheck e test rodando em paralelo, o tempo total cai pela metade.

🚀
Pro tip

Use test sharding para dividir suites de teste grandes em múltiplos jobs paralelos. O Jest tem suporte nativo a sharding: jest --shard=1/4, jest --shard=2/4, etc. Com 4 shards em 4 runners, uma suite de 8 minutos vira 2 minutos.

Comparação com alternativas

Turborepo (Vercel): para monorepos JavaScript, adiciona cache inteligente que evita re-executar tasks que não mudaram. Se você tem 10 pacotes e mudou só um, ele só roda o CI desse pacote.

Nx Cloud: similar ao Turborepo, mas com cache remoto distribuído entre todos os devs e runners. Um dev local que roda o teste pode usar o resultado em cache de outro dev que rodou o mesmo teste horas antes.

BuildKite: CI pago focado em performance, com runners próprios mais rápidos que os runners gratuitos do GitHub. Custo significativo para times pequenos.

O GitHub Actions ainda e a escolha mais comum por causa da integração nativa, mas com as otimizações corretas ele chega perto do desempenho das alternativas mais caras.

Pontos positivos e limitações

A otimização de CI tem ROI alto e mensurável: cada minuto a menos no pipeline e multiplicado por todos os PRs do time. Para um time de 10 devs que abre 5 PRs por dia, economizar 5 minutos por run são 250 minutos economizados diariamente.

As limitações são reais: paralelizar jobs aumenta o custo em runners pagos porque você usa mais runners simultaneamente. E preciso calcular se a redução no tempo de feedback compensa o aumento no custo de compute.

Testes flakey são o maior inimigo de pipelines rápidos. Um teste que falha 5% das vezes força re-runs que anulam todo o ganho de paralelismo. Investir em estabilidade dos testes tem retorno maior do que qualquer outra otimização de CI.

Casos de uso reais

Times com muitos coding agents: empresas que usam Claude Code ou Copilot Workspace para gerar PRs automatizados precisam de um CI que processe dezenas de PRs por hora sem criar filas.

Monorepos com dezenas de pacotes: um monorepo com 30 pacotes onde cada mudança dispara o CI de todos os pacotes e insustentável. Ferramentas como Nx ou Turborepo que só rebuildam o que mudou cortam o tempo em 80-90%.

Times que cresceram rapidamente: uma startup que era 3 devs e virou 30 provavelmente nunca revisou o pipeline de CI. Uma auditoria rápida geralmente revela ganhos imediatos.

Projetos open source com muitos PRs externos: CI lento desencoraja contribuições. Otimizar o pipeline e também uma estratégia de crescimento de comunidade.

Dicas e boas práticas

💡
Dica

Configure o cache key do node_modules com o hash do arquivo de lock (package-lock.json, yarn.lock, pnpm-lock.yaml). Assim o cache só invalida quando as dependências realmente mudarem, não a cada commit.

💡
Dica

Separe os testes pelo tempo de execução: testes rápidos (unitários, menos de 1s cada) rodam em paralelo sem sharding; testes lentos (integração, E2E) usam sharding. Não misture os dois no mesmo job.

🔴
Cuidado

Não paralelize jobs que compartilham estado: dois jobs que escrevem no mesmo banco de dados de teste vao colidir e gerar falhas aleatórias. Use banco de dados separado por job (containers Docker efémeros) ou isole o estado por variável de ambiente.

⚠️
Atenção

Monitore o custo dos runners pagos após otimizar. Configure alertas de gasto no GitHub Actions para não ser surpreendido com uma fatura inesperada no fim do mes.

Vale a pena?

Se o seu time usa IA para gerar código e o CI leva mais de 10 minutos, a otimização e quase sempre um dos melhores investimentos que você pode fazer agora. O retorno e imediato, mensurável e escala com o time.

Vale muito a pena se: seu CI leva mais de 10 minutos, você tem jobs sequenciais que poderiam ser paralelos, ou o cache de dependências esta invalidando a cada run. Qualquer um desses três pontos sozinho pode cortar o tempo do pipeline pela metade.

O próximo passo: abra o GitHub Actions do seu projeto e olhe o tempo dos últimos 20 runs. Se a media estiver acima de 8 minutos, comece pela auditoria da secao acima.