Os sete produtos
Antes de decidir
Como nos comparamos
vs. Supabase
Postgres gerenciado, fatura em dólar
vs. Clerk
Login pronto, suporte em outro fuso
vs. Stripe
Cobrança global, assinatura como evento
Se o seu produto é global e cobra em dólar, as ferramentas de lá provavelmente são a escolha certa.
Banco de dados sem cerimônia
A coleção nasce no primeiro insert. Sem schema, sem migration, sem container. Você manda um JSON, a tabela se cria sozinha com os tipos certos — inclusive o campo de embedding, que já vira busca vetorial. E o que fica no disco é um arquivo SQLite que abre no seu computador.
A partir de R$ 29,99/mês. O que muda entre os planos é o número de instâncias — o resto está em todos.
O problema
Schema antes de saber o formato dos dados. Migration antes de ter dado. Container antes de ter usuário. Você queria salvar um registro e acabou decidindo versionamento de schema, política de IAM e estratégia de conexão — tudo antes da primeira linha entrar no banco.
O que isso custa hoje
O caminho inteiro
Delegue ao agente — ou faça à mão em cinco blocos.
Atalho · Delegar
Ou não escreva nada disso
Um arquivo de 5.156 bytes com a integração inteira — collections, busca vetorial, blobs e SQL. Cole a URL no Claude Code, no Cursor ou no Copilot e peça a integração: ele escreve os cinco blocos abaixo por você. O arquivo também lista o que não existe, para o agente não inventar API.
$ curl https://myinfrastructure.click/products/storage/llms.txt # RiLiGar Storage — Master # Implementation Guide (LLM-Ready) > Collections, vetores, blobs > e SQL: a integração inteira. ▊
1 · Instalar
Um pacote, zero dependências
O SDK são 4.371 bytes de ESM sem nenhuma dependência de runtime. Não há build step: o package.json aponta para o fonte.
$ bun add @riligar/storage-sdk installed @riligar/storage-sdk@1.2.1 2 packages [1362.00ms]
2 · Salvar
A coleção nasce aqui
A coleção "produtos" não existe antes desta chamada. A tabela se cria com os tipos inferidos deste objeto: número vira REAL, array de números vira F32_BLOB, o resto vira TEXT.
import Storage from
'@riligar/storage-sdk'
const storage = new Storage(
BASE_URL,
process.env.STORAGE_KEY,
)
await storage
.collection('produtos')
.insert({
nome: 'Teclado Mecânico',
preco: 350.5,
tags: ['perifericos'],
})3 · Ler
Filtro, sem SQL
Operadores: $eq, $neq, $gt, $gte, $lt, $lte e $like. Repare que $like envolve o valor em % automaticamente — não dá para ancorar prefixo. E não existe OR: condições são sempre combinadas com AND.
const { data } = await storage
.collection('produtos')
.select({
where: {
nome: { $like: 'Teclado' },
},
limit: 10,
})4 · Buscar por significado
O mesmo insert já indexou o vetor
Array de números vira F32_BLOB e ganha um índice vetorial na hora — você não cria índice, não sobe Pinecone, não paga um segundo banco. A consulta é kNN pelo vector_top_k do libSQL, no mesmo select() do filtro comum, e topK vai até 100. Guarde o embedding ao lado do texto que ele representa: é a mesma linha, no mesmo arquivo.
// o embedding entra como campo comum
await storage.collection('memorias')
.insert({
texto: 'prefere modo escuro',
embedding: [0.1, 0.2, 0.3],
})
// e volta por similaridade
const { data } = await storage
.collection('memorias')
.select({
vectorIndex: 'embedding',
vector: await embed('tema do app'),
vectorTopK: 3,
})5 · Conferir
A saída, colada do terminal
Não é exemplo plausível — é o que apareceu aqui, colado do terminal. O tags voltou como array, o preco como número, e o id e o created_at você não escreveu.
$ curl .../produtos -H "x-api-key: sk_..."
{
"data": [
{
"id": "0293cef6-1831...",
"created_at": "2026-08-18 15:12:23",
"nome": "Teclado Mecânico",
"preco": 350.5,
"tags": ["perifericos"]
}
],
"meta": {
"total": 1,
"page": 1,
"last_page": 1,
"limit": 50
}
}
[200 em 0.256434s]Model Context Protocol
O Storage já era memória de agente antes de existir MCP: schema-less, busca vetorial nativa, um arquivo por instância. Faltava o agente usar isso sem alguém escrever a integração. São 10 ferramentas — 7 leem, 3 escrevem — na revisão 2026-07-28, a stateless.
O que o servidor NÃO oferece
Autentica das duas formas com a sua sk_ ou com OAuth 2.1 pelo RiLiGar Auth. As duas chegam na mesma instância.
Como o agente entra
O token nasce no navegador e vale só na instância que você aprovou.
OAuth 2.1
Você aprova no navegador, uma vez
Sem header nenhum no comando. Na primeira chamada o servidor responde 401 apontando para o metadata; o cliente descobre o authorization server sozinho, abre o navegador e você aprova. O token vale só naquela instância — o id no endereço vira a audiência dele — e o escopo decide se escreve ou só lê. Em CI, onde não há navegador, a sua sk_ conecta direto.
$ claude mcp add --transport http \
riligar-storage \
https://storage.manager.myinfrastructure.click/mcp/<id-da-instância>
→ 401 WWW-Authenticate
→ descobre o auth server
→ abre o navegador
✓ token com aud= esta instância ▊O que muda na prática
Ninguém escreveu esse filtro
O agente não adivinha nomes de coleção nem de campo: ele consulta o schema antes, porque o storage é schema-less e não há como chutar. As três chamadas abaixo saíram de uma frase.
Você: "quantos produtos acima de 300?"
→ list_collections
{ "produtos": 1, "docs": 1 }
→ describe_collection("produtos")
colunas: nome, preco (REAL), tags
→ query_collection
{ where: { preco: { $gt: 300 } } }
1 documento. Teclado Mecânico,
R$ 350,50.Portabilidade
Cada tenant tem um arquivo próprio, não uma linha com tenant_id numa tabela compartilhada. E esse arquivo abre na ferramenta que já vem no seu sistema — sem conversor, sem dump proprietário, sem nós no meio.
Sem prisão
Não é um argumento — é um arquivo. Rode o comando com a sua chave e o banco desce inteiro, no formato que qualquer ferramenta SQLite abre. Sem ticket, sem exportador proprietário, sem esperar aprovação.
O que acontece quando você roda
A ressalva que continua valendo se você usa busca vetorial, o arquivo carrega um índice libsql_vector_idx, que é extensão do libSQL. Os dados continuam legíveis e o .dump recupera tudo, mas PRAGMA integrity_check falha no sqlite3 padrão e o índice precisa ser recriado do outro lado. Quem não usa vetores tem um arquivo 100% padrão.
Sendo justo
Postgres / Supabase
Onde eles são a resposta certa
Dado relacional, JOIN e integridade referencial
Postgres
Escrita concorrente alta (MVCC)
Postgres
Realtime, Auth e Edge Functions integrados
Supabase
Ecossistema, extensões e gente que já sabe operar
30 anos
Backup com restauração testada
Eles têm
Use eles se
Seu dado é relacional
O Supabase é excelente — para os problemas de lá.
RiLiGar Storage
Guardar dados sem tomar decisão de infraestrutura antes de saber o formato deles — e que o que fique no disco seja um arquivo aberto.
A régua
A mesma tabela em toda página de produto da RiLiGar. Cada linha traz o número que medimos, a data e o método — não uma promessa.
Sair e levar tudo
Um comando
Um curl devolve o banco inteiro. Sem ticket, sem espera, sem falar com vendedor — o mesmo caminho no primeiro e no último dia.
Formato do export
SQLite 3 padrão
Abre em sqlite3, DBeaver, Python — sem conversor. Ressalva: com busca vetorial vem um índice libsql_vector_idx não padrão; os dados seguem legíveis, o índice precisa ser recriado.
Tempo até o primeiro dado salvo
1,9 s
Do bun add até o dado voltar: 1,36 s no pacote, 0,248 s no insert, 0,256 s na leitura. O relógio começa depois do cadastro, que é onde você pega a API key.
Custo em R$
R$ 29,99 a R$ 99,99/mês
Starter, Pro e Scale — o que muda é o número de instâncias (1, 5 ou ilimitadas), e esse é o único limite verificado no servidor. Não há cota de tamanho, de coleções nem de documentos. Os valores desta linha vêm do mesmo catálogo que a seção de preço lê ao vivo.
Latência de leitura para usuário em São Paulo
0,15 ms no banco
A requisição completa de São Paulo leva 232 ms (mediana de 15 amostras, 18/08/2026, curl). Desses, 0,15 ms é o banco e o resto é a viagem até iad (EUA) — o número vem do próprio servidor, no campo meta.duration.
Se algum destes números não bater no seu caso, escreva. A gente mede de novo e corrige a linha.
Preço
Sem “fale com vendas”: você escolhe o plano na tela acima e começa. Se travar em algum passo, é bug de documentação e a gente conserta.
FAQ
Achou um limite que não está escrito aqui?
Fala direto com quem escreveu o código. Se você encontrou onde quebra, a gente quer publicar isso na página antes do próximo visitante descobrir sozinho.
