Privacy: was wir nicht sammeln
Fastmons Datenschutz-Position, Punkt für Punkt. Nützlich, wenn Legal nachfragt.
Mit fastmon sollst du Real-User-Performance messen können, ohne dafür ein Datenschutz-Minenfeld aufzumachen. Kurz: keine IPs auf der Platte, kein roher User-Agent, kein Fingerprinting, kein Cross-Site-Tracking, EU-Infrastruktur, null Cookies und ein speicherfreier Default. Auf dieser Seite steht die ausführliche Version: was die Zusagen in der Praxis heißen, was wir trotzdem sammeln, damit das Produkt funktioniert, und wie sich das je nach Tracker-Einstellungen der Site unterscheidet.
Was wir nie sammeln, egal wie eingestellt
Diese Regeln gelten unabhängig davon, wie die Site konfiguriert ist:
| Wir sammeln kein… | Was das praktisch heißt |
|---|---|
| IP-Adressen | Die IP wird am Edge entfernt, bevor sie irgendein Application-Code zu Gesicht bekommt. Das Backend liest nur einen vorbereiteten Ländercode (FM-Country, zweistelliges ISO), nie die IP selbst. Keine IP wird je auf Disk geschrieben. |
| Roher User-Agent-String | Der User-Agent-Header wird ebenfalls am Edge entfernt. Das Backend liest nur vorgefertigte FM-Browser / FM-Browser-Version / FM-OS / FM-Device-Header. Der rohe UA ist für die Anwendung und ihre Logs nie sichtbar. |
| Device- oder Browser-Fingerprints | Kein Canvas-Fingerprinting, keine Font-Enumeration, keine userAgentData-High-Entropy-Hints, kein Battery-/Sensor-/AudioContext-Probing. |
| Cross-Site-IDs | Wir vergeben keine Kennung, die eine Domain-Grenze überlebt. Eine Session auf acme.com ist nicht mit einer auf other.com verknüpfbar. |
| Third-Party-Daten | Wir reichern nicht mit Datenbrokern, Ad-Networks oder Social-Platforms an. Es gibt keine "Audience"-Daten. |
| Seiteninhalt | Wir lesen kein DOM, keine Formularwerte, keine Scroll-Positionen, kein Session-Replay. Es gibt keine Aufzeichnung. Die einzige Ausnahme ist das Opt-in pagetype_ruleset, das einen einzelnen Body-Controller-Klassen-Token zur Page-Type-Einordnung liest; standardmäßig aus. |
| Query-Parameter-Werte und URL-Fragmente | Die URL wird im Tracker auf Origin + Pfad gekürzt. Das #…-Fragment wird immer verworfen, und Query-Werte werden verworfen. /orders/checkout?email=jane@x.com kommt unter dem Default-Preset Standard als /orders/checkout?email an (der Name email bleibt via collect_query_keys, der Wert wird gestrippt), oder als /orders/checkout bei Minimal. Ein Wert bleibt nur für Schlüssel, die du explizit in collect_query_values_for allow-listest. |
| Personenbezogene Daten | Nichts, was der Besucher tippt, klickt oder im Browser hat, wird erfasst. |
Zu Cookies und Storage
fastmon setzt überhaupt keine Cookies, in keiner Konfiguration. Das Einzige, was der Tracker auf das Gerät des Besuchers schreiben kann, ist ein einzelner sessionStorage-Eintrag (_fms), die Session-ID, und das nur, wenn collect_sessions an ist. Per Default schreibt er nichts: das Standard-Preset, mit dem neue Sites starten, speichert keine Session-ID, also keine Cookies, kein localStorage, kein sessionStorage, kein IndexedDB, keine Cache API.
Speicherfrei bezieht sich darauf, was auf dem Gerät liegt. Das Auslesen der Performance-APIs ist nach unserer Einschätzung kein Zugriff auf gespeicherte Informationen im Sinne des TDDDG, weil die Werte erst zur Laufzeit entstehen; eine strengere Lesart sieht das anders. Siehe Consent und TDDDG.
Wenn collect_sessions an ist, entscheidet der Schalter session_consent, ob die Session-ID beim Pageload geschrieben oder aufgeschoben wird, bis dein CMP Consent erteilt. Die ID liegt im sessionStorage und verschwindet beim Schließen des Tabs. Es gibt nirgends im Design einen persistenten Identifier oder ein seitenübergreifendes Cookie.
Was wir sammeln
Genau das, was wir brauchen, um Web Vitals und Performance pro Seite auszurechnen. Die genaue Liste Feld für Feld steht unter Der RUM-Beacon; die Kategorien:
- Seiten-URL: Origin + Pathname, dazu die Query-Parameter-Namen, wenn
collect_query_keysan ist (das Default-Preset Standard). Hash-Fragment und Query-Werte werden im Tracker verworfen; ein Wert bleibt nur für Schlüssel, die du allow-listest (collect_query_values_for). - Referrer: im Tracker auf Origin + Pathname gekürzt (Query und Hash verworfen), serverseitig in eine Quelle und ein Medium klassifiziert. Der Rohwert wird vor jedem Logging-Pfad verworfen und persistiert nie, in keinem Modus.
- Web Vitals: LCP, INP, CLS, FCP, TTFB und verwandte Timings.
- Navigation-Timing: Nav-Typ, TTFB, Pageload-Timing.
- Resource-Timing: pro Kategorie aggregierte Byte-Größen und Counts (Script, CSS, Image, Font, Sonstige).
- Server-Timing: die Metriken, die dein eigenes Backend an seine Response anhängt (Phasen-Dauern, Cache-Status, Seitentyp, Origin-Host). Server-Selbstmessung, keine Besucherdaten; Namen und Werte werden beim Ingest formgeprüft, gegen eine Denylist geführt und von allem ID-Förmigen befreit. Das eine besuchernahe Feld ist das optionale Logged-in-Flag (
fm-loggedin): ein einzelnesyes/noüber den Render-Modus, nur vorhanden, wenn dein Server es sendet, und nie ein Identifikator. Siehe Server-Timing-Header. - Fehler: Typ und Count immer. Die Fehler-Message zu behalten, ist Opt-in (
collect_error_messages) und läuft auch dann durch einen immer aktiven Scrubber, der URLs, E-Mail-Adressen, numerische IDs und Strings in Anführungszeichen vor dem Versand durch*maskiert. Stack-Frame-Detail ist Opt-in (collect_error_frames); aus fallen Frames auf host-only zusammen, außer deinen eigenen First-Party-External-Scripts, die immer Pfad und Zeile/Spalte behalten, damit ein Bug im eigenen Code lokalisierbar bleibt. Diese Position ist für jeden betroffenen Besucher identisch: sie identifiziert den Fehler, nicht die Person. - Umgebung: Browser-Familie, OS-Familie, Device-Klasse (
mobile/tablet/desktop), Viewport-Klasse, effektiver Connection-Typ, Netzwerk-RTT- und Downlink-Schätzungen. Die Netzwerkwerte sind Echtzeit-Messungen, die der Browser beim Lesen berechnet, kein gespeicherter Geräte- oder OS-Zustand.navigator.deviceMemory,navigator.hardwareConcurrency, dassaveData-Flag,prefers-color-schemeundprefers-reduced-motionlesen wir gar nicht. - Geo: nur Land (zweistelliges ISO). Wird am Edge aus der IP abgeleitet und als Request-Header weitergereicht; die IP selbst erreicht die Anwendung nie.
- Bot- und Rechenzentrums-Labels: drei am Edge abgeleitete Labels, die Netzwerk und Software des Clients beschreiben, nicht den Besucher: einen Cloud-/Hosting-Provider (etwa
awsoderhetzner), einen benannten Crawler (etwagooglebotodergptbot) und dessen Kategorie (etwasearch-engineoderai-crawler). Alle drei werden am Edge aus IP und User-Agent abgeleitet, bevor beide verworfen werden, stammen aus einer festen, geschlossenen Liste und werden auf einen kurzen Slug bereinigt; keine rohe IP und kein roher User-Agent bleiben. Siehe Bot- und Rechenzentrums-Labels. - Kampagnen-Attribution:
utm_source/utm_medium/utm_campaign/utm_term/utm_contentund ein Ad-Plattform-Labelclick_id_param(z. B."gclid"), aus der Seiten-URL extrahiert. Jedes Feld auf 64 Zeichen begrenzt. Der Click-ID-Wert (Cj0KCQabc...) wird bewusst verworfen; nur das Label, welche Plattform den Klick geschickt hat, wird gespeichert. Das sind vom Marketer auf den eigenen Outbound-URLs gesetzte Tags, keine Besucher-abgeleiteten Daten. - LCP-Image-URL, LoAF-Script-Pfade, Third-Party-Domain-Map: in jeder Konfiguration erfasst, bei der Erfassung auf Origin + Pathname reduziert. Sie beschreiben die Seitenzusammensetzung des Kunden (siehe Site-Metadaten vs. Besucherdaten), nicht den Besucher.
- Fetch/XHR-Aggregate: Opt-in (
collect_fetch_xhr). Aufruf-Counts, Dauern und Fehlercodes pro Endpunkt für deine eigenen APIs. Pfade werden strenger als Seiten-URLs bereinigt (Query, Fragment und ID-artige Segmente entfernt). - Checkout-Stufe und Warenkorb-Interaktion: zwei serverseitig abgeleitete Labels, beim Ingest aus Werten berechnet, die schon auf dem Beacon stehen. Die Stufe (
cart,checkout,successoder leer) entsteht durch Abgleich der bereinigten Seiten-URL mit URL-Mustern; der Warenkorb-Merker aus einem Fetch/XHR-POSTan einen bekannten Warenkorb-Endpunkt. Keines von beiden fügt dem Beacon ein Feld hinzu oder liest etwas, das deine Einstellungen nicht schon erlaubt haben, und pro Besucher wird nichts gespeichert: Der Funnel wird zur Abfragezeit berechnet. Standardmäßig an, mit Opt-out (checkout_tracking). Siehe Checkout-Funnel. - Session-ID: nur wenn
collect_sessionsan ist (das Preset Full, oder nachdem dein CMPgrantConsent()aufruft). Liegt imsessionStorage, gruppiert Pageviews einer Session, stirbt mit dem Tab.
Mehr schickt der Beacon nicht. Es gibt auch keinen Opt-In, mit dem du irgendwo „noch ein bisschen mehr" freischaltest. Das Mehr haben wir gar nicht gebaut.
Bot- und Rechenzentrums-Labels
Jedes Beacon wird am Edge als Bot-, Crawler- oder Rechenzentrums-Traffic markiert, damit es sich von echten Besucherdaten trennen lässt. Drei unabhängige Prüfungen laufen am Edge, die ersten beiden gegen eine feste, kuratierte Liste, kein offenes Nachschlagen:
- Cloud-/Hosting-Provider, gesetzt, wenn die Client-IP in einem bekannten Rechenzentrums-Bereich liegt: einer von
aws,azure,googlecloud,oracle,digitalocean,hetzner,ovhcloud,linode,vultr,alibaba,tencent. - Crawler, gesetzt, wenn der User-Agent zu einem bekannten Bot passt: ein Name (
googlebot,bingbot,gptbot,applebot,duckduckbot,amazonbot,perplexitybot,yandex,baidu,metaoderunknownfür eine generische Bot-Heuristik) plus eine Kategorie wiesearch-engine,ai-crawler,seoodermonitoring. - User-Agent-Anomalie, gesetzt, wenn der User-Agent den Low-Entropy Client Hints des Browsers (
sec-ch-ua,sec-ch-ua-platform) widerspricht:headless,spoofedodernon-browser. Die Hints werden am Edge ausgewertet und mit dem Rest des rohen Requests verworfen; gespeichert wird nur das Verdikt.
Der am Edge abgeleitete stitch-Identifier
Für Unique-Visitor-Zahlen und per-Besucher-Performance-Debugging, ohne dass etwas auf dem Gerät liegt, kann der Edge einen kurzlebigen Join-Key unter einem rotierenden Salt berechnen, bevor IP und User-Agent zerstört werden:
stitch = HMAC-SHA256(rotierendes_Salt, IP | User-Agent | collector_hash | domain)abgeschnitten auf 128 Bit (32 Hex-Zeichen auf dem Wire). Er wird gespeichert, wann immer store_stitch an ist, was das Default-Preset Standard einschließt; das Preset Minimal ist das Opt-down, das die Zeile ganz ohne Besucher-Identifier lässt. Eigenschaften, wenn er an ist:
- Forward Secrecy by Construction. Das Salt ist ein 32-Byte-Wert aus
crypto/rand, lebt ausschließlich im RAM des aktiven Edge und rotiert alle 24 Stunden. Es wird nie persistiert, nie verteilt, nie geloggt. Wer später Zugriff auf die Zeile bekommt, kannstitchnicht zurück auf (IP, UA) rechnen: das Salt, mit dem es produziert wurde, ist weg. - Verknüpfbarkeit gedeckelt, höchstens ~24 h. Bei jeder Salt-Rotation bekommt derselbe Besucher einen neuen
stitch-Wert. Cross-Pageview-Verknüpfung kann nicht über ein Salt-Fenster hinaus anwachsen. - Pro Domain, nie Cross-Site. Sowohl
collector_hashals auch die Seiten-domainstecken im HMAC-Input, also liefert dieselbe (IP, UA) auf jeder Domain einen anderenstitch, auch über die Domains hinweg, die eine einzelne Application bedient. Nichts verknüpft einen Besucher über Domains oder Sites hinweg; die „keine Cross-Site-Identifier"-Zeile oben gilt unverändert. - Das Salt ist das einzige Geheimnis. Die übrigen HMAC-Inputs sind öffentlich oder stehen in der gespeicherten Zeile selbst, und der Eingaberaum ist klein genug zum Durchprobieren; wer das lebende Salt hätte, könnte ein vermutetes (IP, UA)-Paar durch Nachrechnen bestätigen. Niemand hat es: es existiert nur im laufenden Edge-Prozess und ist nach der Rotation weg. Die Garantie ist operativ (RAM-only-Salt, 24-h-Rotation), nicht mathematisch.
Ehrlich eingeordnet: solange das Salt lebt, ist stitch ein pseudonymer Besucher-Identifier und damit personenbezogenes Datum, verarbeitet nach Art. 6 Abs. 1 lit. f DSGVO mit dokumentierter Interessenabwägung. Weil er unter dem Default-Preset Standard an ist, benenne ihn in deiner Datenschutzerklärung. Wenn du lieber gar keinen Besucher-Identifier speicherst, hält store_stitch aus (das Preset Minimal) die Zeile echt anonym.
Identifier abschalten, oder aus lassen
Zwei Schalter pro Site entscheiden, ob überhaupt ein Besucher-Identifier in die Speicherung gelangt. Unter dem Default-Preset Standard ist store_stitch an und collect_sessions aus; das Preset Minimal schaltet beide aus.
store_stitch. An speichert den am Edge abgeleitetenstitchfür Unique-Visitor-Zahlen und besucherbezogene Metriken (Bounce-Rate, Seiten pro Besuch, Verweildauer). Aus lässt eine Zeile ganz ohne Besucher-Identifier zurück, vollständig anonym. Alle Per-Pageview-Signale (Web Vitals, Fehler, Third-Party, Attribution) bleiben so oder so unberührt.collect_sessions. An schreibt die tab-gebundenesessionStorage-Session-ID für seitenübergreifende Journeys und Funnels. Aus fasst das ausgelieferte BundlesessionStoragegar nicht erst an: der Schreibvorgang auf dem Gerät entfällt, er wird nicht bloß serverseitig verworfen.
Die beiden sind unabhängig: schalte einen an, beide oder keinen.
Site-Metadaten vs. Besucherdaten
Eine Handvoll Felder beschreibt die Site des Kunden, nicht den Besucher: welche Third-Party-Domains die Seite lädt, der Byte-Mix nach Script / Image / Font, die Origin des LCP-Bilds, die LoAF-Script-Pfade. Diese Werte sind über alle Besucher derselben Seite identisch. Sie sagen dir, welches deiner CDNs langsam ist; sie identifizieren niemanden.
Das macht sie zu Site-Konfiguration, nicht zu Besucherdaten. Wir behandeln sie trotzdem sorgfältig (Script-URLs und LCP-Image-URLs werden bei der Erfassung auf Origin + Pathname reduziert), aber sie sind nicht das, worum es bei den Consent- und Verknüpfbarkeits-Reglern geht.
Personenbezogene Daten: was ausgeschlossen ist, und was nicht
- Keine personenbezogenen Daten, in jeder Konfiguration. Web Vitals und alle Timings, Resource-/LoAF-/Third-Party-Metadaten, Device-/Connection-/Viewport-Buckets, der zweistellige Ländercode sowie Fehlertyp + Count. Keine IP, kein roher User-Agent, kein Fingerprint wird je gespeichert. Auf dem Preset Minimal trägt die gespeicherte Zeile gar keinen Besucher-Identifier.
- Nicht vollständig auszuschließen; wir minimieren, der Rest liegt bei dir. Der am Edge abgeleitete
stitch(unter dem Preset Standard an) ist konstruktionsbedingt pseudonymes personenbezogenes Datum. URL- und Fetch/XHR-Pfade werden bereinigt (Query, Fragment und Werte gestrippt), aber ein Segment, das du aus personenbezogenen Daten baust (/orders/jane-doe), übersteht das. Fehler-Messages (collect_error_messages) laufen durch einen Scrubber, der gemusterte PII maskiert, aber nicht jeden Freitext-Leak fängt. Und alles, was du aktiv einschaltest: ein allow-gelistetercollect_query_values_for-Wert oder diecollect_sessions-ID. Für diese Fälle greifen deine Pflichten unten.
Was deine Einstellungen ändern
Die Tracker-Einstellungen der Site entscheiden über Verknüpfbarkeit und Content-Tiefe, nicht über die Privacy-Untergrenze. Die Untergrenze oben (keine IP-Speicherung, kein roher User-Agent, keine Fingerprints, keine Cookies) gilt in jeder Konfiguration. Was die Einstellungen bewegen: ob Session-ID, Fehler-Message, Fehler-Frame-Detail, Query-Keys oder Fetch/XHR-Telemetrie vorhanden sind und ob der Edge-stitch gespeichert wird. Die Aufschlüsselung pro Einstellung steht unter Tracker-Einstellungen, die drei Ausgangspunkte unter Presets.
Consent und TDDDG
Ob das Einbinden von fastmon eine Einwilligung erfordert, wer verantwortlich ist und die zwei Auslegungen sind vollständig unter Tracker-Einstellungen → Consent und TDDDG beschrieben.
Wo die Daten liegen
- Nur EU, keine US-Jurisdiktion. Alle Daten werden ausschließlich in der EU verarbeitet und gespeichert, auf in Deutschland betriebener Infrastruktur. Jeder Anbieter im Datenpfad ist ein deutsches oder EU-Unternehmen: kein Cloudflare, kein AWS, kein GCP, kein Vercel, kein US-eigener Subprozessor.
- Verantwortlich. Verarbeitet wird von fastmon, der Firma hinter dem Produkt. Im AVV stehen alle Sub-Auftragsverarbeiter, den schicken wir auf Anfrage.
- Retention. Per Default 90 Tage. Pro Site einstellbar (
data_retention_days). Was abläuft, wird weggeworfen, nicht archiviert.
Kein US-CLOUD-Act-Zugriff
Weil weder fastmon noch ein Subprozessor unter US-Recht fällt, hat der US CLOUD Act keinen Zugriff auf deine RUM-Daten.
Vergleich
Wenn du von einem US-Analytics-Produkt umsteigst, hier das relevante Delta:
| Fähigkeit | fastmon | Typischer US-RUM-Anbieter |
|---|---|---|
| Gesetzte Cookies | 0 | 1-N (Analytics + Ad-Partner) |
| IP gespeichert | Nein | Oft, manchmal trunkiert |
| Cross-Site-Identity-Graph | Nein | Oft, via SDK oder Pixel-Netz |
| Session-Replay / DOM-Dump | Nein | Häufig als Opt-In |
| Datenpfad ausschließlich EU | Ja | Selten |
| Daten verlassen die EU | Nein | Oft (US CLOUD Act) |
Deine Verantwortung
Der Tracker garantiert die Wire-Form. Zwei Dinge bleiben bei dir:
- Keine PII in URL-Pfaden. Query-Strings und Hash-Fragmente werden entfernt, der Pathname bleibt erhalten.
/orders/jane.doe@x.comwürde die E-Mail in unsere Pipeline tragen. Nutze opake IDs (UUIDs, numerische DB-IDs) oder bring PII in Query-Parameter, die ohnehin gestrippt werden. - Keine PII in UTM-Parametern. UTM-Tags und Click-ID-Labels landen wortwörtlich aus den Outbound-URLs der Marketer in der Datenbank. Pack da keine Besucher-PII rein. Bau Kampagnen-URLs niemals als
?utm_term=jane@example.com&utm_content=user-12345für Per-Empfänger-Tracking. Jedes Feld wird serverseitig auf 64 Zeichen gedeckelt, der Wert läuft aber nicht durch den Scrubber. Ad-Plattform-Click-ID-Werte verwirft der Tracker selbst, damit greift das Per-Empfänger-Join-Risiko nur bei den UTM-Feldern. - Kein roher User-Input in
throw. Der immer aktive Scrubber fängt gemusterte PII (URLs, E-Mails, IDs), aber freier Text (Namen, eigene Bezeichner) kann durchrutschen. Typisiere den Fehler:throw new EmailDeliveryError({ code: "..." })stattthrow new Error("Failed to send to " + email). Greift nur, wenncollect_error_messagesan ist; sonst wird die Message ohnehin komplett verworfen.
Was das für dich heißt
- Zwei Fragen, getrennt zu prüfen. Nach § 25 TDDDG hängt es am Preset: Minimal und Standard schreiben nichts auf das Gerät, Full schreibt eine Session-ID und braucht dafür eine Einwilligung. Nach DSGVO ist die Rechtsgrundlage die Interessenabwägung nach Art. 6 Abs. 1 lit. f, weil über den HTTP-Header eine IP-Adresse im Spiel ist. Die Bewertung für deinen Einsatz bleibt deine (siehe Consent und TDDDG).
- Deine Daten verlassen die EU nie. Es gibt gar keinen US-Transfer, über den man nachdenken müsste.
- Deinem Team kannst du eine Ein-Seiter-Antwort geben: Link auf diese Seite plus unseren AVV, fertig.
- Explizites Opt-In vor jeder Session-Verknüpfung? Schalte
collect_sessionsan und lasssession_consentaufdeferred, sodass die Session-ID erst geschrieben wird, nachdem dein CMPgrantConsent()aufruft.
Nächste Schritte
- Tracker-Einstellungen und Presets ansehen.
- Technische Details zum Beacon.
- AVV gewünscht? Mail an support@fastmon.eu.