2026-10-26 · Architektur
Warteschlange und Suche in drei Sprachen ohne neue Dienste: was PostgreSQL kann
Fünf neue Funktionen für einen Messenger, den Teams mit einem Befehl auf dem eigenen Server installieren. Jede hätte einen eigenen Dienst nach sich ziehen können. Am Ende kam keiner dazu.
Einladungen per E-Mail, Push-Benachrichtigungen, Suche, Webhooks und ein Import aus Slack. Für Hintergrundjobs nimmt man üblicherweise einen Message Broker, für die Suche Elasticsearch oder Meilisearch. Bei einem Produkt, das man selbst betreibt, ist aber jeder zusätzliche Dienst eine Pflicht mehr für den, der den Server betreut.
Die Warteschlange
Jobs liegen in PostgreSQL und werden mit FOR UPDATE SKIP LOCKED abgeholt. Wiederholungen laufen mit exponentieller Verzögerung, der Job eines abgestürzten Workers wird erneut aufgenommen, und stundenlange Importe verlängern ihre Sperre mit Lebenszeichen. Steckt im Job ein Einmal-Link aus einer E-Mail, wird sein Inhalt nach der Ausführung gelöscht.
Die eine Falle war die Uhr. Der Startzeitpunkt kam von der Uhr der Anwendung, verglichen wurde aber mit NOW() der Datenbank. Deren Container-Uhr ging nach, und neue Jobs galten als «noch nicht fällig». Jetzt setzt die Datenbank die Zeit selbst. Vergleicht eine Regel mit der Zeit der Datenbank, muss auch die Datenbank die Zeit schreiben.
Suche in drei Sprachen
Die Teams schreiben Deutsch, Englisch und Russisch, oft gemischt. Der Index ist eine berechnete tsvector-Spalte: exakte Tokens jeder Sprache ohne Diakritika mit Gewicht A, dazu die Stämme für Englisch, Russisch und Deutsch mit Gewicht B. Die Abfrage vereint vier websearch_to_tsquery. Der GIN-Index entsteht mit CONCURRENTLY in einer eigenen Migration, weil das Migrationstool jede Datei in einer Transaktion ausführt.
Zugriffsrechte schreibe ich nicht von Hand ins SQL. Ein Test vergleicht die Suchregel mit der normalen Zugriffsprüfung auf einer zufälligen Konfiguration.
Vorab notiert ist auch, wann ich aussteige: über etwa 10 Millionen Nachrichten, p95 über 500 Millisekunden, oder wenn Tippfehlertoleranz oder Suche in Dateien gebraucht werden. Bis dahin laufen alle fünf Funktionen auf PostgreSQL, Redis und Speicher, die schon da waren, und die End-to-End-Prüfung ist von 22 auf 57 Szenarien gewachsen.