Der TSV 1990 Merseburg ist ein Tischtennisverein aus Merseburg, Sachsen-Anhalt, mit mehreren Herren-, Damen- und Nachwuchsmannschaften in verschiedenen Ligen. Der Verein wollte seinen Mitgliedern, Fans und potenziellen Neuzugängen eine moderne, übersichtliche Online-Präsenz bieten — eine, die aktuelle Tabellen und Spielpläne automatisch anzeigt, ohne dass jemand im Vorstand manuell Daten pflegen muss.
Diese Case Study beschreibt, wie wir das Problem angegangen sind, welche technischen Entscheidungen wir getroffen haben und was dabei herausgekommen ist.
Die Herausforderung
Vereinswebsites haben ein typisches Problem: sie veralten. Wer pflegt wochentags Tabellenstände nach, wenn der Ligaspieltag am Wochenende war? In der Praxis — niemand. Die meisten Vereinswebsites zeigen Tabellen aus der Vorsaison oder gar keine. Das frustriert Mitglieder und macht die Website irrelevant.
Hinzu kamen konkrete technische Anforderungen:
- Automatisch aktuelle Tabellenstände und Spielplandaten von mytischtennis.de einbinden
- Mobile-first — die Mehrheit der Vereinsmitglieder surft mobil
- Ladezeit deutlich unter einer Sekunde, auch auf schlechten Verbindungen
- Kein CMS, kein Redaktionssystem, kein Passwort, das jemand vergisst — zero maintenance für den Vorstand
- DSGVO-konform: keine externen Fonts, kein Google Analytics, kein Tracking
Unsere Lösung: Laravel auf tmpfs mit AJAX-Tabellen
Der Kern unserer Architektur ist eine Multi-Domain Laravel-Applikation: eine einzige Codebase, die verschiedene Websites auf verschiedenen Domains ausliefert. Für den TSV Merseburg haben wir eine Domain in der zentralen Konfiguration eingetragen — fertig. Kein separates Repo, kein separates Deployment.
Statischer HTML-Cache auf tmpfs
Das Performance-Herzstück ist ein statischer HTML-Cache, der auf einem tmpfs-Filesystem läuft — also im RAM des Servers. Wenn ein Nutzer eine Seite zum ersten Mal aufruft, rendert Laravel die Blade-Template, schreibt das fertige HTML in eine Datei auf dem RAM-Disk und sendet es aus. Beim nächsten Aufruf liefert Nginx diese Datei direkt aus, ohne PHP oder die Datenbank auch nur zu berühren.
Das Ergebnis: Ladezeiten unter 50 Millisekunden für gecachte Seiten — gemessen am Server. Im Vergleich: eine typische WordPress-Seite ohne Caching braucht 500–2.000 ms, selbst mit gutem Caching selten unter 150 ms.
AJAX-Tabellen und Spielplan
Tabellen und Spielplandaten sind dynamisch und ändern sich wöchentlich. Diese laden wir via AJAX nach — der initiale Seitenaufruf ist damit sofort da (gecachtes HTML), die Tabellendaten kommen asynchron nach. Der Nutzer sieht sofort Inhalt, die Tabelle folgt in Millisekunden.
Im Hintergrund laufen zwei Services: TsvTableService und TsvScheduleService. Sie scrapen die Daten von mytischtennis.de, parsen die HTML-Tabellen und speichern das Ergebnis im SQLite-basierten Laravel-Cache mit einer TTL von einer Stunde. Ein stündlicher Cron-Job (`tsv:refresh-tables`) hält die Daten frisch und sendet bei Fehlern eine Mail an uns — der Vorstand bekommt davon nichts mit.
Technische Details
Der Server läuft auf Hetzner Cloud in Deutschland — wichtig für die DSGVO. Als Webserver nutzen wir Nginx 1.24 mit PHP 8.4-FPM. Das SSL-Zertifikat wird über Let's Encrypt automatisch erneuert. Die Datenbank ist SQLite — klein, wartungsarm, schnell genug für einen Vereinsverein.
Das Design ist dark-mode-first mit Neon-Akzenten: dunkles Navy als Hintergrund, elektrisches Blau für interaktive Elemente und Highlights. Auf Mobilgeräten öffnet die Navigation als vollbildschirm-Overlay mit animierten Menüpunkten. Kein externer Font, keine Tracking-Pixel, keine Cookie-Banner — DSGVO aus dem Stand.
Ergebnis
Die Website läuft seit dem Launch wartungsfrei. Der Vorstand kümmert sich um den Verein — nicht um Software-Updates oder Datenbankbackups. Tabellen und Spielpläne aktualisieren sich automatisch. Die Seite lädt schneller als jede vergleichbare Vereinswebsite in der Region.
Und falls die externe Datenquelle mal einen Tag ausfällt? Der Cache liefert die zuletzt bekannten Daten aus, der Cron sendet uns eine Benachrichtigung. Der Nutzer sieht nichts davon.