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.php gerado 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ão files, redis, memcached ou user (a própria aplicação decide).
  • session.save_path — onde guarda. Um caminho como /var/lib/php/sessions ou /tmp combinado com files significa, 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:

  1. 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.
  2. 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.
  3. 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ó.