Sessão, carrinho e imagem que somem quando a loja roda em dois servidores: o que precisa sair do disco local antes de duplicar capacidade
Quando a loja roda em dois servidores, cliente é deslogado, carrinho esvazia e imagens desaparecem. Descubra por que antes de contratar mais capacidade.
2026-09-19 · Equipe · 14 min de leitura
Cliente deslogado no meio da compra, carrinho que esvazia e foto que aparece para um visitante e some para outro têm a mesma raiz: parte do estado da loja foi gravada no disco de uma máquina, e a segunda máquina não enxerga esse disco. Descobrir o que ainda vive em disco local vem antes de contratar qualquer reforço.
Por que sessão, carrinho e imagem somem quando a loja roda em múltiplos servidores
Porque cada requisição do visitante pode cair numa máquina diferente, e o que a primeira máquina gravou no disco dela não existe no disco da segunda. Sessão, upload e cache são as três coisas que costumam estar nesse disco — por isso sessão, carrinho e imagem são justamente o que some quando a loja passa a rodar em múltiplos servidores.
Sessão, em uma frase, é o dado que guarda “quem é este visitante e o que ele já fez”, identificado por um cookie que fica no navegador. O cookie viaja junto com o cliente; o dado, só se estiver num lugar que as duas máquinas alcancem.
O que torna isso difícil de diagnosticar é que o sintoma é intermitente por natureza. Funciona, quebra, volta a funcionar — depende de qual máquina atendeu cada clique. O dono testa, dá certo, testa de novo e dá errado, e acaba culpando o plugin que instalou na semana passada.
Os sintomas típicos da estreia em duas máquinas são estes:
- O cliente é deslogado no meio da compra, sem ter feito nada.
- O carrinho esvazia ao atualizar a página — e volta a aparecer se atualizar mais uma vez.
- Uma imagem ou PDF abre para um visitante e dá 404 para outro, no mesmo link.
Nada disso é lentidão nem falta de capacidade. É o que quebra funcionalmente quando entra a segunda máquina — e a diferença entre multiplicar réplica e multiplicar máquina está em auto scaling em VPS.
Estado local: o que é e por que ele não sobrevive a mais de uma máquina
Estado é tudo que a aplicação grava e precisa reler depois: sessão, arquivo enviado, cache em disco, log. Quando esse dado fica no disco da própria máquina que o gravou, ele é estado local.
Um serviço sem estado atende cada requisição inteira e não guarda nada para a próxima. Qualquer cópia atende igual, então acrescentar cópia funciona. Um serviço com estado é o oposto: a segunda requisição depende do que a primeira gravou, e se a cópia que gravou não é a que atende agora, o dado simplesmente não existe.
Na linguagem do balcão: dois atendentes, cada um com sua própria gaveta. O cliente volta, é atendido pelo segundo, e a ficha dele está na gaveta do primeiro. Ninguém perdeu nada — só que quem atende não alcança.
E o ponto que costuma pegar o dono de surpresa: o disco não é compartilhado por padrão. Cada VPS e cada nó de nuvem tem o seu, e nada é copiado entre eles automaticamente. A exceção na loja típica é reveladora: o banco de dados já é tratado como serviço central, ao qual todas as máquinas perguntam — e é exatamente por isso que ele não quebra quando a aplicação é duplicada. Ele quebra de outro jeito, descrito em gargalo de banco de dados MySQL na VPS.
Antes de acusar a sessão: onde uma loja WordPress guarda cada coisa
Aqui vale uma correção que muda o diagnóstico em boa parte das lojas brasileiras. No WordPress, o login não depende de arquivo de sessão em disco: ele é um cookie assinado com as chaves e salts do wp-config.php e conferido contra um token guardado no banco. Se as duas máquinas rodam a mesma instalação, com o mesmo wp-config.php, o login atravessa bem.
E no WooCommerce, a sessão do carrinho fica numa tabela do banco (wp_woocommerce_sessions), identificada por cookie. Ou seja: numa instalação padrão, carrinho e login não somem só porque entrou uma segunda máquina.
O que derruba os dois, na prática, é outra coisa:
- Réplicas com chaves e salts diferentes — cada máquina com o seu
wp-config.phpgerado na instalação. Aí o cookie assinado por uma não é aceito pela outra, e o cliente é deslogado ao trocar de máquina. - Plugin ou tema que chama
session_start()e passa a gravar arquivo de sessão no disco da máquina. É comum em checkout customizado, multi-step, calculadora de frete e área do cliente. - Aplicação fora do WordPress — loja própria, Laravel com driver de sessão
file, painel feito em casa. Nesses casos a sessão em arquivo local é o padrão, e ela quebra exatamente como descrito acima.
Conclusão prática: não presuma onde está a sessão. Descubra. É o próximo passo.
Os sintomas e o estado que está por trás de cada um
| O que o cliente vê | Estado envolvido | Onde costuma estar gravado |
|---|---|---|
| Deslogado, “sessão expirada” | Sessão de login | Arquivo de sessão no disco — ou chaves diferentes em cada réplica |
| Carrinho que esvazia e volta | Sessão do carrinho | Arquivo de sessão no disco, quando o carrinho não está no banco |
| Imagem de produto quebrada | Upload | Pasta de uploads da aplicação |
| Boleto, nota ou etiqueta que não abre | Arquivo gerado na hora | Pasta temporária da máquina que gerou |
| Página desatualizada, layout alternando | Cache em disco | Diretório de cache de cada réplica |
Há ainda o token de formulário inválido no meio do pagamento. Esse merece cuidado no diagnóstico: no WordPress o nonce é derivado das chaves do wp-config.php, então ele só falha entre máquinas quando as chaves divergem ou quando o token foi guardado em sessão de arquivo. Não é um sintoma automático de duas máquinas.
O que separa tudo isso de falta de capacidade é a ausência de sinal de aperto. Não há CPU no teto, não aparece nenhum dos erros 502 e 503 que indicam servidor no limite, a máquina está saudável — e a loja está errada mesmo assim. Quando o sintoma é lentidão e não sumiço, o caminho é o outro: WooCommerce lento com muito acesso.
Como descobrir onde sua aplicação guarda sessão e upload hoje
Em PHP, duas configurações respondem quase tudo sobre sessão:
session.save_handler— quem guarda. Os valores usuais sãofiles,redis,memcachedouuser(a própria aplicação decide).session.save_path— onde guarda. Um caminho como/var/lib/php/sessionsou/tmpcombinado comfilessignifica, sem margem para dúvida: estado local.
Dá para ler isso sem terminal, pela página de informações do PHP no painel da hospedagem ou pela própria loja — no WordPress, em Ferramentas → Saúde do site → Informações.
Depois, o resto do inventário:
- Chaves de autenticação. Se um dia houver duas máquinas, as duas precisam do mesmo bloco de chaves e salts do
wp-config.php. Conferir isso é de graça e evita o deslogamento em massa. - Uploads. No WordPress e no WooCommerce, tudo vive em
wp-content/uploads: imagem de produto, anexo, mídia da página. Isso cresce sozinho, sem deploy nenhum — é dado, não código. - Cache de plugin. Diretório próprio dentro de
wp-content, com cache de página, cache de objeto em disco e arquivos minificados de CSS e JS. A pergunta aqui não é onde fica, é se ele pode divergir entre réplicas sem estragar a página. - Arquivo gerado sob demanda. Boleto, nota fiscal, etiqueta de envio, exportação de relatório. Costuma ir para uma pasta temporária e ser entregue por link alguns segundos depois — e esse link pode cair na outra máquina.
O produto dessa etapa é uma lista escrita de tudo que a aplicação grava em disco. Sem essa lista, não existe como julgar se a loja está pronta para uma segunda máquina — e qualquer decisão de arquitetura tomada antes dela é palpite.
Como testar isso com um servidor só, antes de gastar com o segundo
Três testes que não exigem contratar nada:
- Sessão. Fora do horário de venda, mova (não apague) o conteúdo do diretório de sessão para outra pasta e navegue pela loja logado e com carrinho. Se o estado se perde, ele era local mesmo. Se nada acontece, sessão e carrinho estão em outro lugar — banco ou cookie — e já atravessam máquina.
- Upload. Suba uma imagem nova e confira se ela foi parar dentro do diretório da aplicação. Se foi, ela não vai existir na segunda máquina.
- Arquivo gerado. Emita um boleto ou um relatório e veja se o link entregue ao cliente aponta para um arquivo no disco da máquina que gerou.
O teste mais fiel é outro, e continua barato: suba uma segunda cópia da aplicação na mesma VPS, em outra porta, apontando para o mesmo banco, e navegue alternando entre as duas. É a reprodução honesta do problema — e, de quebra, mostra na hora se as duas cópias estão com chaves diferentes.
Faça tudo com backup do que for movido. O objetivo é provar o comportamento agora, não descobri-lo no dia do pico. Junte esse resultado com a medição de teto de quantos acessos simultâneos a sua VPS aguenta: são os dois pré-requisitos de qualquer burst.
Sticky session e outros remendos: o que cada um resolve e o que continua quebrado
Sticky session é o balanceador — a peça que distribui as requisições entre as máquinas — amarrando o visitante sempre na mesma máquina, em geral por cookie ou por IP. Resolve o sintoma mais barulhento: se a sessão está em arquivo, o cliente volta sempre para a gaveta certa.
O que ela não resolve: o balanceador não move arquivo. O upload continua existindo só onde foi gravado, e a imagem segue aparecendo para uns e não para outros. E há um custo escondido — se a máquina daquele visitante cai, ou é removida quando o pico passa, ele perde a sessão de qualquer jeito. A distribuição também tende a ficar desigual, com uma máquina carregando mais que a outra.
Dois outros atalhos aparecem sempre:
- Sincronizar a pasta por rsync entre as máquinas. É cópia periódica, então sempre existe uma janela em que o arquivo está só de um lado; quanto mais movimento, maior a janela. É o remendo que falha justamente quando é mais necessário.
- Sessão em cookie assinado. Tira o arquivo do disco, mas tem limite de tamanho, exige suporte da aplicação (o WordPress não faz isso nativamente) e coloca no navegador do cliente um dado que passa a viajar em toda requisição.
A regra que separa remendo de solução: remendo evita o sintoma sem tirar o estado do disco local. Solução tira.
As saídas de verdade — e o preço de cada uma dita na cara
Para sessão, são duas:
- No banco de dados. É o caminho mais simples em loja WordPress, e é onde o carrinho do WooCommerce já está. O efeito colateral é somar gravação a um banco que talvez já seja o seu gargalo.
- Em Redis — um serviço que guarda dado na memória, fora da aplicação, e que todas as máquinas consultam. Rápido e feito para isso, ao custo de mais um serviço para manter de pé: se ele cai, quem depende dele perde a sessão ao mesmo tempo.
Para uploads, também duas:
- Volume compartilhado — uma pasta em rede que as duas máquinas montam. O código da loja não muda, e o preço é latência maior por arquivo e um novo ponto único de falha.
- Storage de objeto (S3 e equivalentes), onde cada arquivo vira uma URL. É a saída que sobrevive à máquina sumir. Exige plugin ou ajuste no código, e a migração dos arquivos antigos é um trabalho de uma vez só.
Para cache, a escolha costuma ser o oposto: cache local por réplica, cada uma com o seu, aceitando divergência de segundos. Compartilhar cache raramente compensa o custo que acrescenta. E arquivo gerado sob demanda — boleto, nota, exportação — deve ser tratado como upload, não como temporário, ou então gerado e entregue na mesma requisição, sem link para depois.
A ordem de execução não é indiferente: chaves iguais e sessão resolvida primeiro, porque é isso que quebra a compra; upload depois; cache por último. Quem for mexer na camada de cache deve ler antes o que ela absorve e o que não absorve, em cache de página e CDN no pico de acesso.
A regra do SwarmBurst: o que fica pinado no nó fixo e o que recebe réplica
No SwarmBurst, banco, uploads e sessão ficam pinados no nó fixo por regra de posicionamento no Docker Swarm — a instrução que diz ao orquestrador em qual máquina cada serviço pode rodar. Só o serviço sem estado recebe réplica no nó de reforço, e é ele que absorve o pico e desaparece quando o pico passa.
O que isso entrega: o nó extra pode nascer e morrer sem levar junto sessão de cliente nem arquivo de produto.
O que isso não entrega: pinar não transforma estado local em estado compartilhado. Se a aplicação lê upload do disco dela, a réplica no nó de reforço continua sem enxergar esse arquivo — e a imagem vai faltar para quem for atendido lá.
A parte honesta, então: loja com sessão e upload presos em disco local não está pronta para burst nenhum. Esse arrumo vem antes de qualquer conversa sobre pico, inclusive antes do orçamento de aumentar o plano ou pagar reforço só no pico. Quem chegou aqui sem o conceito encontra ele inteiro em o que é cloud bursting; quem já está com data marcada deve começar por preparar a loja para a Black Friday sem trocar de servidor.
Quero revisar o inventário de estado da minha loja
Se você já fez a lista do que a aplicação grava em disco, é uma conversa no WhatsApp para ler essa lista junto e dizer o que falta antes de qualquer reforço.
Perguntas frequentes
Por que o cliente é deslogado quando a loja roda em dois servidores?
Porque cada requisição pode cair numa máquina diferente, e o que a primeira máquina gravou no disco dela não existe no disco da segunda. No WordPress, o login é um cookie assinado com as chaves do wp-config.php. Se as duas máquinas rodem a mesma instalação com as mesmas chaves, o login atravessa bem. Mas se cada máquina tiver chaves e salts diferentes, o cookie assinado por uma não é aceito pela outra.
Qual é a diferença entre sticky session, sessão em banco de dados e sessão em Redis?
Sticky session amarra o visitante sempre na mesma máquina, resolvendo o deslogamento intermitente. Mas não move arquivo e não protege contra queda da máquina. Sessão em banco de dados é o caminho mais simples em WordPress, pois o carrinho do WooCommerce já fica lá, mas soma gravação ao banco que talvez já seja seu gargalo. Sessão em Redis é um serviço na memória que todas as máquinas consultam - rápido e feito para isso, mas introduz mais um serviço para manter.
Como descobrir onde minha aplicação guarda sessão e upload?
Em PHP, duas configurações respondem quase tudo: session.save_handler (quem guarda - files, redis, memcached, ou user) e session.save_path (onde guarda). No WordPress, isso aparece em Ferramentas > Saúde do site > Informações. Para uploads, tudo vive em wp-content/uploads - imagem de produto, anexo, mídia. Há ainda cache de plugin e arquivos gerados sob demanda em pastas temporárias.
Dá para testar esse problema antes de contratar o segundo servidor?
Sim. Você pode mover o conteúdo do diretório de sessão para outra pasta e navegar logado - se a sessão se perde, ela era local. Pode subir uma imagem nova e conferir se está no diretório da aplicação. O teste mais fiel é subir uma segunda cópia da aplicação na mesma VPS, em outra porta, apontando para o mesmo banco, e navegar alternando entre as duas. Isso reproduz honestamente o problema.
Qual é a diferença entre volume compartilhado e storage de objeto para uploads?
Volume compartilhado é uma pasta em rede que as duas máquinas montam - o código não muda, mas há latência maior por arquivo e um novo ponto único de falha. Storage de objeto, como S3, transforma cada arquivo numa URL, sobrevive à máquina desaparecer, exige plugin ou ajuste no código e a migração dos arquivos antigos é um trabalho de uma vez só.