ADR-0002: Kein Redis, bis ein konkreter Auslöser eintritt¶
- Status: accepted
- Datum: 2026-08-21
- Betrifft: Architektur, Deployment
Kontext¶
Die ursprüngliche Architekturskizze sah Redis als festen Bestandteil vor, mit dem Verwendungszweck "Caching". Bei der Durchsicht ließ sich dieser Zweck nicht belegen: Bei einer Nutzerzahl im niedrigen zweistelligen Bereich beantwortet Postgres alle Lese-Abfragen (Rangliste, Tabelle, Historie) im Sub-Millisekunden-Bereich. Ein Cache würde Invalidierungslogik einführen, ohne ein bestehendes Problem zu lösen.
Es gibt jedoch zwei Anforderungen, für die Redis die naheliegende Lösung ist — beide sind im MVP nicht enthalten.
Entscheidung¶
Redis wird nicht aufgenommen. Es wird aufgenommen, sobald einer der folgenden Auslöser eintritt:
- Die App läuft mit mehr als einer Replica und nutzt SSE. Live-Score-Events
müssen dann an Verbindungen auf allen Replicas verteilt werden. Ohne Redis
Pub/Sub (oder Postgres
LISTEN/NOTIFY) sieht ein Client nur die Events, die auf seiner eigenen Replica entstehen. - Die Platten-Buchung wird umgesetzt. Zwischen "Slot ausgewählt" und "Buchung
committed" braucht es einen kurzlebigen Lock, um Doppelbuchungen zu
verhindern.
SET NXmit TTL ist dafür das passende Primitiv.
Bis dahin gilt: In-Process-Caching, wo überhaupt nötig.
Konsequenzen¶
- Positiv: Zwei Container statt drei in allen Zielumgebungen. Einfacheres Compose-File, ein Backing Service weniger in K8s und ACA.
- Positiv: Keine Cache-Invalidierung, damit eine ganze Klasse von Inkonsistenz-Bugs ausgeschlossen.
- Negativ: Wenn Auslöser 1 eintritt, ist Redis nachträglich einzuziehen. Der Aufwand wird auf wenige Stunden geschätzt, da die Event-Verteilung ohnehin hinter einer Schnittstelle liegt.
- Risiko: Diese Entscheidung sieht ohne Kontext wie ein Versäumnis aus. Genau deshalb existiert dieses ADR.
Hinweis für später¶
Falls nur Auslöser 1 eintritt und Auslöser 2 dauerhaft ausbleibt, ist Postgres
LISTEN/NOTIFY die schlankere Alternative zu Redis Pub/Sub — es kommt ohne
zusätzlichen Service aus. Für den Lock-Anwendungsfall taugt es nicht, dafür
braucht es Redis oder SELECT ... FOR UPDATE SKIP LOCKED.