Dejad de Llamar a Supabase "Firebase para Postgres". Es al Revés: un Motor de 35 Años que Absorbió Todo el Feature Set de Firebase
Cada vez que escucho "Supabase es el Firebase de Postgres", muero un poco.
Es la comparación al revés. La dirección real es la inversa: MySQL reinó en la web de los 2000, y luego Firebase convenció a una generación de que los documentos NoSQL eran el futuro. Pero PostgreSQL —ese motor "aburrido" de 35 años— ha absorbido en silencio todo lo que Firebase hacía especial: auth, realtime, storage, incluso búsqueda vectorial para IA.
Y la prueba no está en el marketing de Supabase.
Está en que si quitas PostgreSQL de debajo de cualquier feature "estrella" de Supabase, no queda nada. Quitas Postgres y no hay auth. No hay realtime. No hay vector search. El ceño fruncido de la comparación se apoya entero en una columna vertebral que es SQL puro y portable.
*El riesgo que cargas con Supabase no es el lock-in. Es lo contrario: que todo tu miedo va dirigido en la dirección equivocada. *
Empecemos por lo que la mayoría entiende mal.
El Argumento Convencional es una Falsa Dicotomía
El debate típico en 2026 se plantea así:
❌ "¿Quieres velocidad para el MVP? Usa Firebase o Supabase. ¿Quieres un backend serio para producción? Monta algo propio."
❌ "Supabase vale para hackathons. Nadie ejecuta producción sobre ella."
Ambos bandos fallan igual. Los dos tratan Supabase como un atajo del que te gradúas. Los dos ignoran que la premisa es exactamente la inversa.
✅ Supabase no es la opción fácil de la que te vas. Es el argumento de que PostgreSQL es el sitio de mayor apalancamiento para poner auth, realtime y lógica de IA.
Vamos a desmontarlo con evidencia, no con opiniones.
La Arquitectura Revela Dónde Está el Valor Real
Mira qué pasa bajo el capó cuando usas Supabase:
- Auth (GoTrue) emite JWTs. Pero la autorización no vive en un middleware. Vive en políticas de Row-Level Security escritas en SQL directamente en la base de datos.
- Realtime no es un websocket con un event-bus casero por encima. Se construye sobre logical replication de Postgres. Un mensaje de chat es literalmente una fila commiteada.
- AI/vector search no requiere una base de datos vectorial aparte. Es una extensión (pgvector) y una columna con una query de similitud coseno escrita en SQL plano.
- Storage, Edge Functions (Deno), PostgREST... todos son wrappers finos alrededor de Postgres y un stack open source bajo licencia Apache 2.0.
Cada feature de Supabase que te parece "magia" es una primitiva de Postgres con gabardina.
Eso tiene consecuencias que casi nadie comenta.
La Seguridad la Decide la Base de Datos, No tu API
Vengo de años escribiendo middlewares en Node/Express. Mi primer impulso fue proteger la base de datos desde la API. Supabase te obliga a un reset mental: no estás protegiendo la base de datos de la API. La base de datos se protege a sí misma.
Mira una política de RLS típica:
-- Trigger que crea el perfil al registrarse
CREATE OR REPLACE FUNCTION public.handle_new_user()
RETURNS TRIGGER AS $$
BEGIN
INSERT INTO public.profiles (id, username)
VALUES (new.id, split_part(new.email, '@', 1));
RETURN new;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;
CREATE TRIGGER on_auth_user_created
AFTER INSERT ON auth.users
FOR EACH ROW EXECUTE FUNCTION public.handle_new_user();
// Suscripción a cambios reales de la base, no a un mensajero artificial
const channel = supabase
.channel('todos-changes')
.on('postgres_changes', {
event: 'INSERT',
schema: 'public',
table: 'todos'
}, (payload) => {
console.log('Fila commiteada:', payload.new);
})
.subscribe();
// supabase-js: operación CRUD
const { data, error } = await supabase
.from('todos')
.insert({ task: 'Aprender RLS', user_id: userId })
.select();
// Lo que ocurre por debajo: una petición REST a PostgREST
// POST /rest/v1/todos
// Body: { "task": "Aprender RLS", "user_id": "..." }
// Headers: { "Content-Type": "application/json", "Authorization": "Bearer <JWT>" }
-- Activas la extensión y creas la columna de embeddings
CREATE EXTENSION IF NOT EXISTS vector;
ALTER TABLE documents ADD COLUMN embedding vector(1536);
-- Búsqueda híbrida: los documentos más cercanos de este usuario, en este workspace
SELECT d.id, d.title,
d.embedding <=> $1 AS distancia
FROM documents d
JOIN workspaces w ON w.id = d.workspace_id
WHERE d.owner_id = auth.uid()
ORDER BY d.embedding <=> $1
LIMIT 10;
// Edge Function (Deno): genera y guarda el embedding sin exponer secretos
Deno.serve(async (req) => {
const { content, docId } = await req.json();
const res = await fetch("https://api.openai.com/v1/embeddings", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": Bearer ${Deno.env.get("OPENAI_API_KEY")},
},
body: JSON.stringify({ model: "text-embedding-3-small", input: content }),
});
const { data } = await res.json();
await supabase.from("documents")
.update({ embedding: data[0].embedding })
.eq("id", docId);
return new Response("ok", { status: 200 });
});
Artículos relacionados
- Supabase vs Firebase 2026: Deja de Llamarlo "Firebase para PostgreSQL" — Es una Trampa para Frontend Developers
- Supabase vs Firebase 2026: El NoSQL fue un Desvío de 10 Años y Supabase es la Vuelta a la Cordura
- Supabase vs Firebase 2026: El NoSQL fue un Desvío de 10 Años y Supabase es la Vuelta a la Cordura
- Supabase vs Firebase 2026: El NoSQL fue un Desvío de 10 Años y Supabase es la Vuelta a la Cordura
- Supabase vs Firebase 2026: El Producto no es el Dashboard — es una PostgreSQL que Tú Mismo Vas a Exponer si Ignoras el RLS
---
¿Quieres recibir contenido como este cada semana? Suscríbete a mi newsletter

