Zurück zum Blog

Authentik Login-Page lädt nicht: 215.000 veraltete Task-Logs als Ursache

Datum 10. Juli 2026
Kategorie Self-Hosting / Authentik / PostgreSQL
Betroffener Service Authentik SSO
Symptom: Die Authentik-Login-Seite lud nach dem Aufrufen nur teilweise — Formular und Styles erschienen, aber das JavaScript der Flow-Engine hing. Ein Browser-Refresh löste das Problem jedes Mal. Keine Fehlermeldung, kein roter HTTP-Status.

Ermittlung: Wo hängt es?

Der erste Blick in die Authentik-Server-Logs zeigte auf den ersten Blick nichts Auffälliges — alle Container liefen, Healthchecks schlugen grün an. Erst eine gezielte Suche nach langsamen API-Calls (Laufzeit > 1 Sekunde) brachte das Problem ans Licht:

5174ms  /api/v3/flows/executor/default-provider-authorization-explicit-consent/
5153ms  /api/v3/flows/executor/default-authentication-flow/
5141ms  /api/v3/core/users/me/
1444ms  /api/v3/core/applications/?only_with_launch_url=true

Der Endpunkt /api/v3/core/users/me/ — den die Authentik-SPA beim Seitenaufbau aufruft um den eingeloggten Nutzer zu laden — brauchte über 5 Sekunden. Das JavaScript wartete, der Browser zeigte eine leere bzw. halbfertige Seite. Beim Refresh hatte der Browser die statischen Assets bereits gecacht und nur der API-Call lief neu — manchmal schneller, manchmal wieder langsam.

Ursache: 215.000 veraltete Task-Logs

Ein Blick auf die PostgreSQL-Tabellengrößen enthüllte das eigentliche Problem:

authentik_tasks_tasklog   72 MB   (215.982 Zeilen)
authentik_tasks_task      22 MB   (17.023 Zeilen)

Die Tabelle authentik_tasks_tasklog hatte seit dem letzten Datenbankstart Zehntausende Einträge pro Tag angesammelt, ohne dass je aufgeräumt wurde. Das Autovacuum hatte zuletzt vor mehreren Tagen angelaufen, war aber mit dem Wachstum nicht mehr mitgekommen.

Warum wächst authentik_tasks_tasklog so schnell?

Authentik nutzt ein Task-System (Django-Dramatiq) für alle internen Hintergrundprozesse. Eine Auswertung der Log-Einträge der letzten 24 Stunden zeigte:

authentik.core.tasks.clean_expired_models             7488 Logs/Tag
authentik.outposts.tasks.outpost_service_connection_monitor  1728
authentik.core.tasks.clean_temporary_users            1056
authentik.admin.tasks.update_latest_version            432

Der Task clean_expired_models lief etwa 5-mal pro Minute und schrieb bei jedem Lauf mehrere Log-Einträge — über 7.000 pro Tag allein für diesen einen Task. Ohne periodische Bereinigung akkumulieren sich diese Logs unbegrenzt.

Kein Bug, aber ein Design-Problem: Authentik hat keine eingebaute Retention-Policy für authentik_tasks_tasklog. Die Tabelle wächst dauerhaft, bis manuell oder per Cron aufgeräumt wird.

Der Fix

1. Direkte Bereinigung

134.517 Task-Logs älter als 7 Tage wurden gelöscht, dazu 10.536 abgelaufene Tasks:

DELETE FROM authentik_tasks_tasklog
WHERE timestamp < NOW() - INTERVAL '7 days';
-- 134517 Zeilen gelöscht

DELETE FROM authentik_tasks_task
WHERE result_expiry IS NOT NULL
  AND result_expiry < NOW() - INTERVAL '7 days';
-- 10536 Zeilen gelöscht

2. Speicherplatz zurückgewinnen

Nach dem Löschen ist der Speicher in PostgreSQL noch nicht freigegeben — die Seiten sind als „dead“ markiert, werden aber erst durch Vacuum recycelt. VACUUM FULL komprimiert die Tabelle physisch:

VACUUM FULL ANALYZE authentik_tasks_tasklog;
VACUUM FULL ANALYZE authentik_tasks_task;

Ergebnis: 72 MB → 24 MB für die Tasklog-Tabelle, 22 MB → 6 MB für Tasks.

3. Automatische tägliche Bereinigung

Damit sich das Problem nicht wiederholt, wurde ein täglicher Cron-Job unter /etc/cron.daily/ eingerichtet, der Logs und abgelaufene Tasks älter als 7 Tage automatisch bereinigt.

Ergebnis

Login-Seite lädt sofort:
  • Response-Zeit /api/v3/core/users/me/: 5141 ms → unter 100 ms
  • Kein Browser-Refresh mehr nötig
  • Datenbankgröße dauerhaft kontrolliert durch tägliches Cleanup

Lektionen

Authentik-Tasklog braucht manuelle Retention. Authentik hat keine eingebaute Cleanup-Routine für authentik_tasks_tasklog. Bei aktiven Instanzen mit vielen Background-Tasks (Outpost-Monitoring, Ablauf-Bereinigung) wächst die Tabelle auf Hunderttausende Zeilen pro Monat. Einen Cron-Job zur Bereinigung von Beginn an einrichten.
Langsame API-Calls sind das eigentliche Symptom. „Seite lädt nicht vollständig“ klingt nach einem Frontend-Problem. Tatsächlich war es ein Datenbank-Performance-Problem, das sich im Netzwerk-Tab des Browsers als hängender API-Call zeigte. Immer zuerst die Netzwerk-Requests und Server-Logs prüfen, bevor Frontend oder Browser als Ursache vermutet werden.
VACUUM FULL nach großen Deletes. Ein DELETE gibt in PostgreSQL keinen Speicherplatz frei — die Seiten bleiben als „dead tuples“ stehen. Erst VACUUM FULL komprimiert die Tabelle und gibt Disk-Speicher zurück. Bei Tabellen mit hohem Schreib-Durchsatz und regelmäßigem Löschen lohnt sich eine geplante Wartungsfenster-Routine.