TL;DR: O Supabase consolida banco PostgreSQL, autenticação, storage e busca vetorial em uma única plataforma — gratuita até 50k usuários ativos mensais. Para um solo builder, isso elimina o custo de integrar quatro serviços separados antes de escrever uma linha de produto.
Se você está construindo um produto solo e fica travado na parte de infraestrutura — banco de dados, autenticação, uploads, permissões por usuário — o Supabase resolve tudo isso de uma vez. Neste guia você vai ver como configurar o stack completo, integrar com APIs de IA usando pgvector, e um walkthrough completo de um produto RAG do upload ao LLM.
Por que o Supabase mudou o jogo para builders solo
Antes do Supabase, lançar um produto solo com backend significava: configurar servidor, banco de dados, autenticação, storage, rate limiting, migrations, SSL. Horas gastas antes de escrever uma linha de código útil para o produto em si.
O Supabase condensa tudo isso em uma plataforma com:
- PostgreSQL gerenciado — banco de dados completo, não uma versão simplificada
- Auth integrado — email/senha, magic link, OAuth (Google, GitHub, Apple)
- Storage — upload de arquivos com permissões por bucket e por usuário
- Edge Functions — código serverless em TypeScript/Deno rodando na borda
- Realtime — subscriptions via websocket para dados ao vivo
- pgvector — busca vetorial nativa para RAG e produtos com IA
O free tier: 500MB de banco, 1GB de storage, 50k usuários ativos mensais e 500k invocações de edge functions por mês. Para um MVP ou micro-SaaS com tráfego inicial, você não paga nada.
O que você consegue construir
Com o Supabase como base, um solo builder pode lançar:
- SaaS com autenticação completa — usuário se registra, faz login, acessa apenas seus próprios dados
- Produto com RAG — chatbot, assistente, busca semântica em documentos do cliente
- API de dados — Supabase gera APIs REST e GraphQL automaticamente a partir das tabelas
- Aplicativo com uploads — PDFs, imagens, áudio diretamente no storage com URL assinada
- Produto realtime — notificações, feeds, dashboards ao vivo sem polling
Exemplos concretos que um solo builder pode monetizar hoje:
- Ferramenta de análise de contratos — upload de PDF, agente de IA analisa e responde perguntas específicas do documento
- Chatbot treinado em base de conhecimento própria — RAG com pgvector, sem pagar Pinecone
- SaaS de gestão para nicho — CRM simplificado para fisioterapeutas, advogados, clínicas pequenas
- API de dados enriquecidos — scraping + processamento por IA + banco → vender como assinatura mensal
Supabase + IA: usando pgvector para RAG
O pgvector é a extensão do PostgreSQL que permite armazenar e consultar embeddings diretamente no banco. Isso significa que você não precisa de um banco de dados vetorial separado (Pinecone, Weaviate, Qdrant) para construir um produto RAG. O seu banco de dados já faz isso.
1. Ativando o pgvector
No Supabase Dashboard, vá em Database > Extensions e ative vector.
Depois crie a tabela para os chunks de documento:
create extension if not exists vector;
create table documents (
id bigint primary key generated always as identity,
user_id uuid references auth.users not null,
content text not null,
embedding vector(1536),
metadata jsonb,
created_at timestamptz default now()
);
-- Índice para busca por similaridade (cosine)
-- lists = sqrt(número de documentos) é uma boa heurística inicial
-- Para até 10k docs: lists = 100. Para 100k docs: lists = 300
create index on documents using ivfflat (embedding vector_cosine_ops)
with (lists = 100);
2. Inserindo embeddings
import { createClient } from '@supabase/supabase-js'
import OpenAI from 'openai'
const supabase = createClient(
process.env.SUPABASE_URL!,
process.env.SUPABASE_ANON_KEY!
)
const openai = new OpenAI()
async function insertChunk(content: string, metadata: object) {
const { data } = await openai.embeddings.create({
model: 'text-embedding-3-small',
input: content,
})
await supabase.from('documents').insert({
content,
embedding: data[0].embedding,
metadata,
})
}
3. Buscando por similaridade
Crie a função SQL no Supabase:
create or replace function match_documents(
query_embedding vector(1536),
match_threshold float,
match_count int,
p_user_id uuid default null -- filtra por usuário quando informado
)
returns table(id bigint, content text, similarity float)
language sql stable
as $$
select id, content,
1 - (embedding <=> query_embedding) as similarity
from documents
where 1 - (embedding <=> query_embedding) > match_threshold
and (p_user_id is null or user_id = p_user_id)
order by similarity desc
limit match_count;
$$;
E chame do TypeScript:
async function search(query: string, limit = 5) {
const { data } = await openai.embeddings.create({
model: 'text-embedding-3-small',
input: query,
})
const { data: results } = await supabase.rpc('match_documents', {
query_embedding: data[0].embedding,
match_threshold: 0.78,
match_count: limit,
})
return results
}
Autenticação em 5 minutos
Um dos maiores ganhos de tempo com Supabase é a autenticação. Em 5 minutos você tem login com email/senha, Google, GitHub, magic link — com tokens JWT gerenciados automaticamente.
// Registrar
const { data, error } = await supabase.auth.signUp({
email: 'usuario@email.com',
password: 'senha-segura'
})
// Login
const { data, error } = await supabase.auth.signInWithPassword({
email: 'usuario@email.com',
password: 'senha-segura'
})
// OAuth em uma linha
await supabase.auth.signInWithOAuth({ provider: 'google' })
// Sessão atual
const { data: { user } } = await supabase.auth.getUser()
Row Level Security: permissões por usuário no banco
Para garantir que cada usuário acesse apenas seus próprios dados, use Row Level Security (RLS). Isso acontece no banco — não no código da aplicação:
-- Ativar RLS na tabela
alter table documents enable row level security;
-- Usuário vê apenas seus documentos
create policy "select_own"
on documents for select
using (auth.uid() = user_id);
-- Usuário insere apenas nos seus registros
create policy "insert_own"
on documents for insert
with check (auth.uid() = user_id);
Com RLS ativo, você não precisa filtrar por user_id no código. O banco faz isso automaticamente baseado na sessão JWT do usuário logado. Isso elimina toda uma classe de bugs de segurança em produtos multi-tenant.
Edge Functions: lógica server-side sem servidor
Edge Functions são funções serverless em TypeScript/Deno que rodam distribuídas globalmente. São ideais para:
- Webhooks de pagamento (Stripe, Paddle)
- Processamento de arquivo após upload
- APIs intermediárias entre frontend e APIs externas
- Tarefas agendadas (cron)
Exemplo: processar um PDF após upload e gerar os embeddings automaticamente:
// supabase/functions/process-pdf/index.ts
import { serve } from 'https://deno.land/std@0.168.0/http/server.ts'
import { createClient } from 'https://esm.sh/@supabase/supabase-js@2'
serve(async (req) => {
const { file_path, user_id } = await req.json()
const supabase = createClient(
Deno.env.get('SUPABASE_URL')!,
Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')!
)
// Download do storage
const { data: fileData } = await supabase.storage
.from('uploads')
.download(file_path)
// Extrair texto do PDF — use pdf-parse (npm install pdf-parse)
// import pdfParse from 'pdf-parse'
// const parsed = await pdfParse(Buffer.from(await fileData.arrayBuffer()))
// const text = parsed.text
const text = await extractText(fileData) // substitua pela implementação com pdf-parse
// Dividir em chunks de ~500 tokens (aprox. 2000 caracteres)
const chunks = splitIntoChunks(text, 2000)
for (const chunk of chunks) {
await insertChunk(chunk, { user_id, file_path })
}
return new Response(JSON.stringify({ status: 'ok', chunks: chunks.length }))
})
Deploy:
supabase functions deploy process-pdf
Juntando tudo: walkthrough completo do upload ao LLM
Até aqui você viu cada peça separada. Este é o fluxo completo de um produto RAG real — do upload do documento à resposta do LLM — com todas as peças conectadas.
Usuário faz upload do PDF
→ supabase.storage.upload()
→ Storage webhook dispara Edge Function "process-pdf"
→ Edge Function: baixa o arquivo, extrai texto, divide em chunks
→ Para cada chunk: gera embedding via OpenAI
→ Insere chunk + embedding na tabela documents
Usuário faz uma pergunta
→ Frontend chama Edge Function "ask"
→ Edge Function: gera embedding da pergunta
→ Chama match_documents() — retorna top 5 chunks mais similares
→ Monta prompt: instrução de sistema + chunks como contexto + pergunta
→ Chama OpenAI chat completion
→ Retorna resposta ao frontend
Edge Function “ask” completa
// supabase/functions/ask/index.ts
import { serve } from 'https://deno.land/std@0.168.0/http/server.ts'
import { createClient } from 'https://esm.sh/@supabase/supabase-js@2'
import OpenAI from 'https://esm.sh/openai@4'
serve(async (req) => {
const { question, user_id } = await req.json()
const supabase = createClient(
Deno.env.get('SUPABASE_URL')!,
Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')!
)
const openai = new OpenAI({ apiKey: Deno.env.get('OPENAI_API_KEY') })
// 1. Gerar embedding da pergunta
const { data: embedData } = await openai.embeddings.create({
model: 'text-embedding-3-small',
input: question,
})
// 2. Buscar chunks do usuário específico (evita vazar dados entre usuários)
const { data: chunks } = await supabase.rpc('match_documents', {
query_embedding: embedData[0].embedding,
match_threshold: 0.75,
match_count: 5,
p_user_id: user_id,
})
if (!chunks || chunks.length === 0) {
return new Response(JSON.stringify({
answer: 'Não encontrei informações relevantes nos documentos.'
}))
}
// 3. Montar contexto a partir dos chunks
const context = chunks.map((c: { content: string }) => c.content).join('\n\n')
// 4. Chamar o LLM com o contexto
const completion = await openai.chat.completions.create({
model: 'gpt-4o-mini',
messages: [
{
role: 'system',
content: `Você é um assistente que responde perguntas com base nos documentos fornecidos.
Use apenas as informações abaixo. Se a resposta não estiver nos documentos, diga isso claramente.
DOCUMENTOS:
${context}`
},
{ role: 'user', content: question }
],
})
const answer = completion.choices[0].message.content
return new Response(JSON.stringify({ answer }), {
headers: { 'Content-Type': 'application/json' }
})
})
Chamando do frontend (Next.js)
// app/api/ask/route.ts
export async function POST(req: Request) {
const { question } = await req.json()
const { data: { user } } = await supabase.auth.getUser()
const { data, error } = await supabase.functions.invoke('ask', {
body: { question, user_id: user?.id }
})
return Response.json(data)
}
Com essas três Edge Functions (process-pdf, ask, e o webhook de storage) você tem o núcleo de um produto RAG completo. O frontend só precisa de dois elementos: um botão de upload e um campo de pergunta.
Quanto custa na prática
A comparação honesta é montar o mesmo stack com serviços separados:
| Serviço | Função | Custo/mês |
|---|---|---|
| AWS RDS t3.micro | PostgreSQL | ~R$80 |
| Pinecone Starter | Banco vetorial | ~R$350 |
| Auth0 Essentials | Autenticação | ~R$120 |
| AWS S3 | Storage | ~R$15 |
| Total separado | ~R$565/mês |
Com Supabase free tier: R$0 — até você crescer. Com Supabase Pro: R$130/mês — quando precisar de produção séria com backups e sem pausa por inatividade.
A diferença não é só financeira. É o tempo de integração: cada serviço separado tem seu próprio SDK, sua autenticação, seus erros específicos, seu plano de billing. O Supabase elimina esse custo operacional de integrar e manter quatro plataformas diferentes.
Para deploy, complete o stack com ferramentas gratuitas:
| Camada | Ferramenta | Custo inicial |
|---|---|---|
| Frontend | Next.js / Astro | Gratuito |
| Deploy | Vercel / Cloudflare Pages | Gratuito |
| LLM | OpenAI / Claude API | Pay-as-you-go |
| Pagamentos | Stripe | 2.9% + R$0,30 por transação |
| Email transacional | Resend | 100 emails/dia grátis |
Limites do free tier: o que você precisa saber
O free tier é generoso, mas tem comportamentos que podem pegar desprevenido:
1. Projetos inativos são pausados em 7 dias. Se não há requisições por 7 dias, o projeto hiberna. A primeira requisição depois acorda com latência de ~5 segundos. Para um produto em produção com usuários reais, isso não acontece. Para um MVP sem tráfego ainda, configure um ping periódico via cron ou migre para Pro quando lançar.
2. Edge Functions têm cold start. Funções sem chamadas recentes levam 1–3 segundos na primeira invocação. Para webhooks de pagamento (Stripe), isso pode causar timeout. Solução: mantenha warm com chamadas periódicas ou use a opção de instâncias dedicadas disponível no Pro.
3. Limite de 60 conexões simultâneas. Para um MVP, é mais do que suficiente. Para um produto com picos de tráfego, monitore esse número. O plano Pro vai para 200+ conexões.
4. Backups automáticos só no Pro.
No free tier não há point-in-time recovery. Faça dumps manuais regularmente (pg_dump) se os dados são críticos.
O plano Pro ($25/mês ≈ R$130/mês) remove todos esses limites. Faz sentido migrar quando você tem usuários pagantes — não antes.
Monetização: modelos reais para esse stack
Modelo 1 — SaaS por assinatura
Produto com login + dashboard + funcionalidade com IA. Exemplos:
- Análise de documentos para um nicho (contratos, laudos médicos, propostas comerciais)
- Assistente treinado nos dados internos do cliente (RAG)
- Dashboard de dados enriquecidos por IA
Preço típico: R$99–499/mês por usuário. Com 30 clientes ativos a R$149/mês = R$4.470/mês recorrentes.
Modelo 2 — API como produto
Você constrói o pipeline de dados (coleta + processamento + banco) e vende acesso via API. O Supabase serve como backend e banco da API.
Preço: por requisição ou por volume de dados processados.
Modelo 3 — Produto B2B para nicho
Versão especializada para um setor vertical (imobiliário, saúde, jurídico, contabilidade). Produto mais simples, ticket mais alto, muito menos competição do que soluções genéricas.
Preço: R$499–3.000/mês por empresa.
Modelo 4 — Starter kit / template
Se você construiu um produto funcional com Supabase, pode vender o template para outros builders que querem o mesmo ponto de partida.
Preço: R$199–599 (venda única, zero suporte marginal).
Como começar hoje (30 minutos)
- Crie conta em supabase.com — gratuito, sem cartão
- Crie um novo projeto e anote as credenciais em Settings > API
- Ative a extensão
vectorem Database > Extensions - Instale o SDK:
npm install @supabase/supabase-js - Configure as variáveis de ambiente:
SUPABASE_URLeSUPABASE_ANON_KEY - Crie sua primeira tabela, ative RLS, escreva sua primeira policy
Em 30 minutos você tem banco de dados, autenticação e storage funcionando. O Supabase não é a ferramenta mais avançada para cada componente isolado — mas para um solo builder que precisa de velocidade sem gerenciar cinco serviços diferentes, ele é imbatível em custo-benefício até você ter receita para justificar especializar.
FAQ
O free tier do Supabase é realmente gratuito para sempre? O plano gratuito não tem prazo de expiração, mas projetos sem atividade por mais de 7 dias são pausados automaticamente. Para produção com tráfego constante, o plano Pro ($25/mês) remove essa limitação e adiciona backups automáticos.
Posso usar Supabase sem TypeScript/JavaScript? Sim. Existem SDKs oficiais para Python, Flutter, Swift, Kotlin e C#. Além disso, o Supabase expõe uma API REST e GraphQL que funcionam com qualquer linguagem ou ferramenta.
Supabase vs Firebase: qual escolher? Firebase é mais simples para começar mas usa um banco NoSQL limitado para consultas complexas. Supabase usa PostgreSQL real — joins, views, funções, triggers, pgvector. Para produtos com dados relacionais ou busca semântica, Supabase ganha.
O pgvector aguenta escala de produção? Para a maioria dos casos de uso de solo builders, sim. Até alguns milhões de vetores com latência adequada. Acima disso ou com requisitos de latência muito baixos, você considera soluções dedicadas. Mas para lançar e validar um produto? pgvector é mais que suficiente.
Posso migrar para outro banco depois se crescer? Sim. O Supabase usa PostgreSQL padrão. Você pode fazer dump completo e importar em qualquer serviço PostgreSQL (AWS RDS, Neon, Google Cloud SQL). Sem lock-in de formato proprietário.
Row Level Security não vai tornar minhas queries mais lentas? O RLS adiciona overhead mínimo — geralmente imperceptível para produtos com o volume de um solo builder. O ganho de segurança e a eliminação de bugs de isolamento de dados compensam amplamente.
