Cold start é a penalidade de latência paga quando a plataforma serverless precisa criar e inicializar um novo ambiente antes de executar o seu código. Não é um bug, é uma fatura: scale-to-zero significa que ambientes ociosos são recolhidos para que ficar parado não custe nada — e a primeira request depois da recolha paga o setup. Entender as fases, os números reais e a escada de mitigação transforma cold starts de um medo vago em uma decisão de engenharia com preço.
Principais pontos
| Pergunta | Resposta |
|---|---|
| A causa | Scale-to-zero: sem custo ocioso ⇒ alguém inicializa sob demanda |
| As fases | Alocar → baixar o código → subir o runtime → rodar o init → atender |
| Os números | ~100 ms–1 s+ típico; menos de 1% do tráfego constante, quase todo o tráfego esparso |
| O gatilho esquecido | Scale-out de concorrência — warmers não resolvem |
| A escada | Correções gratuitas no código primeiro; capacidade paga sempre warm por último |
As cinco fases, com o relógio correndo
COLD START custo típico
1 Alocar um sandbox (micro-VM / contêiner) ~50–100 ms
2 Baixar o pacote de deploy 50–500 ms ← escala com o tamanho do bundle
3 Subir o runtime da linguagem 50–1.000 ms ← interpretador rápido, VM lenta
4 Rodar o SEU init (imports, clients de SDK, conexões) 0 ms–segundos ← a maior alavanca que você controla
5 Invocar o handler o trabalho de verdade
WARM START = só o passo 5 (+ ~1–10 ms de descongelamento). O ambiente foi
congelado, não destruído — conexões e caches fora do handler sobrevivem,
e é por isso que disciplina no init paga aluguel em cada request seguinte.
O contraste que vale a pena medir você mesmo — uma função em um backend sempre em execução, onde a corrida nunca começa:
// JavaScript / Node.js — Back4app JS SDK
// Cloud Code runs on an always-on backend — no scale-from-zero cold start
const t0 = Date.now();
const avg = await Parse.Cloud.run('averageStars', { movie: 'Arrival' });
console.log(`Round trip: ${Date.now() - t0} ms`); // consistent p50 ≈ p99
// The FaaS mitigations (warmers, provisioned capacity, bundle diets)
// don't apply here: the process serving this call was already running. // Flutter / Dart — Back4app Flutter SDK
// Cloud Code runs on an always-on backend — no scale-from-zero cold start
final t0 = DateTime.now();
final response = await ParseCloudFunction('averageStars')
.execute(parameters: {'movie': 'Arrival'});
print('Round trip: ${DateTime.now().difference(t0).inMilliseconds} ms');
// Consistent p50 ≈ p99: the process serving this call was already running. // iOS / Swift — Back4app Swift SDK
// Cloud Code runs on an always-on backend — no scale-from-zero cold start
let t0 = Date()
let avg: Double = try await Cloud.run(name: "averageStars",
parameters: ["movie": "Arrival"])
print("Round trip: \(Int(Date().timeIntervalSince(t0) * 1000)) ms")
// Consistent p50 ≈ p99: the process serving this call was already running. // Android / Kotlin — Back4app Android SDK
// Cloud Code runs on an always-on backend — no scale-from-zero cold start
val t0 = System.currentTimeMillis()
val avg = ParseCloud.callFunction<Double>(
"averageStars", mapOf("movie" to "Arrival"))
println("Round trip: ${System.currentTimeMillis() - t0} ms")
// Consistent p50 ≈ p99: the process serving this call was already running. Cold starts vs. warm starts
| Cold start | Warm start | |
|---|---|---|
| Ambiente | Criado e inicializado agora | Reutilizado, descongelado |
| Latência extra | ~100 ms a segundos | Milissegundos de um dígito |
| Quando | Primeira chamada, pós-deploy, pós-ociosidade, scale-out | Tráfego constante dentro do pool warm |
| Código de init | Roda | Pulado — seus resultados persistem |
| Nota de cobrança | Nas grandes plataformas, a fase de init hoje é cobrada como execução | Só o tempo do handler |
Quanto duram, e com que frequência — honestamente
A duração depende sobretudo do runtime e do bundle: runtimes interpretados (JavaScript, Python) tipicamente 200–400 ms; compilados (Go, Rust) abaixo de ~100–300 ms; baseados em VM (JVM, .NET) de 500 ms a vários segundos, com snapshot-restore cortando dramaticamente o número da JVM; os p99 rodam 2–3× a mediana, e árvores de dependências inchadas já foram medidas multiplicando o startup várias vezes, independentemente da linguagem. A frequência é onde a maioria dos explicadores conta só metade da história. Tráfego de produção constante vê cold starts em menos de um por cento das invocações — tranquilizador, e real. Mas a conta se inverte no tráfego esparso: a aritmética de Fowler — uma função invocada uma vez por hora dá cold start praticamente toda vez, e ambientes de dev veem taxas frias de 30–90%. E o gatilho que todo mundo esquece: o scale-out de concorrência — quando dez requests chegam e três ambientes estão warm, sete dão cold start ao mesmo tempo, no meio do seu pico de tráfego, que é exatamente quando dói.
A escada de mitigação, com preços
Em ordem de custo, do mais barato primeiro. Gratuito, no código: encolha o bundle de deploy e pode as dependências — a maior alavanca que a maioria dos times ainda não puxou; importe só os submódulos do SDK que você usa; carregue sob demanda módulos pesados de caminhos raros; abra conexões de banco no escopo de init para que warm starts as reutilizem. Barato, na configuração: aumente a memória (a CPU escala junto, de forma material para runtimes de VM); habilite snapshot-restore onde a plataforma oferecer. Frágil, remédio caseiro: pings de keep-warm — uma request agendada a cada poucos minutos mantém um ambiente warm e não faz nada pelo scale-out; status honesto: gambiarra legada. Pago, definitivo: capacidade pré-provisionada (“concorrência provisionada”, “instâncias mínimas”) — N ambientes sempre inicializados, cold starts eliminados até N, a um preço sempre ativo que cancela em parte o pagar-pelo-uso. A ironia merece a própria frase: a correção para o problema-assinatura do serverless é comprar de volta o servidor que prometeram que você não tinha.
Isolates: como os runtimes de edge contornam o problema
Plataformas de edge reportam cold starts próximos de zero mudando a arquitetura em vez de aquecê-la: no lugar de subir um contêiner ou micro-VM por tenant, elas rodam milhares de isolates V8 — sandboxes no estilo aba de navegador — dentro de um único processo de longa duração. Criar um contexto de isolate custa milissegundos de um dígito e megabytes, não centenas de milissegundos e um boot de runtime. A troca é o ambiente: um subconjunto de APIs padrão da web, limites apertados de CPU, sem sistema de arquivos — uma ferramenta diferente, não um upgrade gratuito, coberta com honestidade no verbete de edge.
Casos de uso comuns onde cold starts importam
- APIs interativas — um humano está olhando o spinner; o p99 inclui a cauda fria.
- Pagamentos e checkout — sensíveis a latência e precificados em conversão.
- Login e emissão de sessão — o caminho da primeira impressão, muitas vezes depois de períodos ociosos.
- Endpoints de tráfego esparso — ferramentas de admin e APIs internas onde quase toda chamada é fria.
- Onde não importam: jobs enfileirados, webhooks, trabalho agendado — o assíncrono absorve a cauda de forma invisível.
Você deveria otimizar cold starts? Matriz de decisão
| Situação | Faça |
|---|---|
| Cargas assíncronas/enfileiradas/agendadas | Nada — cold starts são invisíveis aqui |
| Tráfego alto e constante, interativo | Correções no código; meça antes de pagar |
| Tráfego esparso, voltado ao usuário | Instâncias mínimas nesse caminho — ou um backend sempre ativo |
| Runtime de VM (JVM/.NET), sensível a latência | Snapshot-restore + memória primeiro |
| Tráfego com picos e p99 rígido | Capacidade provisionada dimensionada para o pico |
| Lógica estilo gateway, usuários globais | Runtimes de edge baseados em isolates |
| A maioria dos backends de app em um BaaS | Já resolvido — não existe scale-from-zero |
Limitações e trade-offs
- Mitigações trocam dinheiro por latência. Capacidade pré-aquecida é uma conta permanente; decida por endpoint, não para a plataforma inteira.
- Warmers mentem para os dashboards. Uma função pingada parece saudável enquanto cada pico real de tráfego ainda dá cold start no scale-out.
- Economia no init tem limites. Lazy-loading agressivo move a latência dos cold starts para os caminhos de primeiro uso — meça para onde você a moveu.
- Benchmarks envelhecem rápido. Rankings de runtime e números de plataforma mudam a cada ano; números velhos (e penalidades de rede corrigidas há muito tempo) ainda circulam — date seus dados.
- A métrica que importa é a sua. Estatísticas de percentual frio descrevem o tráfego de outra pessoa; só o seu p99 sob carga parecida com produção justifica gastar.
Cold starts no Back4app
O Back4app é uma plataforma open-source de Backend as a Service (BaaS) que combina banco de dados gerenciado, APIs REST e GraphQL geradas automaticamente, autenticação, armazenamento de arquivos e funções serverless com Cloud Code. A história de cold start aqui é ausência arquitetural: o Cloud Code roda dentro de um backend sempre em execução, então não existe o momento de scale-from-zero — sem corrida de init, sem pool warm para gerenciar, sem linha de capacidade provisionada na fatura — e a medição dos code tabs mostra o que isso compra: p50 e p99 a uma distância de grito um do outro, na primeira request do dia e na milionésima. A troca é a nomeada em BaaS vs. serverless: você abre mão da granularidade de cobrança por invocação em troca de latência consistente e um banco de dados anexado — o que, para backends de apps voltados ao usuário, costuma ser o lado da troca que os usuários conseguem sentir.
Perguntas frequentes
O que é cold start?
É a latência extra quando a plataforma serverless precisa construir um ambiente de execução do zero antes de rodar sua função: alocar uma instância, baixar seu código, subir o runtime, rodar seu código de inicialização — e só então atender a request. Um warm start pula direto para o último passo, porque reutiliza um ambiente que já passou por tudo isso.
Quanto tempo dura um cold start?
Tipicamente de cem milissegundos a mais de um segundo. Runtimes interpretados (JavaScript, Python) ficam em torno de 200–400 ms; compilados (Go, Rust) podem cair abaixo de 100 ms; runtimes baseados em VM (JVM, .NET) vão de 500 ms a vários segundos, com setups pesados em frameworks no pior caso. As latências de cauda costumam ser duas a três vezes a mediana.
Qual a diferença entre cold start e warm start?
Um warm start reutiliza um ambiente congelado mas já inicializado: a plataforma o descongela e chama seu handler, adicionando milissegundos de um dígito. Tudo o que vive fora do handler — conexões, caches, módulos carregados — sobrevive entre invocações, e é por isso que disciplina na inicialização rende em cada warm start seguinte.
Com que frequência os cold starts acontecem?
As duas respostas são verdadeiras: menos de um por cento das invocações em tráfego de produção constante — e a esmagadora maioria em tráfego esparso, já que uma função chamada de hora em hora dá cold start quase toda vez. Rajadas adicionam mais: cada request concorrente acima do pool warm dispara o próprio cold start.
Como reduzir cold starts?
Suba a escada do gratuito ao pago: encolha o bundle de deploy e pode as dependências (o maior ganho gratuito), carregue sob demanda os imports raramente usados, escolha um runtime mais rápido, aumente a memória (a CPU escala junto), use snapshot-restore onde a plataforma oferecer — e só então pague por capacidade pré-aquecida.
O que é concorrência provisionada?
A solução paga, também vendida como instâncias mínimas: a plataforma mantém N ambientes inicializados antes da demanda, eliminando cold starts para tráfego até N. A ironia já vem no preço — você reintroduz custo sempre ativo em um modelo de pagar pelo uso, e é por isso que ela pertence apenas aos caminhos críticos de latência.
Pings de keep-warm funcionam?
Parcialmente, e de forma frágil: um ping agendado mantém um ambiente warm, mas não faz nada quando a concorrência escala — a décima request simultânea dá cold start por mais warm que o primeiro ambiente esteja. Warmers são a gambiarra legada; instâncias mínimas são a resposta suportada pelas plataformas.
Cold starts realmente importam para o meu app?
Só onde um humano está esperando: caminhos síncronos e voltados ao usuário, como APIs interativas e pagamentos. Filas, webhooks, jobs agendados e outros trabalhos assíncronos absorvem cold starts de forma invisível. Meça a latência de cauda sob tráfego parecido com produção antes de gastar dinheiro com o problema.