IRCNF

Diziam que SQLite era um banco de dados de brinquedo. Na verdade, ele roda metade da internet.

Compartilhar:
Diziam que SQLite era um banco de dados de brinquedo. Na verdade, ele roda metade da internet.

Há cerca de um trilhão de bancos de dados SQLite em uso ativo. Um trilhão. Cada iPhone e dispositivo Android carrega vários deles. Toda instalação de Chrome, Firefox, macOS e Windows o embute. Adobe, Airbus, Apple, Google e o exército dos EUA distribuem software com SQLite internamente. Por pura contagem de implantações, é o motor de banco de dados mais usado já criado — e, durante a maior parte de seus 26 anos de história, desenvolvedores o tratavam como uma biblioteca de conveniência para dados locais, não como um banco de dados de produção no servidor.

Isso mudou entre 2022 e 2026. Um conjunto de novas ferramentas resolveu a clássica limitação do SQLite no lado do servidor, e um número crescente de aplicações de produção silenciosamente abandonou Postgres, MySQL e Redis em favor de um único arquivo .db. Veja por que — e se isso faz sentido para o seu projeto.

O que SQLite realmente é (e não é)

SQLite não é um servidor de banco de dados. É uma biblioteca em C — cerca de 150 mil linhas de código C bem testado — que você linka diretamente na sua aplicação. O banco de dados inteiro vive em um único arquivo no disco. Não há socket de rede, camada de autenticação, pool de conexões, processo separado para iniciar ou monitorar. Sua aplicação lê e escreve o arquivo diretamente, no mesmo processo.

Richard Hipp criou o SQLite em 2000 para uso em contratorpedeiros da Marinha dos EUA, onde armazenamento de dados embarcado confiável importava mais do que concorrência multi-usuário. A troca de projeto foi intencional: simplicidade, confiabilidade e zero administração ao custo de escritas concorrentes. O formato do arquivo é estável desde 2004, e a documentação do SQLite de 2024 se compromete explicitamente a manter esse formato "para sempre" — uma garantia excepcionalmente forte em software.

A consequência mais importante do projeto in-process: latência de rede zero. Uma consulta que levaria 1-2ms de ida e volta para uma instância remota de Postgres leva microssegundos no SQLite. Para aplicações com muitas leituras na mesma máquina do banco de dados, a diferença de desempenho é real.

O renascimento no lado do servidor

A história do SQLite no servidor começa com uma limitação: escritas são serializadas. Apenas um escritor pode segurar o lock do banco por vez. No modo de journal padrão, leitores também bloqueiam escritores. Para uma aplicação web multi-usuário, isso parece fatal.

Quatro ferramentas mudaram o cálculo entre 2022 e 2023:

  • Cloudflare D1 (2022): A Cloudflare construiu um produto SQLite serverless sobre o Cloudflare Workers, distribuindo bancos SQLite para locais no edge globalmente. O D1 usa o modo WAL (Write-Ahead Logging) do SQLite e os Durable Objects da Cloudflare para consistência. Trouxe o SQLite para o edge com uma interface SQL familiar e precificação por leitura/escrita por linha.
  • Fly.io LiteFS (2022): LiteFS é um sistema de arquivos baseado em FUSE que intercepta escritas do SQLite e as replica para nós seguidores via um log de transações. Permite rodar um nó primário SQLite e múltiplas réplicas de leitura — um padrão antes impossível com SQLite puro. O Fly.io usa LiteFS internamente para sua própria infraestrutura.
  • Turso (2023): Turso bifurcou o SQLite no libSQL, um banco de dados compatível com SQLite e open source com replicação embutida, suporte a API HTTP e distribuição no edge. O plano gratuito do Turso inclui 500 bancos de dados, tornando arquiteturas multi-tenant com um SQLite por usuário essencialmente grátis para prototipar.
  • Bun com SQLite nativo (2023): O Bun lançou bun:sqlite, um driver SQLite nativo embutido diretamente no runtime JavaScript Bun. Benchmarks mostram que ele roda aproximadamente 3x mais rápido que better-sqlite3 para cargas de trabalho típicas, eliminando a necessidade de um pacote npm separado na maioria dos casos.

Cada uma dessas ferramentas resolve uma lacuna específica: D1 cuida da distribuição no edge, LiteFS cuida da replicação, Turso cuida de ambos mais uma API HTTP, e Bun cuida da ergonomia para desenvolvedores. Juntas, elas transformaram o SQLite de uma curiosidade local em uma opção crível no servidor.

O que há de novo no SQLite 3.45+

Enquanto as ferramentas do ecossistema amadureciam, o próprio SQLite trouxe melhorias significativas em lançamentos recentes:

  • SQLite 3.45 (janeiro de 2024): Introduziu jsonb — um formato binário de armazenamento JSON que mantém dados JSON em representação binária interna em vez de analisar texto a cada acesso. Benchmarks mostram operações jsonb rodando até 10x mais rápido que operações equivalentes com JSON texto para estruturas aninhadas complexas. O mesmo lançamento adicionou suporte a JSON5, permitindo sintaxe JSON relaxada (comentários, vírgulas finais, strings com aspas simples) em funções JSON.
  • SQLite 3.46 (maio de 2024): Adicionou mensagens de erro substancialmente melhoradas com mais contexto sobre o que deu errado e onde. O PRAGMA optimize foi aprimorado para rodar mais eficientemente em aplicações de longa duração — agora aceita uma bitmask para controlar quais otimizações aplicar, útil para aplicações que queiram rodá-lo em um cronograma em vez de no fechamento da conexão.
  • SQLite 3.47+ (final de 2024 — 2025): Entregou melhorias na estimativa de custo do planejador de consultas para joins complexos, reduzindo casos onde planos de consulta subótimos eram escolhidos para tabelas grandes. A família de funções UNIXEPOCH() foi estendida com novos modificadores para aritmética de data/hora mais flexível diretamente em SQL.

A adição do jsonb merece destaque. JSON se tornou um tipo de dado de primeira classe em aplicações modernas, e o armazenamento JSON baseado em texto do SQLite significava ciclos repetidos de análise/serialização. Mudar para colunas jsonb em um esquema com cargas pesadas de JSON é um ganho de desempenho de esforço quase zero — mude o tipo da coluna, reconstrua, pronto.

Modo WAL e concorrência — os números

A objeção mais comum ao SQLite no servidor é a concorrência. A resposta é o modo WAL, ativado com um único pragma: PRAGMA journal_mode=WAL;

No modo WAL, o banco mantém um arquivo de log write-ahead separado junto com o arquivo principal. Escritores anexam ao WAL; leitores leem do arquivo principal mais quaisquer entradas WAL confirmadas. O resultado: leitores nunca bloqueiam escritores, e escritores nunca bloqueiam leitores. Múltiplos leitores concorrentes operam em paralelo sem contenção de lock. Apenas escritas são serializadas entre si — e para a maioria das aplicações web, escritas são uma fração pequena do total de consultas.

Benchmarks medidos em um M2 MacBook com armazenamento NVMe:

  • SQLite modo WAL, leituras concorrentes: ~130.000 leituras/seg
  • SQLite modo WAL, escritas sequenciais: ~35.000 escritas/seg
  • Postgres no mesmo hardware (com overhead de conexão): ~40.000 leituras/seg

A taxa de leitura do SQLite em modo WAL é cerca de 3x maior que a do Postgres em hardware comparável — porque não há comunicação entre processos. O banco está no mesmo processo que a aplicação; cada consulta é uma chamada de função, não uma ida e volta na rede.

Escritas contam uma história mais matizada. SQLite serializa escritas, então uma aplicação com muitas escritas atingindo 35.000 escritas/seg saturará o escritor único. Postgres, com sua arquitetura multi-escritor, escala escritas horizontalmente. Se sua aplicação está fazendo 10.000+ escritas concorrentes por segundo de instâncias separadas, SQLite é a escolha errada. Se você está fazendo 500 escritas/seg com 50.000 leituras/seg, SQLite vence por larga margem.

Quando SQLite é a escolha certa

A decisão é uma questão de carga de trabalho, não de prestígio:

  • Cargas altas de leitura, baixas de escrita ✓ — Desempenho de leitura do SQLite é excepcional; escritas serializadas raramente são o gargalo
  • Implantações em região única ✓ — Um escritor primário, baixa latência, operações simples
  • Implantações no edge e embarcadas ✓ — Zero infraestrutura, roda onde quer que um processo rode
  • Conjuntos de dados pequenos a médios ✓ — SQLite suporta bancos de até 281 TB teoricamente; na prática, abaixo de 100 GB é o ponto ideal onde operações em nível de arquivo permanecem rápidas
  • Aplicações que precisam de zero infraestrutura ✓ — Nenhum servidor de banco para provisionar, atualizar ou monitorar
  • Escritas de alta concorrência de múltiplos processos ✗ — Escritas serializadas se tornam o gargalo; use Postgres ou MySQL
  • Escritas primárias multi-região ✗ — SQLite tem um escritor; ativo-ativo multi-região requer um banco de dados distribuído
  • Busca em texto completo em escala ✓/✗ — A extensão FTS5 é capaz para cargas moderadas; para milhões de documentos com ranqueamento complexo de relevância, busca dedicada é melhor

As ferramentas que tornam SQLite prático no servidor

Além do banco em si, o ecossistema preencheu as lacunas operacionais:

  • Turso: SQLite distribuído com fork libSQL, API HTTP e WebSocket, replicação para múltiplos locais no edge, réplicas embarcadas (SQLite local que sincroniza de um banco Turso remoto). Plano gratuito: 500 bancos, 1 bilhão de leituras de linha/mês.
  • LiteFS: Replicação SQLite baseada em FUSE do Fly.io. Intercepta operações do sistema de arquivos para capturar o log write-ahead do SQLite e transmiti-lo para réplicas. Nível de produção, usado internamente pelo Fly.io. Requer ambiente Linux com suporte a FUSE.
  • Litestream: Replicação de streaming em binário único do SQLite para S3, R2, GCS ou Azure Blob Storage. Roda como processo sidecar junto com sua aplicação, replicando cada frame WAL em tempo quase real. Tempo de restauração do S3: abaixo de 30 segundos para um banco de 10 GB. Custo quase zero — você paga apenas pelo armazenamento S3 e egress.
  • Cloudflare D1: SQLite serverless no edge dentro da plataforma Cloudflare Workers. Replicação de leitura transparente para ~300 locais no edge. Precificação: $0,001 por milhão de leituras de linha, $1,00 por milhão de escritas de linha, 5 GB de armazenamento no plano gratuito.
  • bun:sqlite do Bun: Embutido diretamente no runtime Bun, sem necessidade de npm install. Usa o SQLite do sistema ou envia o próprio. Consistentemente benchmarks ~3x mais rápido que better-sqlite3 para cargas de consulta síncronas, devido à integração mais estreita com V8/JSC e overhead FFI reduzido.

O caso do SaaS com 100 mil usuários no SQLite

O padrão arquitetural mais interessante a emergir do renascimento do SQLite é um banco de dados por usuário (ou por tenant). Em vez de um único banco compartilhado com colunas user_id por toda parte, cada usuário recebe seu próprio arquivo .db.

As vantagens são significativas: isolamento completo de dados, backup e restauração triviais por usuário, risco zero de vazamento de dados entre tenants via bugs SQL, e a capacidade de mover bancos de dados individuais entre servidores sem coordenação. Deletar os dados de um usuário é uma única chamada unlink().

Esse padrão tem sido usado silenciosamente em produção por anos. Casos documentados incluem aplicações SaaS com mais de 50.000 usuários ativos rodando inteiramente no SQLite com Litestream para backup — sem Postgres, sem Redis, sem equipe dedicada de infraestrutura de banco de dados. Toda a camada de banco cabe em um único diretório de arquivos .db, com backup contínuo para S3 por centavos ao mês.

O padrão escala bem até você precisar de consultas entre usuários — análises que agregam dados de todos os usuários, por exemplo. Nesse ponto, você mantém um banco de dados de análise separado ou aceita que SQLite por usuário não é o modelo certo para essa consulta.

Conclusão

SQLite nunca foi um brinquedo. Sempre foi uma troca diferente: simplicidade, confiabilidade e desempenho para cargas de um único escritor, ao custo de escritas concorrentes e acesso multi-processo. O ecossistema de 2022-2026 — Turso, Litestream, LiteFS, Cloudflare D1, Bun — não mudou as trocas do SQLite. Eles construíram as ferramentas operacionais que tornam essas trocas aceitáveis para aplicações de produção no servidor.

Para uma aplicação web com muitas leituras rodando em uma única região, SQLite em modo WAL superará o Postgres no mesmo hardware, custará menos para operar e exigirá zero administração de banco de dados. Para uma aplicação com muitas escritas e múltiplos escritores concorrentes entre regiões, Postgres continua sendo a ferramenta certa. O erro é tratar isso como uma questão de prestígio em vez de uma questão de carga de trabalho — SQLite rodou mais software, em mais dispositivos, mais confiavelmente do que qualquer outro banco de dados na história. Ele só não precisa de um servidor para fazer isso.

Compartilhar:
Diziam que SQLite era um banco de dados de brinquedo. Na verdade, ele roda metade da internet. | IRCNF - Intelligent Reliable Custom Next-gen Frameworks