“Funciona em prod” — uma frase que o desenvolvedor diz quando um bug não pode ser reproduzido em produção, embora no ambiente de staging ou na máquina local o erro se manifeste de forma estável. O problema quase sempre é causado pela divergência de ambientes: versões diferentes de dependências, arquivos de configuração, estado do banco de dados ou configurações do servidor. De acordo com a análise da Stack Overflow Developer Survey 2024, 43% dos desenvolvedores enfrentam pelo menos uma vez por mês uma situação em que o código funciona na máquina local, mas falha em produção. Entendemos por que essa divergência ocorre e como evitá-la.
Pontos principais
“Funciona em prod” é uma expressão consolidada entre desenvolvedores que descreve uma situação em que o código funciona no servidor de produção, mas se recusa a funcionar no ambiente de teste ou na máquina local de um colega. Externamente soa como “não há problema”, embora na realidade o problema exista — simplesmente não pode ser reproduzido no ambiente de produção. A raiz da divergência está na diferença de configurações, versões e dados entre os ambientes.
A frase nasceu como o antípoda de outra desculpa conhecida — “funciona na minha máquina”. Se o desenvolvedor diz “funciona localmente”, o bug existe apenas para os outros. Mas se “funciona em prod”, o bug aparece apenas no staging ou no ambiente de teste, enquanto a produção está limpa. A ironia do destino: em ambos os casos o problema é real, simplesmente não se manifesta para quem está olhando. De acordo com o estudo DevOps Research and Assessment (DORA) 2023, equipes com alto nível de automação de implantação enfrentam essas divergências 3 vezes menos.
Do ponto de vista do negócio, a situação “funciona em prod” é mais perigosa do que parece. Se há um bug no staging mas não em prod, o desenvolvedor pode ignorá-lo — e então, com a próxima implantação, o erro irá para produção. Um alívio temporário se torna um problema futuro que terá que ser corrigido sob pressão dos usuários.
A razão psicológica da persistência da frase é um reflexo de defesa. O desenvolvedor que vê um erro no staging mas não em produção pode subestimar inconscientemente o problema: “se em produção está tudo bem, então não é urgente”. Um clássico viés cognitivo — o viés de sobrevivência, onde o sucesso visível da produção supera a ameaça potencial de uma futura falha.
A segunda razão é a responsabilidade difusa. Se a produção funciona mas o staging não, o culpado é o ambiente, não o código. O desenvolvedor se liberta da responsabilidade do erro e a transfere para o engenheiro DevOps ou o administrador. De acordo com o Atlassian State of DevOps 2022, em equipes sem um ambiente de implantação unificado (Docker, Kubernetes), essas transferências de responsabilidade ocorrem 60% mais frequentemente.
A terceira razão é o medo de um lançamento sem tempo de inatividade. Se o desenvolvedor corrigir o erro no staging e implantar a correção, isso exigirá outra revisão de código, testes e implantação. A frase “funciona em prod” permite adiar a correção até o próximo lançamento, reduzindo a carga de trabalho atual. Correções adiadas são uma das principais causas de acúmulo de dívida técnica nas equipes.
Produção e staging nunca são completamente idênticos — isso é tecnicamente impossível devido às diferenças de escala, carga e dados. No entanto, os parâmetros chave devem coincidir: a versão do sistema operacional, compilador, interpretador, banco de dados, servidor web e todas as dependências do projeto. Se pelo menos um parâmetro diferir, o comportamento do código pode mudar.
As principais diferenças entre ambientes incluem:
A contêinerização resolve a maior parte desses problemas. A mesma imagem Docker construída para produção deve ser usada também no staging. A única diferença são as variáveis de ambiente e as montagens de volume. De acordo com o Docker State of Application Development 2023, equipes que usam uma única imagem em todos os ambientes reduzem as discrepâncias em 74%.
| Parâmetro | Ambiente local | Staging | Produção |
|---|---|---|---|
| SO | macOS / Windows | Servidor Linux | Servidor Linux |
| Banco de dados | SQLite / MySQL local | Cluster MySQL | Cluster MySQL com replicação |
| Carga | 1 usuário | Simulação 10–100 | 1000+ reais |
| Dados | Fixtures | Mascarados | Reais |
| CDN / cache | Não | Parcial | Completo |
A primeira e mais frequente causa são as versões diferentes de dependências. O desenvolvedor instala um pacote localmente com a flag --save mas esquece de atualizar o package.json ou o arquivo lock. Ao implantar em produção, uma versão diferente é instalada e se comporta de maneira distinta. Para o ecossistema npm, o arquivo lock resolve completamente o problema; para outros gerenciadores de pacotes existem mecanismos análogos (Gemfile.lock, Podfile.lock, pubspec.lock).
A segunda causa são as variáveis de ambiente ausentes ou extras. O desenvolvedor usa um arquivo .env em sua máquina local, mas não adiciona as variáveis correspondentes ao pipeline de CI/CD ou ao servidor. O resultado: o código falha com um erro de conexão à API ou banco de dados. De acordo com a GitLab DevSecOps Survey 2023, 27% dos incidentes em produção estão relacionados a variáveis de ambiente incorretas.
A terceira causa é o estado do banco de dados. No staging, o banco pode conter registros que não existem em produção, ou vice-versa — podem faltar migrações. Um cenário típico: o desenvolvedor escreve código que trabalha com um novo campo na tabela, mas a migração ainda não foi aplicada em produção. Uma estratégia de migração com compatibilidade reversa é a única maneira de evitar essas situações.
A quarta causa são as configurações regionais e de idioma. Formatação de datas, separadores decimais, codificação de texto — tudo isso pode diferir na máquina local do desenvolvedor e no servidor. Isso é especialmente relevante para projetos com internacionalização. A solução é especificar explicitamente a localidade na configuração da aplicação e não depender das configurações do sistema.
O primeiro passo é comparar os logs de ambos os ambientes. A diferença no nível de registro muitas vezes oculta a causa: em produção pode estar ativado INFO, enquanto no staging está DEBUG. Configure o mesmo nível de registro e garanta que ambos os ambientes escrevam em um formato que permita a comparação automatizada. Use sistemas centralizados de coleta de logs — Sentry, Datadog, ELK Stack.
O segundo passo é verificar as versões das dependências. Compare os arquivos lock, liste os pacotes instalados em ambos os ambientes. Uma diferença em uma versão menor ou de patch é a causa mais provável da divergência. Ferramentas como npm ls, pip freeze, mvn dependency:tree ajudam a identificar rapidamente as discrepâncias.
O terceiro passo é reproduzir o ambiente de produção localmente. Use Docker Compose ou ferramentas similares para criar uma cópia exata da infraestrutura de produção. Se o erro se reproduzir em um contêiner local, o problema está no código, não no ambiente. Se não se reproduzir, procure uma diferença na configuração.
O quarto passo é verificar os feature flags e os testes A/B. Talvez o código funcione em um modo diferente em produção porque a flag incorreta está ativada. De acordo com o LaunchDarkly State of Feature Management 2023, até 40% do comportamento inesperado em produção está relacionado a valores incorretos de feature flags. Um manifesto único de flags para todos os ambientes resolve esse problema.
A principal ferramenta de prevenção é Infrastructure as Code (IaC). Todos os ambientes devem ser descritos em código: Dockerfile, docker-compose.yml, scripts Terraform ou playbooks Ansible. Alterações manuais no servidor são proibidas — qualquer mudança de configuração passa pelo repositório e revisão de código. Isso garante que todos os ambientes tenham a mesma configuração.
A segunda ferramenta mais importante é um pipeline CI/CD unificado. O mesmo script de compilação, teste e implantação deve ser usado para todos os ambientes. A única diferença são as variáveis alvo (URLs, chaves). Se o pipeline para staging e produção diferir nas etapas, as divergências são inevitáveis.
A terceira ferramenta é a sincronização automática de dados. Atualize periodicamente (diariamente ou conforme uma agenda) o staging com uma cópia anonimizada do banco de dados de produção. Isso permite testar o código com dados reais em vez de fixtures sintéticas. Ferramentas: pg_dump/pg_restore para PostgreSQL, mysqldump para MySQL, serviços especializados como DataGrip.
A quarta ferramenta é o monitoramento de divergências. Configure alertas quando diferenças entre staging e produção forem detectadas. Um script simples que compare os hashes dos arquivos de configuração ou as versões dos pacotes instalados economizará horas de depuração. A prevenção é sempre mais barata que o diagnóstico: prevenir divergências de ambientes requer menos esforço do que encontrar a causa do bug “funciona em prod”.
Perguntas frequentes
No primeiro caso, o bug é visível no staging mas não em prod. No segundo, todos veem o bug exceto o desenvolvedor cujo código funciona localmente. A raiz comum é a divergência de ambientes, mas a situação se manifesta em estágios diferentes.
Mostre que um bug no staging é um bug que já está pronto para ir para produção na próxima implantação. Corrigi-lo agora será mais barato do que um hotfix sob pressão dos usuários. Dê exemplos do histórico do projeto.
De acordo com DORA 2023, cerca de 25–30% dos incidentes em produção são causados por diferenças entre ambientes. Em equipes sem conteinerização, esse número chega a 50%. A conteinerização reduz para 10–15%.
Sim, esta é uma das causas comuns. Em produção, CDN, Varnish ou cache Redis está ativado, enquanto no staging não. Se o bug estiver relacionado à entrega de dados em cache, ele aparecerá no staging, mas será ocultado pelo cache em produção.
O Docker garante a identidade do ambiente em todos os estágios: desenvolvimento, teste, staging, produção. Se a imagem for construída uma vez e usada em todos os lugares, a divergência de versões e configurações é eliminada. Uma única imagem é a base da repetibilidade da implantação.
Resumo
Vamos desenvolver um aplicativo móvel chave na mão
A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.
Leia também