Um banco de dados que vive na RAM
O SQLite tem um nome de arquivo especial: :memory:. Ao abrir um banco com esse nome, o SQLite ignora completamente o disco — todo o banco fica na RAM. Tabelas, índices, transações, chaves estrangeiras, tudo funciona exatamente igual. A única diferença é que, quando a conexão é fechada, o banco some.
Pela linha de comando:
sqlite3 :memory:
Pronto, agora você está no prompt do SQLite com um banco em memória zerado, totalmente vazio. Daqui pra frente é tudo igual: cria uma tabela, insere algumas linhas, faz consultas — exatamente como você já faz no dia a dia:
Encerre a sessão e esses dados evaporam. Não sobra arquivo nenhum, porque nenhum arquivo chegou a ser criado.
Quando faz sentido usar
Um banco que não sobrevive a um restart parece bug, não feature. Mas existem três cenários em que isso é exatamente o que você quer.
Testes. Cada teste recebe um banco limpinho em milissegundos. Sem precisar limpar arquivos temporários, sem estado residual da execução anterior, sem aquele fixture compartilhado travando. A maioria das suítes de teste em Python, Node e Go que usam SQLite abre :memory: justamente por isso.
Análise descartável. Carregue um CSV, rode algumas queries, descarte. É mais rápido do que subir um banco de verdade e mais prático do que ficar parseando o arquivo no código toda vez.
Cache e área de rascunho. Dentro de um programa que roda por muito tempo, um banco SQLite em memória vira uma engine de consulta ad-hoc surpreendentemente boa para dados que você já carregou.
O ponto em comum: você quer SQL, mas não quer persistência.
Performance: mais rápido, mas não é mágica
O modo in-memory do SQLite pula o disco, então escritas que normalmente iriam para o sistema de arquivos viram só atualizações de memória. Cargas de trabalho limitadas por I/O ficam visivelmente mais rápidas. Já as limitadas por CPU — planejamento complexo de queries, ordenações grandes — praticamente não mudam, porque o SQLite já mantinha as páginas quentes em memória de qualquer jeito.
Veja como a sintaxe é idêntica à de um banco em arquivo:
Esse exemplo rodou em um banco de dados em memória, mas é exatamente o mesmo SQL que você usaria em um banco em arquivo. O motor do banco não faz distinção.
SQLite in memory vs arquivo: quando usar cada um
O trade-off é simples, e vale deixar claro:
- Banco em arquivo (
mydata.db): Persiste entre reinicializações. Vários processos podem abrir o mesmo arquivo. Sobrevive a quedas (com modo WAL, na maior parte dos casos). Use sempre que precisar guardar informação de verdade. - Banco em memória (
:memory:): Some quando a conexão é fechada. Por padrão, fica restrito à conexão que o abriu. Mais rápido para cargas de escrita descartáveis. Ideal para testes, rascunhos e caches de curta duração.
Na dúvida, vá de arquivo. O banco em memória é o caso especial.
Cada conexão cria seu próprio banco
Tem um detalhe sutil que pega muita gente: abrir :memory: duas vezes resulta em dois bancos completamente separados. Eles não compartilham tabelas, não compartilham dados e nem enxergam um ao outro.
-- Terminal 1
sqlite3 :memory:
sqlite> CREATE TABLE t (x); INSERT INTO t VALUES (1);
-- Terminal 2
sqlite3 :memory:
sqlite> SELECT * FROM t;
Error: no such table: t
Não é um bug — é assim que foi projetado. :memory: quer dizer "um banco privado para esta conexão". O mesmo vale dentro de um único programa: se o seu código abre duas conexões para :memory:, cada uma terá seu próprio banco isolado.
Compartilhando um banco SQLite em memória entre conexões
Se você precisa que várias conexões enxerguem o mesmo banco SQLite em memória, dá para fazer isso usando nomes de arquivo no formato URI junto com o cache compartilhado. A string mágica é file::memory:?cache=shared:
sqlite3 'file::memory:?cache=shared'
Qualquer conexão no mesmo processo que abrir essa URI exata se conecta ao mesmo banco. Quando todas forem fechadas, o banco desaparece.
Você também pode dar um nome ao banco de dados em memória, o que é útil quando precisa de vários bancos compartilhados distintos:
sqlite3 'file:mydb?mode=memory&cache=shared'
O nome mydb aqui é só um rótulo — continua não existindo arquivo nenhum. Duas conexões que abrem file:mydb?mode=memory&cache=shared compartilham o mesmo banco; já uma conexão que abre file:other?mode=memory&cache=shared cai em outro banco diferente.
Como salvar um banco SQLite em memória no disco
Às vezes você faz todo o trabalho em memória e, no fim, decide que quer guardar o resultado. A CLI tem um dot-command .backup justamente para isso:
sqlite3 :memory:
sqlite> CREATE TABLE results (id INTEGER, score REAL);
sqlite> INSERT INTO results VALUES (1, 0.91), (2, 0.87);
sqlite> .backup snapshot.db
sqlite> .quit
snapshot.db agora é um banco em arquivo comum, com exatamente o mesmo conteúdo. Dá pra abrir depois com sqlite3 snapshot.db e continuar de onde parou.
O caminho inverso também funciona — o .restore carrega um banco em arquivo para a memória da conexão atual:
sqlite3 :memory:
sqlite> .restore snapshot.db
sqlite> SELECT * FROM results;
No código da aplicação, a API C do SQLite expõe o mesmo mecanismo via sqlite3_backup_init, e a maioria dos bindings de linguagens faz um wrapper em cima disso. O módulo sqlite3 do Python, por exemplo, traz o método Connection.backup().
Uma armadilha comum
Vez ou outra, o pessoal tenta "salvar" um banco SQLite em memória anexando um arquivo e copiando os dados na mão:
Isso funciona para cópias simples de tabela, mas não preserva índices, triggers, views ou foreign keys exatamente como estavam. Para uma cópia fiel do banco inteiro, use .backup (ou a backup API) — ela faz uma cópia binária precisa no nível das páginas.
O que fica de bagagem
:memory:é um nome de arquivo especial do SQLite que cria um banco de dados em RAM, sem nenhum arquivo por trás.- O SQL é idêntico ao de um banco em arquivo — mesmas tabelas, mesmas queries, mesmas constraints.
- Cada conexão com
:memory:é privada; use URIs de cache compartilhado (file::memory:?cache=shared) quando várias conexões precisarem compartilhar o mesmo banco. - É a ferramenta certa para testes, análises descartáveis e caches de vida curta — não para nada que precise sobreviver a um restart.
- Quando decidir que vale a pena guardar, promova o banco em memória para o disco com
.backup.
A seguir: criando tabelas
Você já viu o CREATE TABLE aparecer rapidinho em alguns exemplos. A próxima página dá uma freada e mostra ele direito — definições de colunas, tipos, as constraints que dá pra encaixar e as pequenas decisões que tornam um schema agradável de conviver no dia a dia.
Perguntas frequentes
Como criar um banco de dados SQLite em memória?
Em vez de passar o caminho de um arquivo, abra o SQLite com o nome especial :memory:. No CLI fica sqlite3 :memory:; em qualquer biblioteca, é só usar :memory: como nome do arquivo na chamada de conexão. O banco vive na RAM e some assim que você fecha a conexão.
O que é :memory: no SQLite?
:memory: é um nome de arquivo "mágico" que o SQLite reconhece como: "esquece o disco, deixa tudo na RAM". Você tem um banco SQLite completo — tabelas, índices, transações, tudo igual —, só que nada é gravado em disco. E mais: cada conexão que abre :memory: ganha o seu próprio banco, isolado dos outros.
Duas conexões podem compartilhar o mesmo banco em memória?
Por padrão não — cada :memory: é isolado da sua conexão. Para compartilhar, abra usando uma URI tipo file::memory:?cache=shared com o cache compartilhado habilitado. Aí, todas as conexões que abrirem essa mesma URI dentro do processo enxergam o mesmo banco.
Dá para salvar um banco SQLite em memória no disco?
Dá sim. No CLI, use o comando .backup para copiar o banco em memória para um arquivo; nas bibliotecas, existe a API de backup que faz a mesma coisa. Outra opção é usar ATTACH para anexar um banco em arquivo e rodar algo como INSERT INTO arquivo.tabela SELECT * FROM main.tabela para mover os dados.