---
term: 'Präsenz (Online-Status)'
seoTitle: 'Präsenz (Online-Status): Heartbeats und zuletzt gesehen'
headline: 'Was ist Präsenz (Online-Status)?'
slug: praesenz-online-status
category: api-realtime
shortDefinition: 'Präsenz ist ein Echtzeitsignal dafür, ob ein Nutzer gerade online, abwesend oder offline ist, aktuell gehalten durch Verbindungen und Heartbeats.'
relatedTerms:
  - real-time-live-queries
  - websockets-real-time-sync
  - pub-sub-pattern
  - sse-vs-websockets-vs-polling
contrastsWith:
  - push-notifications-apns-fcm
aboutTerms:
  - 'Online Status'
  - 'Last Seen'
  - 'Heartbeat'
  - 'Typing Indicators'
faq:
  - question: 'Was ist ein Präsenzsystem?'
    answer: 'Ein Dienst, der verfolgt, ob jeder Nutzer gerade online, abwesend oder offline ist, und Änderungen in Echtzeit an die Nutzer verteilt, die sie sehen dürfen. Unter der Haube: dauerhafte Verbindungen oder regelmäßige Heartbeats, die in einen schnellen In-Memory-Speicher schreiben, wobei Statusänderungen über Pub/Sub ausgefächert werden.'
  - question: 'Wie funktioniert "zuletzt gesehen"?'
    answer: 'Der Server hält bei jedem Heartbeat und jeder Trennung einen Zeitstempel fest. Solange Sie online sind, wird der Live-Status ausgeliefert; sobald Sie offline gehen, antwortet stattdessen der zuletzt aufgezeichnete Zeitstempel. Es ist das eine dauerhafte Stück eines ansonsten flüchtigen Systems – der Status verfällt, "zuletzt gesehen" bleibt.'
  - question: 'Welches Heartbeat-Intervall sollte Präsenz verwenden?'
    answer: '30 Sekunden sind der verbreitete Standard in der Produktion, mit einer Offline-Zeitüberschreitung beim Zwei- bis Dreifachen des Intervalls (60–90 Sekunden). Kürzere Intervalle verkleinern die Erkennungsverzögerung, vervielfachen aber die Schreiblast linear mit Ihrer Online-Population; das Intervall muss außerdem unter den Idle-Timeouts der Infrastruktur bleiben, sonst töten Proxys stille Verbindungen zuerst.'
  - question: 'Erkennung über die Verbindung oder über Heartbeats – was ist besser?'
    answer: 'Beides, für unterschiedliche Fehler. Verbindungsereignisse (open/close) liefern sofortige Übergänge, verpassen aber den stillen Tod – ein Gerät, dem der Strom ausgeht, sendet kein Close-Frame und hinterlässt eine Zombie-Verbindung. Der Ablauf des Heartbeats begrenzt diese Veralterung, zum Preis einer Erkennungsverzögerung. Produktionssysteme nutzen Verbindungsereignisse als schnellen Pfad und die Heartbeat-TTL als Quelle der Wahrheit.'
  - question: 'Wie verhindern Sie, dass der Online-Status flackert?'
    answer: 'Entprellen Sie den Übergang nach offline: Starten Sie bei der Trennung einen Kulanz-Timer – üblich sind 30 bis 60 Sekunden – und brechen Sie ihn ab, wenn der Nutzer sich neu verbindet; "offline" wird erst veröffentlicht, wenn der Timer ausläuft. Nutzer in Aufzügen und Bahntunneln verbinden sich ständig neu; ohne diese Kulanzzeit flackert jede Kontaktliste mit, auf der sie erscheinen.'
  - question: 'Wie skaliert Präsenz auf Millionen von Nutzern?'
    answer: 'Indem Sie die Rechnung des Fan-outs respektieren: Jede Statusänderung muss jeden Beobachter erreichen, N Kontakte mal M Übergänge explodieren also schnell. Die Hebel sind ein In-Memory-TTL-Speicher für den Status, das Abonnieren nur der sichtbaren Nutzer (die offene Chatliste, nicht das gesamte Adressbuch), das Abrufen von "zuletzt gesehen" bei Bedarf statt es zu pushen, und eine Obergrenze für die Statusverteilung in großen Gruppen.'
  - question: 'Wie funktioniert Präsenz über mehrere Geräte?'
    answer: 'Verfolgen Sie eine Verbindung oder einen Heartbeat pro Gerät und führen Sie sie zusammen: Der Nutzer ist online, solange irgendein Gerät es ist, und offline erst, wenn das letzte verstummt. Die übliche Merge-Regel lautet "verfügbarster Zustand gewinnt" – online auf dem Telefon schlägt untätig auf dem Desktop – wobei "zuletzt gesehen" vom jüngsten Gerät stammt.'
  - question: 'Können Nutzer ihren Online-Status verbergen?'
    answer: 'Sie sollten es können – Sichtbarkeit ist ein Produkt-Feature und kein nachträglicher Einfall: Regeln wie alle, nur Kontakte oder niemand, meist mit Gegenseitigkeit (wer den eigenen Status verbirgt, sieht auch die anderen nicht). Präsenzdaten sind Verhaltensdaten; legen Sie im Berechtigungsmodell fest, wer wen beobachten darf, nicht in der Oberfläche.'
codeLanguages: [javascript, dart, swift, kotlin]
externalAuthorities:
  - name: 'RFC 6121 — XMPP: Instant Messaging and Presence'
    url: 'https://datatracker.ietf.org/doc/html/rfc6121'
  - name: 'RFC 6455 — The WebSocket Protocol (ping/pong, close codes)'
    url: 'https://datatracker.ietf.org/doc/html/rfc6455'
  - name: 'Page Visibility API — MDN Web Docs'
    url: 'https://developer.mozilla.org/en-US/docs/Web/API/Page_Visibility_API'
  - name: 'Beacon API — MDN Web Docs'
    url: 'https://developer.mozilla.org/en-US/docs/Web/API/Beacon_API'
  - name: 'Presence information — Wikipedia'
    url: 'https://en.wikipedia.org/wiki/Presence_information'
cta:
  title: 'Grüne Punkte ohne eigene Infrastruktur'
  text: 'Bauen Sie Präsenz auf Back4app mit dem, was die Plattform ohnehin betreibt: einer Presence-Klasse, Heartbeat-Speicherungen, einem Live-Query-Abonnement für Ihre Kontaktliste und einem geplanten Durchlauf für Zeitüberschreitungen – Berechtigungen inklusive.'
  linkText: 'Kostenlos starten'
  linkUrl: 'https://www.back4app.com/signup'
author: 'Back4app Engineering'
publishedDate: '2026-09-29'
translationKey: presence-online-status
---

**Präsenz ist ein Echtzeitsignal dafür, ob ein Nutzer gerade online, abwesend oder offline ist, aktuell gehalten durch Verbindungen und Heartbeats.** Der grüne Punkt ist täuschend einfache Oberfläche über einem wirklich schweren verteilten Problem: Der Server muss Abwesenheit *erschließen* – Geräte kündigen ihr Ende selten an – und dann jede Schlussfolgerung an alle Zuschauenden senden, im Maßstab einer Kontaktliste. Standardisiert wurde das Muster lange vor dem modernen Chat, in den [Presence-Stanzas](https://datatracker.ietf.org/doc/html/rfc6121) von XMPP; seine Grundlagen haben sich seither nicht verändert.

## Das Wichtigste in Kürze

| Frage | Antwort |
| --- | --- |
| Die Zustände | online · abwesend/untätig · offline – dazu vom Nutzer gesetzte Vorgaben (bitte nicht stören) |
| Der Mechanismus | Heartbeat-Schreibvorgänge + TTL-Ablauf; Verbindungsereignisse als schneller Pfad |
| Die Zahlen | ~30 s Heartbeat · Offline-Zeitüberschreitung beim 2–3-Fachen des Intervalls · 30–60 s Flap-Kulanz |
| Der Begleiter | Zuletzt gesehen – der dauerhafte Zeitstempel hinter dem flüchtigen Punkt |
| Das Schwierige | Fan-out: N Beobachter × M Statusänderungen, multipliziert mit Ihrem Erfolg |

## Der Heartbeat-Vertrag

Das gesamte Muster passt in einen einzigen Austausch:

```text
Client      alle 30 s:  save { status: "online", lastActiveAt: now }
Server      alle 60 s:  Sweep — lastActiveAt älter als 90 s?  → status: "offline"
                        (TTL = 2–3 × Heartbeat-Intervall)
Beobachter  status = "online"   → grüner Punkt
            status = "offline"  → "zuletzt gesehen 12:41"  ← lastActiveAt, der dauerhafte Teil
```

Derselbe Vertrag als SDK-Code – Heartbeat hinaus, Abonnement herein:

**JavaScript:**

```javascript
// JavaScript / Node.js — Back4app JS SDK
// Presence: heartbeat your own status, subscribe to your contacts'
const heartbeat = () =>
  myPresence.save({ status: 'online', lastActiveAt: new Date() });
await heartbeat();
setInterval(heartbeat, 30_000); // server sweeps offline at 2–3× this

const contacts = new Parse.Query('Presence');
contacts.containedIn('user', myContactIds);
const sub = await contacts.subscribe();
sub.on('update', (p) => setStatus(p.get('user'), p.get('status')));
```

**Flutter:**

```dart
// Flutter / Dart — Back4app Flutter SDK
// Presence: heartbeat your own status, subscribe to your contacts'
Future<void> heartbeat() async {
  myPresence
    ..set('status', 'online')
    ..set('lastActiveAt', DateTime.now());
  await myPresence.save();
}
Timer.periodic(const Duration(seconds: 30), (_) => heartbeat());

final contacts = QueryBuilder<ParseObject>(ParseObject('Presence'))
  ..whereContainedIn('user', myContactIds);
final sub = await LiveQuery().client.subscribe(contacts);
sub.on(LiveQueryEvent.update, (p) => setStatus(p.get('user'), p.get('status')));
```

**Swift:**

```swift
// iOS / Swift — Back4app Swift SDK
// Presence: heartbeat your own status, subscribe to your contacts'
func heartbeat() async throws {
    myPresence.status = "online"
    myPresence.lastActiveAt = Date()
    _ = try await myPresence.save()
}
// Fire every 30 s — the server sweeps offline at 2–3× this

let contacts = Presence.query(containedIn(key: "user", array: myContactIds))
let sub = try await contacts.subscribe()
sub.handleEvent { _, e in
    if case .updated(let p) = e { setStatus(p.user, p.status) }
}
```

**Kotlin:**

```kotlin
// Android / Kotlin — Back4app Android SDK
// Presence: heartbeat your own status, subscribe to your contacts'
fun heartbeat() {
    myPresence.put("status", "online")
    myPresence.put("lastActiveAt", Date())
    myPresence.saveInBackground()
}
timer.scheduleAtFixedRate(0, 30_000) { heartbeat() } // sweep at 2–3× this

val contacts = ParseQuery.getQuery<ParseObject>("Presence")
contacts.whereContainedIn("user", myContactIds)
val sub = ParseLiveQueryClient.Factory.getClient().subscribe(contacts)
sub.handleEvent(SubscriptionHandling.Event.UPDATE) { _, p ->
    setStatus(p.getString("user"), p.getString("status"))
}
```

## Verbindungsereignisse vs. Heartbeat-TTL

Die beiden Erkennungsmodelle, ehrlich verglichen – keine Ranking-Seite tut das in einer einzigen Tabelle:

| | Verbindungslebenszyklus | Heartbeat + TTL |
| --- | --- | --- |
| Online-Signal | Socket geöffnet | Frischer Heartbeat im Zeitfenster |
| Offline-Signal | Close-Ereignis / Close-Frame | TTL-Ablauf – kein Heartbeat über 2–3 Intervalle |
| Erkennungstempo | Sofort bei sauberem Schließen | Begrenzte Verzögerung (bis zur Zeitüberschreitung) |
| Stille Ausfälle | **Verpasst** – Stromverlust sendet kein Close-Frame | Erfasst – die Stille ist das Signal |
| Serverzustand | Verfolgung pro Verbindung | Zustandslose Schreibvorgänge in einen TTL-Speicher |
| Versagt wie | Zombie-Nutzer auf "online" | Kurz falsches "offline" bei verpassten Heartbeats |

Das [WebSocket-Protokoll](https://datatracker.ietf.org/doc/html/rfc6455) selbst lehrt die Lektion: Es bringt Ping-/Pong-Steuerframes genau deshalb mit, weil TCP einen verschwundenen Gegenüber nicht offenbart, und seine Taxonomie der Close-Codes reserviert 1006 für "abnormales Schließen – kein Close-Frame empfangen", den Zombie-Fall. Produktionsreife Präsenz schichtet daher beide Modelle übereinander: Verbindungsereignisse für sofortige Übergänge, den Heartbeat-Ablauf als die Wahrheit, die auffängt, was die Ereignisse verpassen.

## Der Zustandsautomat

```mermaid
flowchart LR
  accTitle: Präsenz-Zustandsautomat mit Kulanzzeit
  accDescr: Ein Nutzer wechselt bei Verbindung oder Heartbeat von offline nach online, von online nach abwesend, wenn die App in den Hintergrund geht oder die Eingabe untätig wird, und Richtung offline über eine Kulanzzeit, die bei Trennung oder verpassten Heartbeats beginnt und abgebrochen wird, wenn der Nutzer sich rechtzeitig neu verbindet.
  OFF["offline<br/>(zuletzt gesehen liefern)"] -->|"verbinden / Heartbeat"| ON["online"]
  ON -->|"Tab verborgen · Eingabe untätig"| AW["abwesend"]
  AW -->|"Aktivität kehrt zurück"| ON
  ON -->|"Trennung oder verpasste Heartbeats"| GR["Kulanzzeit<br/>30–60 s"]
  AW -->|"Trennung oder verpasste Heartbeats"| GR
  GR -->|"verbindet sich rechtzeitig neu"| ON
  GR -->|"Timer läuft ab → veröffentlichen"| OFF
```

Zwei Verfeinerungen zeichnen ausgereifte Implementierungen aus. **Abwesenheit wird auf dem Client erkannt:** Der Server sieht einen in den Hintergrund geschobenen Tab nicht, der Browser schon – die [Page Visibility API](https://developer.mozilla.org/en-US/docs/Web/API/Page_Visibility_API) meldet verborgene Tabs, Eingabe-Listener melden Untätigkeit, und ein Offline-Signal nach bestem Bemühen beim Schließen des Tabs reitet auf der [Beacon API](https://developer.mozilla.org/en-US/docs/Web/API/Beacon_API). **Offline wird entprellt:** Der Kulanzzustand existiert, weil mobile Verbindungen flattern – veröffentlichen Sie "offline" bei jedem Tunnel und jedem Aufzug, und die Kontaktliste jedes Beobachters flackert mitfühlend mit. Verzögern Sie die Ankündigung, brechen Sie bei Wiederverbindung ab, und das Flattern fällt in sich zusammen. Eine weitere Unterscheidung lohnt sich, vom Protokoll übernommen, das Präsenz formalisiert hat: *berechnete* Präsenz (online, über die Verbindung) gegenüber *vom Nutzer gesetztem* Status (bitte nicht stören) – Letzterer gewinnt die Zusammenführung immer.

## Flüchtig von Entwurf wegen

Präsenz ist ein Cache der Wirklichkeit, keine dauerhafte Aufzeichnung: Ein Status, der zu spät eintrifft, ist schlimmer als gar keiner – das "online" von gestern ist heute eine Lüge. Dieses Prinzip treibt die Umsetzungsentscheidungen: Status liegt in schnellen Speichern mit TTL statt in dauerhaften Tabellen, wird nie zur späteren Zustellung in die Warteschlange gestellt und fällt unter Backpressure als Erstes weg. Nur `lastActiveAt` verdient Persistenz. **Tippanzeigen** sind dieses Prinzip in seiner Extremform – Mikro-Präsenz auf eine einzige Unterhaltung begrenzt, in Sekunden verfallend, beim Sender entprellt und verworfen statt wiederholt; wenn "Ada tippt …" nicht jetzt ankommen kann, sollte es nie ankommen.

## Das Fan-out-Problem

Die Skalierungsmauer der Präsenz ist Multiplikation, nicht Speicher. Ein durchgerechnetes Beispiel: 100.000 gleichzeitige Nutzer, jeder für 50 Kontakte sichtbar, jeder mit bescheidenen 20 Zustandswechseln pro Stunde – das sind 100.000 × 50 × 20 = **100 Millionen Präsenzereignisse pro Stunde**, die zuzustellen sind, von einem Feature, das pro Nutzer eine kleine Zeile speichert. Die Hebel, in der Reihenfolge, in der man sie zieht: **eng abonnieren** – die Nutzer auf dem Bildschirm beobachten (die offene Liste der Unterhaltungen), nicht den gesamten Kontaktgraphen; **den Long Tail abrufen statt pushen** – "zuletzt gesehen" beim Öffnen eines Profils holen, statt es zu streamen; **die Verteilung in Gruppen begrenzen** – jenseits einiger hundert Mitglieder Präsenz bei Interaktion zeigen, nicht für die gesamte Liste; und **Übergänge bündeln**, sodass ein flatternder Nutzer ein entprelltes Ereignis kostet und nicht dreißig. Das Fan-out selbst reitet auf der üblichen [Pub/Sub](/glossary/de/pub-sub-muster/)-Maschinerie – Präsenz ist der At-most-once-Sonderfall dieses Musters, in dem das Verwerfen eines veralteten Ereignisses ein Feature ist.

## Mehrere Geräte und Datenschutz

Ein Nutzer, drei Geräte, ein Punkt – Präsenz pro *Nutzer* ist eine Zusammenführung von Präsenz pro *Gerät*. Verfolgen Sie den Heartbeat jedes Geräts getrennt; der Nutzer ist online, solange irgendein Gerät es ist, und die Merge-Regel lautet "verfügbarster Zustand gewinnt": online auf dem Telefon schlägt untätig auf dem Desktop, und das "bitte nicht stören" irgendeines Geräts überstimmt den Rest. "Zuletzt gesehen" meldet das jüngste Gerät. Datenschutz ist die andere Hälfte des Entwurfs, und die Hälfte, die Engineering-Blogs überspringen, obwohl Nutzer genau danach am häufigsten fragen: Sichtbarkeitsregeln (alle / Kontakte / niemand), Gegenseitigkeit (wer sich verbirgt, verliert den Blick auf die anderen) und ein grobes "zuletzt gesehen" ("kürzlich" statt Zeitstempeln). Setzen Sie die Regeln in den Berechtigungen der Datenschicht durch – Präsenz ist Verhaltensdaten, und ein durchgesickertes "online um 3 Uhr nachts" ist eine echte Offenlegung.

## Typische Anwendungsfälle

- **Chat und Messaging** – der kanonische grüne Punkt, "zuletzt gesehen" und Tippanzeigen.
- **Kollaborationswerkzeuge** – wer im Dokument ist, Cursor-Präsenz, Seitenleisten mit aktiven Personen.
- **Support und Marktplätze** – Routing nach Verfügbarkeit von Agenten, Vertrauenssignale wie "Verkäufer ist online".
- **Multiplayer und Soziales** – Lobbys, Freundeslisten, Einstiegsmöglichkeiten zu Freunden.
- **Werkzeuge für die Belegschaft** – Verfügbarkeitszustände, die Routing und Status-Dashboards speisen.

## Wie sollten Sie Präsenz bauen? Eine Entscheidungsmatrix

| Feature | Mechanismus |
| --- | --- |
| Grüner Punkt bei Kontakten | Heartbeat + TTL-Speicher, Live-Query-Abonnement auf sichtbare Nutzer |
| Sofortige Übergänge in einem offenen Chat | Verbindungsereignisse als schneller Pfad über den Socket |
| Zuletzt gesehen | Zeitstempel bei jedem Heartbeat; bei Bedarf abrufen |
| Erkennung von Abwesenheit | Clientseitig: Visibility- und Idle-Listener, im Heartbeat gemeldet |
| Tippanzeige | Mikro-Ereignisse pro Unterhaltung, TTL von Sekunden, nie persistiert |
| Präsenz in einer Gruppe mit 5.000 Mitgliedern | Nicht verteilen – bei Interaktion zeigen, die Liste begrenzen |

## Grenzen und Trade-offs

- **Präsenz ist probabilistisch.** Zwischen zwei Heartbeats ist der Punkt eine Vermutung; ehrliche Systeme bekennen sich zu begrenzter Veralterung, statt sofortige Wahrheit vorzutäuschen.
- **Aktualität kostet Schreibvorgänge.** Das Heartbeat-Intervall zu halbieren verdoppelt die Schreiblast über alle Online-Nutzer hinweg – Erkennungstempo wird in Durchsatz bezahlt.
- **Fan-out skaliert mit dem Erfolg.** Das Feature ist bei 1.000 Nutzern günstig und bei 10 Millionen ein Architekturprojekt; entwerfen Sie den Umfang der Abonnements, bevor das Wachstum Sie dazu zwingt.
- **Flattern ist systemimmanent.** Mobilfunknetze garantieren ständige Wiederverbindungen; ohne Entprellen verstärkt Präsenz Netzrauschen zu Rauschen in der Oberfläche.
- **Es hat die Form einer Überwachung.** Online-Muster verraten Schlaf, Arbeit und Gewohnheiten; Sichtbarkeitsregeln und ihre Durchsetzung in der Berechtigungsschicht sind Anforderungen, keine Verbesserungen.

## Präsenz mit Back4app

Back4app ist eine Open-Source-Plattform für Backend as a Service (BaaS), die eine verwaltete Datenbank, automatisch generierte REST- und GraphQL-APIs, Authentifizierung, Dateispeicher und Serverless-Funktionen mit Cloud Code kombiniert. Die Bausteine von oben bilden sich eins zu eins ab: Eine `Presence`-Klasse hält `status` und `lastActiveAt`; der Heartbeat ist eine periodische Speicherung (die Code-Tabs); Beobachter halten ein [Live-Query](/glossary/de/live-queries-echtzeit/)-Abonnement auf die gerade sichtbaren Kontakte und empfangen gepushte Aktualisierungen über die verwaltete [WebSocket](/glossary/de/websockets/)-Flotte der Plattform; ein geplanter Cloud-Code-Job ist der TTL-Durchlauf, der veraltete Zeilen auf offline setzt und das Entprellen auslöst; und Klassenberechtigungen plus ACLs setzen die Sichtbarkeitsregeln in der Datenschicht um, wo sie hingehören. Nichts Maßgeschneidertes zu betreiben – Präsenz wird zur Übung in Datenmodellierung über Infrastruktur, die das Backend ohnehin betreibt.
