Object storage ou disco da aplicação: onde salvar arquivos

Use o disco da aplicação para arquivos temporários, caches e dados que só aquele processo lê. Use object storage para uploads de usuários, arquivos servidos ao público e tudo que precisa sobreviver à troca de servidor.

Atualizado em 7 min de leitura

Objetivos de aprendizado

Depois de ler este artigo, você vai conseguir:

  • Entender o que muda entre gravar no sistema de arquivos e enviar para um bucket
  • Comparar os dois em velocidade, persistência, escala, custo e entrega ao navegador
  • Migrar o upload de arquivos do disco para object storage sem mudar o resto do app
Nesta página

O primeiro upload de quase todo projeto é um fs.writeFile("./uploads/..."). Funciona no seu computador, funciona no primeiro deploy, e um dia as fotos dos usuários somem depois de uma atualização, ou metade delas dá 404 quando você sobe uma segunda instância. O problema não é o código: é o lugar onde o arquivo foi parar.

Os dois lugares mais comuns para guardar os arquivos de uma aplicação são o disco da própria aplicação e um object storage. Não há vencedor universal: cada um resolve um tipo de arquivo, e a maioria dos apps maduros usa os dois.

Disco da aplicaçãoNavegadoruploadLoad balancerAppinstância AAppinstância BGET404Discogato.jpgDiscovazioObject storageNavegadoruploadLoad balancerAppinstância AAppinstância BBucketgato.jpgdireto
No disco, cada instância só vê os próprios arquivos; num bucket, todas gravam no mesmo lugar.

O que é o disco da aplicação?#

É o sistema de arquivos que o seu processo enxerga: a pasta do projeto, o /tmp, qualquer caminho em que você grava com open() ou fs.writeFile. Ele oferece a semântica completa de arquivos: abrir, ler um trecho, gravar no meio, acrescentar no fim, renomear de forma atômica, travar. Tudo isso acontece localmente, sem rede, e por isso é rápido.

O ponto fraco é que esse disco pertence a uma máquina (ou a um container). Duas consequências:

  • Persistência depende da plataforma. A documentação do Docker é direta: dados gravados na camada gravável do container não persistem quando o container é destruído. Volumes e discos persistentes existem para resolver isso, mas cada provedor tem sua regra sobre o que sobrevive a um restart, a um redeploy ou à troca de servidor.
  • Não é compartilhado. Se você roda duas cópias do app, cada uma tem o próprio disco. O arquivo que a instância A gravou não existe para a instância B.

O guia The Twelve-Factor App resume a regra que a maioria das plataformas segue: o sistema de arquivos do processo serve como cache breve, de uma única transação, e qualquer dado que precise persistir vai para um serviço externo com estado.

O que é object storage?#

Object storage guarda arquivos como objetos dentro de buckets, cada um identificado por uma chave como uploads/2026/foto.webp. Você fala com ele por uma API HTTP, em geral compatível com S3: envia o arquivo inteiro com PUT, lê com GET, apaga com DELETE.

Ele troca a semântica de arquivo por outras vantagens. No Amazon S3, gravações e exclusões têm consistência forte de leitura após escrita: assim que o PUT responde com sucesso, qualquer leitor em qualquer servidor vê o arquivo novo. A capacidade cresce sem você redimensionar disco, e o arquivo ganha uma URL que o navegador pode baixar direto, com cache de CDN, ou por uma URL assinada quando é privado.

O preço disso: não há edição parcial. No S3 padrão, para mudar um byte você envia o objeto inteiro de novo. O append existe só numa classe específica (S3 Express One Zone, em directory buckets). Cada operação também é uma requisição de rede, com latência bem maior que a de um disco local; a AWS vende uma classe à parte justamente para baixar a latência a um dígito de milissegundo.

Qual a diferença lado a lado?#

Critério Disco da aplicação Object storage
Acesso Sistema de arquivos (open, fs) API HTTP (PUT, GET, DELETE)
Latência por operação Muito baixa, local Uma ida e volta pela rede
Editar um trecho ou acrescentar Sim Não (objeto inteiro), salvo classes específicas
Compartilhado entre instâncias Não Sim
Sobrevive à troca de container ou servidor Depende da plataforma Sim, independe do app
Capacidade Limitada ao disco da máquina Cresce conforme o uso
Servir ao navegador Passa pelo seu app URL direta, CDN, link assinado
Custo típico Incluso no servidor Por GB armazenado, às vezes por requisição e por saída
Bom para Temporários, caches, banco local, sessões Uploads, mídia, exports, cópias de segurança

O custo da última linha muda bastante entre provedores. Muitos cobram também pelo tráfego de saída, o que pesa quando você serve mídia; veja o que são taxas de egress.

Quando o disco da aplicação é a escolha certa?#

  • Arquivos temporários. Redimensionar uma imagem, descompactar um ZIP, gerar um PDF antes de enviar. Use o diretório temporário do sistema e apague no fim.
  • Caches que podem ser refeitos. Se o arquivo sumir, o app recria. Perder o cache custa tempo, não dados.
  • Bancos embutidos e arquivos de estado de um único processo. SQLite, a pasta de sessão de um bot de WhatsApp, índices locais. Precisam de escrita no meio do arquivo e de baixa latência, coisas que object storage não oferece. Aqui o disco precisa ser persistente, e vale mandar cópias periódicas para fora.
  • Configuração e código. O que vem no deploy fica no disco por definição.

Quando object storage é a escolha certa?#

  • Uploads de usuários. Avatares, anexos, documentos. São dados do usuário, não do servidor, e precisam sobreviver a qualquer deploy. Para o padrão completo de "arquivo no storage, chave no banco", veja imagens no banco ou em object storage.
  • Arquivos servidos ao público. Imagens de produto, vídeos, downloads. Saindo direto do storage ou da CDN, eles não ocupam a banda nem a memória do seu app.
  • Mais de uma instância. Assim que você coloca um load balancer na frente de duas cópias do app, o disco local deixa de ser uma opção para arquivos compartilhados.
  • Arquivos grandes ou volume que cresce. Gigabytes de mídia não cabem bem num disco que você precisa redimensionar à mão.
  • Cópias de segurança. Uma cópia guardada no mesmo disco que ela protege não protege nada.

Para entender onde o block storage (o tipo de disco que fica por trás de um volume) entra nessa conta, leia object, block e file storage.

Como migrar os uploads do disco para object storage?#

A troca costuma ser pequena: onde havia uma gravação em disco, entra um PUT no bucket, e o banco passa a guardar a chave em vez do caminho local. Exemplo em Node.js com o AWS SDK v3, que funciona com qualquer storage compatível com S3:

js
// npm install @aws-sdk/client-s3
import { randomUUID } from "node:crypto";
import { PutObjectCommand, S3Client } from "@aws-sdk/client-s3";

const s3 = new S3Client({
  region: process.env.S3_REGION ?? "us-east-1",
  endpoint: process.env.S3_ENDPOINT, // omita na AWS; defina num storage compatível
  forcePathStyle: process.env.S3_PATH_STYLE === "true", // alguns storages compatíveis exigem
  credentials: {
    accessKeyId: process.env.S3_ACCESS_KEY,
    secretAccessKey: process.env.S3_SECRET_KEY,
  },
});

// Antes: await writeFile(`./uploads/${nome}`, dados)
export async function salvarUpload(dados, contentType) {
  const key = `uploads/${randomUUID()}`;
  await s3.send(
    new PutObjectCommand({
      Bucket: process.env.S3_BUCKET,
      Key: key,
      Body: dados,
      ContentType: contentType,
    }),
  );
  return key; // guarde a chave no banco, não um caminho do disco
}

Três cuidados na migração:

  1. Mova os arquivos antigos. Um aws s3 sync ./uploads s3://seu-bucket/uploads --endpoint-url "$S3_ENDPOINT" copia o que já existe. Depois, atualize no banco os caminhos antigos para as novas chaves.
  2. Mantenha o disco como rascunho. Se você processa o arquivo antes de guardar (miniatura, conversão), faça isso no diretório temporário e envie só o resultado.
  3. Decida a visibilidade. Arquivos públicos ganham URL direta; privados abrem por link assinado. Veja arquivos públicos ou privados.

Como fazer isso na Square Cloud#

Na Square Cloud, os dois lugares existem. O disco da aplicação é persistente entre restarts e deploys: um novo commit (ZIP ou push) sobrescreve só os arquivos que vêm nele, e o resto fica. É por isso que a pasta de autenticação de um bot de WhatsApp continua conectada depois de um restart. Você também abre e edita esses arquivos pelo navegador, sem redeploy. Só que cada aplicação tem o próprio disco. Se você usa load balancing para servir um domínio com várias aplicações, elas não compartilham arquivos, então os uploads compartilhados devem ir para o object storage.

O Blob Storage é o object storage da plataforma, com API compatível com S3: o código acima funciona apontando S3_ENDPOINT para https://s3-blob.squarecloud.app (região auto), e o aws-cli e o rclone servem para a migração. Arquivos têm até 10 GB, e o multipart só é obrigatório acima de 100 MB. Arquivos públicos saem por uma CDN global na edge, e os privados abrem por link temporário de até 24 horas ou por link de compartilhamento revogável de até 30 dias.

Não há taxa de saída nem de entrada, e todo plano inclui uma cota de 5 GB a 250 GB. Regras por pasta definem visibilidade, expiração e limpeza automática, o que ajuda a manter a pasta de temporários sob controle.

Veja os detalhes e as cotas na página do Blob Storage.

Blob Storage

Object storage compatível com S3, sem taxa de saída

Saiba mais

Perguntas frequentes

Arquivos salvos no disco do container somem?

Depende de como a plataforma trata o container. A documentação do Docker diz que dados gravados na camada do container não persistem quando o container é destruído. Volumes e discos persistentes mudam isso, então confira a regra do seu provedor.

Posso usar object storage como se fosse uma pasta?

Só em parte. Você lê e grava arquivos inteiros por HTTP, com uma chave parecida com um caminho. Não há edição de um trecho no meio do arquivo nem append no S3 padrão: para mudar um objeto, você envia uma versão nova inteira.

Dá para rodar um banco SQLite em object storage?

Não diretamente. O SQLite precisa ler e gravar páginas pequenas no meio do arquivo, o que exige um sistema de arquivos de verdade. Mantenha o arquivo do banco no disco e envie cópias periódicas para o object storage.

Object storage é mais lento que o disco?

Para cada operação, sim: cada leitura é uma requisição HTTP pela rede. Para servir arquivos a muitos usuários, ele costuma ganhar, porque entrega direto ao navegador e pode ficar atrás de uma CDN sem passar pelo seu app.

Próximo artigoBackups em object storage: como e por que guardar fora do servidorEnvie dumps do banco e arquivos para um object storage compatível com S3 com rclone, agende no cron, aplique retenção e teste a restauração. Passo a passo.