Leaders of AI · Ops
Engagement-Cron: weniger Last, gleiche Mails
Vorschlag: Kandidatenliste im Parent per SQL filtern — Subflows und Versand unverändert.
Phase 1 Staffelung (live)
Phase 2 SQL-first (zur Abstimmung)
Kontext
Vier Mails, ein Parent
- Expiring Soon · Streak Lost · Return Nudge · Return Urgency
- Parent entscheidet wen er aufruft
- Subflow macht Event, Lea-Text, SendGrid
Phase 1: Trigger gestaffelt (07:00 / 08:30 / 10:00 / 17:00) — Überlappung runter.
Problem
Filter kommt zu spät
Wir laden viele Members und fragen erst im Subflow: „Brauchst du die Mail?“
- Lange Runs, hohe CPU
- Meiste Calls enden ohne Versand
- Risiko, dass Crons sich in die Quere kommen
Warum so gebaut?
Zwei Systeme, zwei Fragen
| Schritt | System | Frage |
| Enrollments | Airtable | Wer ist eingeschrieben? |
| Status | Supabase | Active? |
| Streak / Return | Supabase Events | Mail heute? |
Die dritte Frage entscheidet — lag bisher am Ende.
Alt vs. neu
Bisher
Airtable ×4 → alle Members
→ Status-Loop
→ Switch
→ Subflow fragt SQL
→ meist: nichts senden
Vorschlag
SQL: nur wer die Mail braucht
→ Loop
→ Subflow (unverändert)
→ Event + Lea + SendGrid
Lösung
SQL-first Parent
Schedule (gestaffelt)
→ SQL „wer braucht Event X?“
→ Filter memberId
→ Loop → Call Subflow X
× 4 Bahnen (Expiring / Lost / Nudge / Urgency)
Kein gemeinsames Airtable-Input, kein Switch über alle.
Scope-Zaun
Was wir nicht anfassen
- Subflows: Event-Insert, Lea-Agent, SendGrid
- Notification- / Gamification-Tools darunter
- Produktregeln (Tage −1 / −3 / −10 …)
- Mail-Templates
Nur die Kandidatenliste im Parent.
Offene Frage
Enrollment „ohne Zertifikat“?
Alt: Airtable filterte Enrollments ohne Zertifikat-Link.
Neu: Active in lms.users + Event-SQL.
Reicht das für Engagement — oder muss „ohne Zertifikat“ hart bleiben?
Sicherheit
Cutover ohne Drama
- Als neuen Workflow importieren
- Schedules erst disabled
- SQL-Counts vs. DEBUG / Stichprobe
- Alten Trigger pausieren — nicht doppelt senden
Subflows prüfen weiter „heute schon?“ — doppelte Safety.
Besprechung
Leitfaden
- Phase 1 Staffelung war richtig
- Ursache: Filter zu spät
- Fix: gleiche Regeln, früher im Parent
- Validieren → dann umschalten
- Optional später: LLM/Wait in Subflows (eigener Slice)
Erkennung · CPU / OOM
Engagement ≠ einzig mögliche Ursache
Starker Fit zu Grafana-Morgen-Spike — aber kein Beweis, dass nichts anderes mitläuft.
- CPU voll = oft Überlappung langer Runs
- OOM = oft große Item-Mengen / V8 in einem Run
- Supabase-CPU (Call) kann parallel lastig sein
Erkennung · wo messen
Grafana → n8n-Pod
- Dashboards → Ordner Azure Managed Prometheus
- Öffnen: Kubernetes / Compute Resources / Namespace (Pods) oder Namespace (Workloads)
- Oben: Cluster wählen, Namespace =
n8n-prod
- CPU/Memory-Spike-Uhrzeit notieren → n8n Executions im gleichen Fenster
Nicht Azure SQL. Optional danach: Ordner LoAI → LoAI Application.
Erkennung · n8n UI
Lange Runs finden (ohne Duration-Filter)
- Executions-Filter hat kein „länger als X Minuten“
- Status Running + alte Started-Zeit = hängend/lang
- Workflow-Filter + Zeitfenster aus Grafana, dann scrollen (Run Time-Spalte)
- 5–12 Min Lerntutor/Notifications: unschön, meist nicht der Morgen-CPU-Hauptverursacher
- Kritisch: Stunden-Runs oder viele lange Runs gleichzeitig
Erkennung · weitere Kandidaten
Neben Engagement im Blick
- Webhook / Tool — LMS Lerntutor Events & Notifications (~5–7 Min gesehen)
- Community-Notifications / Sync-Crons (Cron-Inventar 06–11)
- Sentry = Node-Drilldown für einen Run (Zugang nachziehen)
- n8n API: Executions holen + nach Dauer sortieren (UI kann das nicht)
Abschluss
Kleine Änderung, großer Hebel
Weniger sinnlose Subflow-Calls — gleiche Mails, gleiche Texte, gleiche Regeln.
Repo notes/n8n/parent-sql-first-all-four.json
Detail briefing-sql-first-engagement.md