Você dobra a CPU do runner. O deploy continua demorando o mesmo tempo. Adiciona memória, e nada.
Foi exatamente esse cenário que encontramos durante uma otimização recente do pipeline de deploy da Azion. A primeira reação poderia ter sido continuar aumentando recursos, mas antes decidimos responder uma pergunta simples: onde o tempo realmente estava sendo gasto?
A resposta acabou mudando completamente a direção da otimização. Em vez de um problema de processamento, descobrimos que boa parte do tempo era consumida esperando operações de I/O terminarem.
Continue a leitura para entender como identificar esse tipo de gargalo, por que mais CPU nem sempre resolve o problema e quais métricas realmente ajudam a encontrar a causa da lentidão.
Como identificar se o gargalo é I/O
Um processo pode estar lento porque está fazendo muito trabalho de processamento, ou porque está esperando os dados chegarem. No primeiro caso, mais CPU ajuda. No segundo, o processador já está ocioso. Adicionar núcleos não acelera uma fila de rede.
Um dos primeiros sinais está no uso de CPU durante a etapa lenta. Se a CPU permanece baixa enquanto o tempo cresce, o processo provavelmente passa boa parte do tempo esperando operações de I/O.
Ferramentas como top e htop costumam ser suficientes para observar isso. Mas baixa CPU sozinha não é diagnóstico definitivo: lock contention, rate limiting de API e processos em espera por resposta externa produzem o mesmo sinal.
Vale olhar também para o que o passo lento está fazendo. Upload de artefatos, pull de dependências e clone de repositório são operações de rede. O tempo delas depende de protocolo e paralelismo, não de CPU.
Quando você suspeitar de I/O de rede, aumentar o paralelismo é um teste útil, mas o resultado precisa ser interpretado com cuidado. Existem dois cenários com comportamentos opostos:
- Latency-bound (muitas requisições pequenas, RTT alto): aumentar workers ajuda, porque você sobrepõe os tempos de espera de cada requisição.
- Bandwidth-bound (link saturado): aumentar workers não ajuda. A banda já está no limite, e mais requisições simultâneas competem pelo mesmo pipe.
Se aumentar workers reduziu o tempo proporcionalmente, isso indica que o gargalo era latência. Se não moveu o ponteiro, o link provavelmente já estava saturado.
Meça cada etapa separadamente. A maioria das plataformas de CI tem logs com timestamp por step. Se não tiver, time resolve:
time ./seu-script-de-upload.shO comando reporta tempo de wall-clock e tempo de CPU. Para trabalho de I/O, você vai ver wall-clock alto com CPU baixa, o que confirma que o processo estava esperando, não computando.
Quer investigar mais a fundo? strace -c -p <PID> coleta estatísticas de chamadas de sistema e imprime um resumo ao final, útil para identificar se read, write e sendto estão dominando o tempo. No macOS, o equivalente é dtruss, mas versões recentes exigem desabilitar o System Integrity Protection (SIP) para funcionar.
O que fazer quando confirmar que é I/O
Troque o protocolo. O S3 suporta uploads paralelos de múltiplos objetos simultaneamente, com SDKs que já implementam paralelismo e retry nativamente. Para pipelines com centenas de arquivos pequenos, essa diferença aparece diretamente no tempo total de upload.
Ajuste o paralelismo. Um ponto de partida razoável é entre 2x e 4x o número de cores, não porque cores e I/O tenham relação causal, mas porque é um proxy útil quando não há dados melhores. Aumente gradualmente e observe se o tempo continua caindo. Quando parar, você encontrou o teto do link.
Reduza o volume transferido. Cache de artefatos entre deploys, transferência incremental e compressão de assets de texto (JS, CSS, HTML) funcionam bem. Compressão não ajuda em arquivos já comprimidos, como imagens e fontes.
Mais CPU e mais memória não vão mover o ponteiro se o processo está parado esperando rede.
Como aplicamos isso na Azion
O upload de arquivos estáticos consumia entre 1 minuto e 35 segundos e 1 minuto e 45 segundos. Com centenas de assets, essa etapa sozinha atrasava cada release. A primeira hipótese foi aumentar CPU e memória do ambiente de execução. O resultado foi zero.
As medições indicaram que a etapa era limitada principalmente pelo custo de múltiplas operações de rede sequenciais e pelo baixo paralelismo do processo de upload.
A solução veio em duas frentes: migração para o Azion Object Storage via protocolo S3, que suporta uploads paralelos de múltiplos arquivos simultaneamente, e aumento do paralelismo da CLI de um valor fixo de 5 workers para até 20 simultâneos, calculados dinamicamente com base nos cores de CPU como heurística de partida. As duas mudanças juntas derrubaram o upload para entre 3,5 e 9 segundos, uma redução de 90%.
O time de engenharia documentou o processo completo, com as decisões de arquitetura, o código de alocação dinâmica de workers e os benchmarks. Leia o post completo aqui.
O impacto no ciclo de desenvolvimento
Upload lento fragmenta o fluxo. Você inicia o processo, abre outra aba, perde o contexto. Com o upload caindo de quase dois minutos para menos de dez segundos, o ciclo entre escrever código e ver o resultado no ar fica curto o suficiente para testar, ajustar e republicar antes de perder o fio.
Em equipes que fazem deploy várias vezes por dia, essa diferença acumula no trabalho que você consegue fazer sem interrupção.
Essas melhorias já estão no pipeline do Azion Console. Se você deployou pela Azion nas últimas semanas, já está rodando no pipeline novo, sem nenhum ajuste no seu projeto.
CLI v4.21.0 ou superior para rodar com as melhorias de upload. Se você ainda não usa a Azion, crie sua conta em azion.com e faça o primeiro deploy hoje.
Perguntas frequentes
Como saber se o meu pipeline de CI/CD tem gargalo de I/O e não de CPU? Monitore o uso de CPU durante a etapa mais lenta do pipeline com top ou htop. Se a CPU permanece abaixo de 30-40% enquanto o tempo de execução cresce, o processo provavelmente está esperando operações de rede ou disco, não executando trabalho de processamento. Para confirmar, compare o tempo de wall-clock com o tempo de CPU reportado pelo comando time — wall-clock alto com CPU baixa é a assinatura típica de gargalo de I/O.
Por que aumentar workers paralelos resolve gargalo de I/O em alguns casos mas não em outros? Depende do tipo de gargalo. Se o problema é latência — muitas requisições pequenas esperando resposta individualmente — aumentar workers ajuda porque você sobrepõe os tempos de espera, reduzindo o tempo total. Se o problema é largura de banda saturada, mais workers não ajudam porque o link já está no limite e requisições adicionais competem pelo mesmo pipe. O teste prático: se dobrar o número de workers reduz o tempo proporcionalmente, o gargalo era latência. Se não mover o ponteiro, o limite é a banda disponível.
Qual a diferença entre gargalo de CPU, de I/O de disco e de I/O de rede em pipelines de CI/CD? Gargalo de CPU ocorre quando o processo usa ativamente os núcleos disponíveis — compilação pesada, transpilação, minificação. Adicionar CPU ou paralelismo de threads ajuda diretamente. Gargalo de I/O de disco acontece em operações de leitura e escrita de arquivos locais — instalação de dependências em disco lento, geração de muitos arquivos pequenos. SSDs e cache de artefatos são as principais mitigações. Gargalo de I/O de rede é o mais comum em etapas de upload e download — transferência de artefatos, pull de imagens Docker, clone de repositório. O tempo depende de protocolo, paralelismo e latência até o destino, não de recursos do runner.







