Zum Hauptinhalt springen
Weniger Tools, mehr Postgres – Ein Survival-Guide für dein Backend
#PostgreSQL #Backend #Architektur #DevOps #Kosten

Weniger Tools, mehr Postgres – Ein Survival-Guide für dein Backend

Wie PostgreSQL-Extensions dein Backend vereinfachen und bis zu 10 Services ersetzen können

Einleitung

Moderne Web-Stacks wirken oft wie ein überfüllter Werkzeugkasten: Redis hier, Elasticsearch dort, Auth0 für Logins, Firebase für Realtime, Cronjobs über Lambda, Analytics via SaaS.

Das Ergebnis: Komplexität, Kosten und viele Bruchstellen.

Die gute Nachricht: Postgres 2025 kann die meisten dieser Aufgaben selbst übernehmen.

Wie wir bereits in unseren Artikeln zu PostgreSQL als Plattform und PostgreSQL in der Praxis gezeigt haben, kann PostgreSQL mit den richtigen Extensions locker fünf bis zehn Services ersetzen – ohne dein Backend in eine Service-Wüste zu zerlegen.

Was Postgres ersetzt (Überblick)

Klassisches ToolPostgres-FeatureGeeignet für
RedisUnlogged Tables (Cache)Sessions, Tokens
ElasticsearchTSVECTOR (Volltextsuche)Blogs, Foren, Help-Center
MongoDBJSONB (flexible Dokumente)User-Settings, Logs
RabbitMQ / Cronjobspg_cron + Outbox-PatternJobs, Event-Trigger
Pineconepgvector (AI-Suche)RAG, Empfehlungen
Firebase / Auth0pgcrypto + Row-Level SecurityLogin, Multi-Tenant-SaaS
Google AnalyticsEvents + SQL QueriesKlick-Tracking, Funnel
MixpanelTimescaleDB / pgmeRetention, Dashboards

Praxis-Snippets – so ersetzt du einzelne Tools

Jobs & Zeitpläne mit pg_cron

SELECT cron.schedule(
  'clean_sessions',
  '0 * * * *',
  $$ DELETE FROM sessions WHERE expires_at < now(); $$
);

Ersetzt: Externe Cronjobs oder Functions für einfache Maintenance-Tasks.

Cache mit UNLOGGED TABLES

CREATE UNLOGGED TABLE session_cache (
  token UUID PRIMARY KEY,
  user_id INT,
  expires_at TIMESTAMPTZ
);

Ersetzt: Redis für schnelle, flüchtige Daten.

AI-Suche mit pgvector

SELECT content
FROM docs
ORDER BY embedding <-> '[0.011, -0.043, ...]'::vector
LIMIT 5;

Ersetzt: Pinecone & Co. für kleine bis mittlere Embedding-Szenarien.

Auth & Zugriff mit pgcrypto + RLS

UPDATE users
SET password = crypt('pw', gen_salt('bf'));

ALTER TABLE todos ENABLE ROW LEVEL SECURITY;
CREATE POLICY user_owns_todo ON todos
USING (user_id = current_setting('app.current_user')::INT);

Ersetzt: Login-Logik & Tenant-Isolation direkt in der DB.

Volltextsuche mit TSVECTOR

UPDATE articles
SET search = to_tsvector('english', title || ' ' || body);

SELECT title
FROM articles
WHERE search @@ plainto_tsquery('postgres vector magic')
ORDER BY ts_rank(search, plainto_tsquery('postgres vector magic')) DESC;

Ersetzt: Eine eigene Elasticsearch-Instanz.

Analytics selbst gebaut

CREATE TABLE pageviews (
  path TEXT,
  user_id INT,
  viewed_at TIMESTAMPTZ DEFAULT now()
);

SELECT path, COUNT(*)
FROM pageviews
GROUP BY path
ORDER BY count DESC;

Ersetzt: Google Analytics/Mixpanel – und du behältst die Datenhoheit.

Erweiterungen für mehr Praxisnutzen

Before/After-Szenario

Vorher (klassischer Stack für eine kleine App):

  • Redis für Sessions
  • Auth0 für Logins
  • Firebase für Realtime
  • Elasticsearch für Suche
  • Lambda-Cronjobs für Cleanup
  • Mixpanel für Analytics

Nachher (gleiche App nur mit Postgres):

  • Sessions → Unlogged Tables
  • Auth → pgcrypto + RLS
  • Realtime → LISTEN/NOTIFY oder ElectricSQL
  • Suche → TSVECTOR
  • Cronjobs → pg_cron
  • Analytics → Events-Tabellen + SQL

Ergebnis: Ein einziger Postgres-Cluster, einheitliches Monitoring, weniger Rechnungen.

Kosten-Vergleich (vereinfacht)

Klassischer Multi-Service-Stack:

  • Redis: 10$/Monat
  • Elasticsearch: 50$/Monat
  • Auth0: 50$/Monat
  • Firebase: 25$/Monat
  • Mixpanel: 25$/Monat
  • Gesamt: 160$/Monat für Basis-Funktionen

Postgres-DBaaS Alternative:

  • Supabase / Neon / DO Managed Postgres: 25–50$/Monat inkl. aller Features

Einsparung: Vor allem für Indie-Entwickler & KMU ein entscheidender Unterschied von 110+ $/Monat.

DevOps-Perspektive

Früher: 6 Services deployen, überwachen, updaten. Heute: Eine Postgres-Instanz, zentral Logs, Metriken, Backups.

Tools wie pg_stat_statements oder pg_cron-Views liefern Einblicke direkt aus der Datenbank.

Erweiterte Auth

Zusätzlich zu RLS und pgcrypto:

pgjwt: JWT-Handling direkt in SQL. Use Case: API-Token ausgeben, validieren, sogar Ablaufzeiten in SQL prüfen.

SELECT sign(
  row_to_json(r),
  'your-secret-key'
) AS token
FROM (
  SELECT 'user123' AS sub,
         extract(epoch from now())::integer + 3600 AS exp
) r;

Kombinierte Features

  • FTS + pgvector: Semantische Suche + klassische Volltext-Rankings
  • JSONB + RLS: Multi-Tenant SaaS – flexible Daten je Kunde, aber streng isoliert

Tools im Postgres-Ökosystem

  • ElectricSQL: Echtzeit-Sync zwischen Client und Server
  • PostGraphile: GraphQL-API direkt aus DB-Schema
  • pgme: Analytics & Dashboards einfach in Postgres

Roadmap-Hinweis

Mit Postgres 18 kommen u. a. mehr SQL/JSON-Funktionen und bessere Parallelisierung.

Bedeutung: Die Plattform wird noch stärker, weniger externe Tools werden nötig.

Storytelling-Beispiel: Von der Service-Hölle zur Postgres-Simplicity

Der Ausgangspunkt (2019):

Alex, ein Indie-Entwickler, startet sein SaaS-Projekt “TaskFlow” – eine Projektmanagement-App für kleine Teams. Wie viele andere folgt er den damaligen Best Practices und baut einen “modernen” Stack:

  • MongoDB für flexible User-Daten und Projektstrukturen
  • Redis für Session-Management und Caching
  • Elasticsearch für die Projektsuche
  • Auth0 für Benutzerverwaltung und SSO
  • Firebase für Realtime-Updates zwischen Teammitgliedern
  • Mixpanel für User-Analytics und Conversion-Tracking
  • AWS Lambda für Cronjobs (E-Mail-Versand, Cleanup-Tasks)

Die schmerzhaften Realitäten:

Komplexität explodiert:

  • 7 verschiedene Dashboards zu überwachen
  • Jeder Service hat eigene Logs, Metriken, Alerts
  • Deployment bedeutet: 7 Services koordinieren

Kosten steigen unkontrolliert:

  • MongoDB Atlas: 45$/Monat
  • Redis Cloud: 15$/Monat
  • Elasticsearch Service: 65$/Monat
  • Auth0: 70$/Monat (wegen SSO-Features)
  • Firebase: 35$/Monat
  • Mixpanel: 25$/Monat
  • AWS Lambda + CloudWatch: 20$/Monat
  • Gesamt: 275$/Monat – und das bei nur 500 aktiven Nutzern

Ausfälle werden zum Alptraum:

  • Redis fällt aus → alle Sessions weg
  • Elasticsearch überlastet → Suche funktioniert nicht
  • Auth0 hat Maintenance → niemand kann sich einloggen
  • Jeder Service kann das ganze System lahmlegen

Die Postgres-Transformation (2025):

Nach 6 Jahren Schmerzen entscheidet Alex: Alles muss weg, alles wird Postgres.

Migration Schritt für Schritt:

1. MongoDB → PostgreSQL JSONB

-- Vorher: Komplexe MongoDB-Queries
-- Nachher: SQL mit JSON-Power
CREATE TABLE projects (
  id SERIAL PRIMARY KEY,
  name TEXT,
  settings JSONB,
  members JSONB,
  created_at TIMESTAMPTZ DEFAULT now()
);

-- Flexible Queries wie in MongoDB, aber mit SQL
SELECT name
FROM projects
WHERE settings->>'priority' = 'high'
  AND members @> '[{"role": "admin"}]';

2. Redis → UNLOGGED TABLES

CREATE UNLOGGED TABLE sessions (
  token UUID PRIMARY KEY,
  user_id INTEGER,
  data JSONB,
  expires_at TIMESTAMPTZ
);

-- Auto-Cleanup via pg_cron
SELECT cron.schedule('cleanup-sessions', '*/5 * * * *',
  'DELETE FROM sessions WHERE expires_at < now()');

3. Elasticsearch → TSVECTOR

-- Projektsuche ohne externe Engine
ALTER TABLE projects ADD COLUMN search_vector tsvector;

UPDATE projects
SET search_vector = to_tsvector('english', name || ' ' || description);

-- Suche mit Ranking
SELECT name, ts_rank(search_vector, query) as rank
FROM projects, plainto_tsquery('team collaboration') query
WHERE search_vector @@ query
ORDER BY rank DESC;

4. Auth0 → pgcrypto + RLS

-- Passwort-Hashing
CREATE OR REPLACE FUNCTION hash_password(password TEXT)
RETURNS TEXT AS $$
BEGIN
  RETURN crypt(password, gen_salt('bf', 10));
END;
$$ LANGUAGE plpgsql;

-- Multi-Tenant Isolation
ALTER TABLE projects ENABLE ROW LEVEL SECURITY;
CREATE POLICY tenant_isolation ON projects
  USING (tenant_id = current_setting('app.current_tenant')::integer);

5. Firebase Realtime → LISTEN/NOTIFY

-- Real-time Updates ohne externe API
CREATE OR REPLACE FUNCTION notify_project_update()
RETURNS TRIGGER AS $$
BEGIN
  PERFORM pg_notify('project_updates',
    json_build_object('project_id', NEW.id, 'action', TG_OP)::text);
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER project_update_trigger
  AFTER INSERT OR UPDATE OR DELETE ON projects
  FOR EACH ROW EXECUTE FUNCTION notify_project_update();

6. Mixpanel → Event-Tables

CREATE TABLE events (
  id BIGSERIAL PRIMARY KEY,
  user_id INTEGER,
  event_type TEXT,
  properties JSONB,
  timestamp TIMESTAMPTZ DEFAULT now()
);

-- Analytics ohne externe Tools
SELECT
  date_trunc('day', timestamp) as day,
  COUNT(*) as daily_active_users
FROM events
WHERE event_type = 'login'
  AND timestamp > now() - interval '30 days'
GROUP BY day
ORDER BY day;

Die Ergebnisse nach der Migration:

Drastische Kostensenkung:

  • Vorher: 275$/Monat für 7 Services
  • Nachher: 35$/Monat für Neon Postgres Pro
  • Einsparung: 240$/Monat = 2.880$/Jahr

Ops-Aufwand reduziert um 80%:

  • Vorher: 7 Dashboards, 7 Alert-Systeme, 7 Update-Zyklen
  • Nachher: 1 Postgres-Dashboard, pg_stat_statements, einheitliche Logs

Performance verbessert:

  • Vorher: Netzwerk-Latenz zwischen 7 Services
  • Nachher: Alles in einer DB, optimierte Joins statt API-Calls
  • Suchgeschwindigkeit: 40% schneller durch TSVECTOR vs. Elasticsearch

Reliability erhöht:

  • Vorher: 7 Single Points of Failure
  • Nachher: 1 hochverfügbare Postgres-Instanz mit Replikation
  • Uptime: Von 99.5% auf 99.9% gestiegen

Development-Geschwindigkeit:

  • Vorher: Neue Features benötigten Updates in mehreren Services
  • Nachher: Ein SQL-Migration-File für neue Features
  • Deploy-Zeit: Von 20 Minuten auf 3 Minuten reduziert

Alex’ Fazit nach einem Jahr:

“Ich hätte nie gedacht, dass ich mal alle meine Services durch Postgres ersetzen würde. Aber es funktioniert. Weniger Complexity, weniger Kosten, bessere Performance. Ich fokussiere mich wieder auf Features statt auf Infrastructure-Management. Postgres ist nicht nur eine Datenbank – es ist mein komplettes Backend.”

Lessons Learned:

  • Start simple: Nicht jede App braucht von Tag 1 an Microservices
  • Postgres first: Prüfe zuerst, ob Postgres + Extensions reichen
  • Migration ist möglich: Auch bestehende Apps können schrittweise vereinfacht werden
  • Kosten-Bewusstsein: Frühe Optimierung bei Tools spart später viel Geld

Wo Postgres-first glänzt – und wo nicht

Ideal für:

  • Indie SaaS & MVPs – ein Stack, weniger Kosten
  • Kleine Teams – weniger Ops-Aufwand
  • Projekte mit vielen Features – Auth, Suche, Analytics, Jobs
  • Prototyping – schnelle Iteration ohne Service-Setup

Weniger geeignet für:

  • FAANG-Skala – Multi-Region, globale Latenz-Anforderungen
  • Massive Blob-Speicherung – Videos, Petabyte-Objekte
  • Extrem spezialisierte Anforderungen – z. B. hochskalierte ML-Pipelines
  • Geografisch verteilte Teams – wenn lokale Latenz kritisch ist

Migrationsstrategie

Phase 1: Neue Features

  • Alle neuen Features werden in Postgres implementiert
  • Bestehende Services bleiben erstmal bestehen

Phase 2: Low-Risk Services

  • Caching-Layer (Redis) → UNLOGGED TABLES
  • Cronjobs → pg_cron
  • Analytics → Event-Tables

Phase 3: Core Services

  • Auth-System → pgcrypto + RLS
  • Suche → TSVECTOR/pgvector
  • Realtime → LISTEN/NOTIFY

Phase 4: Clean-up

  • Alte Services abschalten
  • Infrastructure vereinfachen
  • Monitoring konsolidieren

Bottom Line

2025 fühlt es sich fast übertrieben an, für eine einfache App zehn verschiedene Tools hochzuziehen.

Mit Postgres + Extensions baust du ein Backend, das Jobs, Cache, Suche, Auth, AI und Analytics abdeckt.

Die Dev-Erfahrung bleibt simpel: Alles in SQL, weniger Services, weniger Rechnungen, weniger Fehlerquellen.

Merksatz: Statt 20 Tools: Ein Postgres, gut erweitert, reicht oft völlig aus.

Der erste Schritt: Schaue dir deine aktuelle Service-Liste an. Welcher Service könnte als nächstes durch eine Postgres-Extension ersetzt werden?

Die Zukunft gehört nicht komplexeren Stacks – sondern einfacheren.