[{"data":1,"prerenderedAt":2944},["ShallowReactive",2],{"article-alternates":3,"article-\u002Fen\u002Fdata\u002Fprivacy-first-analytics-plausible-server-side":13},{"i18nKey":4,"paths":5},"data-006-2026-07",{"de":6,"en":7,"es":8,"fr":9,"it":10,"ru":11,"tr":12},"\u002Fde\u002Fdata\u002Fprivacy-first-analytics-plausible-server-side","\u002Fen\u002Fdata\u002Fprivacy-first-analytics-plausible-server-side-aggregation","\u002Fes\u002Fdata\u002Fprivacidad-first-analytics-plausible-agregacion-servidor","\u002Ffr\u002Fdata\u002Fprivacy-first-analytics-plausible-server-side-aggregation","\u002Fit\u002Fdata\u002Fanalytics-privacy-first-plausible-aggregazione-lato-server","\u002Fru\u002Fdata\u002Fprivacy-first-analytics-plausible-serverside-aggregation","\u002Ftr\u002Fdata\u002Fprivacy-first-analytics-plausible-ve-sunucu-tarafi-aggregation",{"_path":14,"_dir":15,"_draft":16,"_partial":16,"_locale":17,"title":18,"description":19,"publishedAt":20,"modifiedAt":20,"category":21,"i18nKey":4,"tags":22,"readingTime":28,"author":29,"body":30,"_type":2938,"_id":2939,"_source":2940,"_file":2941,"_stem":2942,"_extension":2943},"\u002Fen\u002Fdata\u002Fprivacy-first-analytics-plausible-server-side","data",false,"","Privacy-First Analytics: Plausible and Server-Side Aggregation","Cookieless tracking, GDPR\u002FKVKK compliance, and GA4 alternative: rebuilding user measurement with Plausible + server-side aggregation architecture.","2026-07-26","verianalizi",[23,24,25,26,27],"privacy-first-analytics","plausible","cookieless-tracking","gdpr-compliance","server-side-aggregation",9,"Roibase",{"type":31,"children":32,"toc":2929},"root",[33,41,48,53,58,63,69,74,83,593,614,624,868,873,879,890,903,949,961,1437,1470,1725,1730,1736,1744,1769,1777,1800,1808,1831,1839,1857,1865,1888,1893,1899,1911,1924,2175,2191,2197,2210,2215,2358,2363,2431,2444,2449,2455,2460,2909,2914,2918,2923],{"type":34,"tag":35,"props":36,"children":37},"element","p",{},[38],{"type":39,"value":40},"text","GA4's mid-2024 announcement of \"360-day user ID storage limits\" and Consent Mode v2's March 2024 mandatory rollout left marketing teams facing two scenarios: either watch cookie banner consent rates drop to 40% and lose the segmentation infrastructure built since UA, or architect a new measurement stack that works without cookies. Combining privacy-first analytics tools like Plausible with server-side aggregation has become the technical solution to this problem.",{"type":34,"tag":42,"props":43,"children":45},"h2",{"id":44},"cookie-blocking-exceeded-60",[46],{"type":39,"value":47},"Cookie Blocking Exceeded 60%",{"type":34,"tag":35,"props":49,"children":50},{},[51],{"type":39,"value":52},"Apple's Intelligent Tracking Prevention (ITP) has blocked third-party cookies in Safari since 2017; Chrome made Privacy Sandbox default in Q4 2024; Firefox has Tracking Protection on by default. According to Mozilla's 2025 report, the average European user clicks \"Reject\" on cookie banners or dismisses them 62% of the time. In GA4 properties, sessions marked consent_status=denied have settled into the 55-65% band starting Q4 2024 on B2C sites.",{"type":34,"tag":35,"props":54,"children":55},{},[56],{"type":39,"value":57},"This means classic client-side pixels (gtag.js, fbq) are losing over half their traffic. GA4's \"modeled conversion\" feature attempts to fill this gap—but modeled data means deriving audience segments from regression predictions instead of actual events. In incrementality tests, modeled conversion sets show an average 18-22% deviation versus real conversions (Google Marketing Platform 2025 beta documentation).",{"type":34,"tag":35,"props":59,"children":60},{},[61],{"type":39,"value":62},"Cookieless tracking rests on two architectures: one collects events entirely server-side (server-side GTM, Segment, RudderStack); the other generates temporary identifiers via sessionStorage\u002FlocalStorage client-side instead of cookies and forwards them to the server. Plausible Analytics uses the second approach, but identity isn't persistent—each session gets a new hash. On first glance it seems you can't track user journeys; in reality, cohort analysis and retention measurement become possible at the aggregation layer.",{"type":34,"tag":42,"props":64,"children":66},{"id":65},"plausible-architecture-beacon-post-and-event-stream",[67],{"type":39,"value":68},"Plausible Architecture: Beacon POST and Event Stream",{"type":34,"tag":35,"props":70,"children":71},{},[72],{"type":39,"value":73},"Plausible is open-source, MIT-licensed web analytics (plausible.io). Script size is 1.4 KB (GA4 is 43 KB, Segment is 28 KB); it doesn't write cookies; GDPR\u002FKVKK\u002FCCPA compliance is default. Here's how it works:",{"type":34,"tag":35,"props":75,"children":76},{},[77],{"type":34,"tag":78,"props":79,"children":80},"strong",{},[81],{"type":39,"value":82},"Client script:",{"type":34,"tag":84,"props":85,"children":89},"pre",{"className":86,"code":87,"language":88,"meta":17,"style":17},"language-javascript shiki shiki-themes github-dark","\u002F\u002F plausible.js minimal implementation\n(function(){\n  const endpoint = 'https:\u002F\u002Fanalytics.example.com\u002Fapi\u002Fevent';\n  const sessionHash = btoa(navigator.userAgent + performance.timing.navigationStart).substring(0,16);\n  \n  function sendEvent(name, props = {}) {\n    navigator.sendBeacon(endpoint, JSON.stringify({\n      n: name,              \u002F\u002F event name\n      u: location.href,     \u002F\u002F page URL\n      d: document.domain,\n      r: document.referrer,\n      w: window.innerWidth,\n      h: sessionHash,       \u002F\u002F temporary session identifier\n      p: props              \u002F\u002F custom properties\n    }));\n  }\n  \n  sendEvent('pageview');\n  \n  \u002F\u002F click tracking\n  document.addEventListener('click', (e) => {\n    if (e.target.matches('[data-track]')) {\n      sendEvent('click', { element: e.target.dataset.track });\n    }\n  });\n})();\n","javascript",[90],{"type":34,"tag":91,"props":92,"children":93},"code",{"__ignoreMap":17},[94,106,127,158,225,234,277,316,330,343,352,361,370,384,398,407,416,424,446,454,463,511,544,566,575,584],{"type":34,"tag":95,"props":96,"children":99},"span",{"class":97,"line":98},"line",1,[100],{"type":34,"tag":95,"props":101,"children":103},{"style":102},"--shiki-default:#6A737D",[104],{"type":39,"value":105},"\u002F\u002F plausible.js minimal implementation\n",{"type":34,"tag":95,"props":107,"children":109},{"class":97,"line":108},2,[110,116,122],{"type":34,"tag":95,"props":111,"children":113},{"style":112},"--shiki-default:#E1E4E8",[114],{"type":39,"value":115},"(",{"type":34,"tag":95,"props":117,"children":119},{"style":118},"--shiki-default:#F97583",[120],{"type":39,"value":121},"function",{"type":34,"tag":95,"props":123,"children":124},{"style":112},[125],{"type":39,"value":126},"(){\n",{"type":34,"tag":95,"props":128,"children":130},{"class":97,"line":129},3,[131,136,142,147,153],{"type":34,"tag":95,"props":132,"children":133},{"style":118},[134],{"type":39,"value":135},"  const",{"type":34,"tag":95,"props":137,"children":139},{"style":138},"--shiki-default:#79B8FF",[140],{"type":39,"value":141}," endpoint",{"type":34,"tag":95,"props":143,"children":144},{"style":118},[145],{"type":39,"value":146}," =",{"type":34,"tag":95,"props":148,"children":150},{"style":149},"--shiki-default:#9ECBFF",[151],{"type":39,"value":152}," 'https:\u002F\u002Fanalytics.example.com\u002Fapi\u002Fevent'",{"type":34,"tag":95,"props":154,"children":155},{"style":112},[156],{"type":39,"value":157},";\n",{"type":34,"tag":95,"props":159,"children":161},{"class":97,"line":160},4,[162,166,171,175,181,186,191,196,201,205,210,215,220],{"type":34,"tag":95,"props":163,"children":164},{"style":118},[165],{"type":39,"value":135},{"type":34,"tag":95,"props":167,"children":168},{"style":138},[169],{"type":39,"value":170}," sessionHash",{"type":34,"tag":95,"props":172,"children":173},{"style":118},[174],{"type":39,"value":146},{"type":34,"tag":95,"props":176,"children":178},{"style":177},"--shiki-default:#B392F0",[179],{"type":39,"value":180}," btoa",{"type":34,"tag":95,"props":182,"children":183},{"style":112},[184],{"type":39,"value":185},"(navigator.userAgent ",{"type":34,"tag":95,"props":187,"children":188},{"style":118},[189],{"type":39,"value":190},"+",{"type":34,"tag":95,"props":192,"children":193},{"style":112},[194],{"type":39,"value":195}," performance.timing.navigationStart).",{"type":34,"tag":95,"props":197,"children":198},{"style":177},[199],{"type":39,"value":200},"substring",{"type":34,"tag":95,"props":202,"children":203},{"style":112},[204],{"type":39,"value":115},{"type":34,"tag":95,"props":206,"children":207},{"style":138},[208],{"type":39,"value":209},"0",{"type":34,"tag":95,"props":211,"children":212},{"style":112},[213],{"type":39,"value":214},",",{"type":34,"tag":95,"props":216,"children":217},{"style":138},[218],{"type":39,"value":219},"16",{"type":34,"tag":95,"props":221,"children":222},{"style":112},[223],{"type":39,"value":224},");\n",{"type":34,"tag":95,"props":226,"children":228},{"class":97,"line":227},5,[229],{"type":34,"tag":95,"props":230,"children":231},{"style":112},[232],{"type":39,"value":233},"  \n",{"type":34,"tag":95,"props":235,"children":237},{"class":97,"line":236},6,[238,243,248,252,258,263,268,272],{"type":34,"tag":95,"props":239,"children":240},{"style":118},[241],{"type":39,"value":242},"  function",{"type":34,"tag":95,"props":244,"children":245},{"style":177},[246],{"type":39,"value":247}," sendEvent",{"type":34,"tag":95,"props":249,"children":250},{"style":112},[251],{"type":39,"value":115},{"type":34,"tag":95,"props":253,"children":255},{"style":254},"--shiki-default:#FFAB70",[256],{"type":39,"value":257},"name",{"type":34,"tag":95,"props":259,"children":260},{"style":112},[261],{"type":39,"value":262},", ",{"type":34,"tag":95,"props":264,"children":265},{"style":254},[266],{"type":39,"value":267},"props",{"type":34,"tag":95,"props":269,"children":270},{"style":118},[271],{"type":39,"value":146},{"type":34,"tag":95,"props":273,"children":274},{"style":112},[275],{"type":39,"value":276}," {}) {\n",{"type":34,"tag":95,"props":278,"children":280},{"class":97,"line":279},7,[281,286,291,296,301,306,311],{"type":34,"tag":95,"props":282,"children":283},{"style":112},[284],{"type":39,"value":285},"    navigator.",{"type":34,"tag":95,"props":287,"children":288},{"style":177},[289],{"type":39,"value":290},"sendBeacon",{"type":34,"tag":95,"props":292,"children":293},{"style":112},[294],{"type":39,"value":295},"(endpoint, ",{"type":34,"tag":95,"props":297,"children":298},{"style":138},[299],{"type":39,"value":300},"JSON",{"type":34,"tag":95,"props":302,"children":303},{"style":112},[304],{"type":39,"value":305},".",{"type":34,"tag":95,"props":307,"children":308},{"style":177},[309],{"type":39,"value":310},"stringify",{"type":34,"tag":95,"props":312,"children":313},{"style":112},[314],{"type":39,"value":315},"({\n",{"type":34,"tag":95,"props":317,"children":319},{"class":97,"line":318},8,[320,325],{"type":34,"tag":95,"props":321,"children":322},{"style":112},[323],{"type":39,"value":324},"      n: name,              ",{"type":34,"tag":95,"props":326,"children":327},{"style":102},[328],{"type":39,"value":329},"\u002F\u002F event name\n",{"type":34,"tag":95,"props":331,"children":332},{"class":97,"line":28},[333,338],{"type":34,"tag":95,"props":334,"children":335},{"style":112},[336],{"type":39,"value":337},"      u: location.href,     ",{"type":34,"tag":95,"props":339,"children":340},{"style":102},[341],{"type":39,"value":342},"\u002F\u002F page URL\n",{"type":34,"tag":95,"props":344,"children":346},{"class":97,"line":345},10,[347],{"type":34,"tag":95,"props":348,"children":349},{"style":112},[350],{"type":39,"value":351},"      d: document.domain,\n",{"type":34,"tag":95,"props":353,"children":355},{"class":97,"line":354},11,[356],{"type":34,"tag":95,"props":357,"children":358},{"style":112},[359],{"type":39,"value":360},"      r: document.referrer,\n",{"type":34,"tag":95,"props":362,"children":364},{"class":97,"line":363},12,[365],{"type":34,"tag":95,"props":366,"children":367},{"style":112},[368],{"type":39,"value":369},"      w: window.innerWidth,\n",{"type":34,"tag":95,"props":371,"children":373},{"class":97,"line":372},13,[374,379],{"type":34,"tag":95,"props":375,"children":376},{"style":112},[377],{"type":39,"value":378},"      h: sessionHash,       ",{"type":34,"tag":95,"props":380,"children":381},{"style":102},[382],{"type":39,"value":383},"\u002F\u002F temporary session identifier\n",{"type":34,"tag":95,"props":385,"children":387},{"class":97,"line":386},14,[388,393],{"type":34,"tag":95,"props":389,"children":390},{"style":112},[391],{"type":39,"value":392},"      p: props              ",{"type":34,"tag":95,"props":394,"children":395},{"style":102},[396],{"type":39,"value":397},"\u002F\u002F custom properties\n",{"type":34,"tag":95,"props":399,"children":401},{"class":97,"line":400},15,[402],{"type":34,"tag":95,"props":403,"children":404},{"style":112},[405],{"type":39,"value":406},"    }));\n",{"type":34,"tag":95,"props":408,"children":410},{"class":97,"line":409},16,[411],{"type":34,"tag":95,"props":412,"children":413},{"style":112},[414],{"type":39,"value":415},"  }\n",{"type":34,"tag":95,"props":417,"children":419},{"class":97,"line":418},17,[420],{"type":34,"tag":95,"props":421,"children":422},{"style":112},[423],{"type":39,"value":233},{"type":34,"tag":95,"props":425,"children":427},{"class":97,"line":426},18,[428,433,437,442],{"type":34,"tag":95,"props":429,"children":430},{"style":177},[431],{"type":39,"value":432},"  sendEvent",{"type":34,"tag":95,"props":434,"children":435},{"style":112},[436],{"type":39,"value":115},{"type":34,"tag":95,"props":438,"children":439},{"style":149},[440],{"type":39,"value":441},"'pageview'",{"type":34,"tag":95,"props":443,"children":444},{"style":112},[445],{"type":39,"value":224},{"type":34,"tag":95,"props":447,"children":449},{"class":97,"line":448},19,[450],{"type":34,"tag":95,"props":451,"children":452},{"style":112},[453],{"type":39,"value":233},{"type":34,"tag":95,"props":455,"children":457},{"class":97,"line":456},20,[458],{"type":34,"tag":95,"props":459,"children":460},{"style":102},[461],{"type":39,"value":462},"  \u002F\u002F click tracking\n",{"type":34,"tag":95,"props":464,"children":466},{"class":97,"line":465},21,[467,472,477,481,486,491,496,501,506],{"type":34,"tag":95,"props":468,"children":469},{"style":112},[470],{"type":39,"value":471},"  document.",{"type":34,"tag":95,"props":473,"children":474},{"style":177},[475],{"type":39,"value":476},"addEventListener",{"type":34,"tag":95,"props":478,"children":479},{"style":112},[480],{"type":39,"value":115},{"type":34,"tag":95,"props":482,"children":483},{"style":149},[484],{"type":39,"value":485},"'click'",{"type":34,"tag":95,"props":487,"children":488},{"style":112},[489],{"type":39,"value":490},", (",{"type":34,"tag":95,"props":492,"children":493},{"style":254},[494],{"type":39,"value":495},"e",{"type":34,"tag":95,"props":497,"children":498},{"style":112},[499],{"type":39,"value":500},") ",{"type":34,"tag":95,"props":502,"children":503},{"style":118},[504],{"type":39,"value":505},"=>",{"type":34,"tag":95,"props":507,"children":508},{"style":112},[509],{"type":39,"value":510}," {\n",{"type":34,"tag":95,"props":512,"children":514},{"class":97,"line":513},22,[515,520,525,530,534,539],{"type":34,"tag":95,"props":516,"children":517},{"style":118},[518],{"type":39,"value":519},"    if",{"type":34,"tag":95,"props":521,"children":522},{"style":112},[523],{"type":39,"value":524}," (e.target.",{"type":34,"tag":95,"props":526,"children":527},{"style":177},[528],{"type":39,"value":529},"matches",{"type":34,"tag":95,"props":531,"children":532},{"style":112},[533],{"type":39,"value":115},{"type":34,"tag":95,"props":535,"children":536},{"style":149},[537],{"type":39,"value":538},"'[data-track]'",{"type":34,"tag":95,"props":540,"children":541},{"style":112},[542],{"type":39,"value":543},")) {\n",{"type":34,"tag":95,"props":545,"children":547},{"class":97,"line":546},23,[548,553,557,561],{"type":34,"tag":95,"props":549,"children":550},{"style":177},[551],{"type":39,"value":552},"      sendEvent",{"type":34,"tag":95,"props":554,"children":555},{"style":112},[556],{"type":39,"value":115},{"type":34,"tag":95,"props":558,"children":559},{"style":149},[560],{"type":39,"value":485},{"type":34,"tag":95,"props":562,"children":563},{"style":112},[564],{"type":39,"value":565},", { element: e.target.dataset.track });\n",{"type":34,"tag":95,"props":567,"children":569},{"class":97,"line":568},24,[570],{"type":34,"tag":95,"props":571,"children":572},{"style":112},[573],{"type":39,"value":574},"    }\n",{"type":34,"tag":95,"props":576,"children":578},{"class":97,"line":577},25,[579],{"type":34,"tag":95,"props":580,"children":581},{"style":112},[582],{"type":39,"value":583},"  });\n",{"type":34,"tag":95,"props":585,"children":587},{"class":97,"line":586},26,[588],{"type":34,"tag":95,"props":589,"children":590},{"style":112},[591],{"type":39,"value":592},"})();\n",{"type":34,"tag":35,"props":594,"children":595},{},[596,598,604,606,612],{"type":39,"value":597},"The ",{"type":34,"tag":91,"props":599,"children":601},{"className":600},[],[602],{"type":39,"value":603},"navigator.sendBeacon",{"type":39,"value":605}," API sends HTTP POST without cookies. ",{"type":34,"tag":91,"props":607,"children":609},{"className":608},[],[610],{"type":39,"value":611},"sessionHash",{"type":39,"value":613}," is generated client-side and never persisted (lost when the tab closes). This hash stitches page views within the same session but doesn't identify the same user on different days.",{"type":34,"tag":35,"props":615,"children":616},{},[617,622],{"type":34,"tag":78,"props":618,"children":619},{},[620],{"type":39,"value":621},"Server side (written in Elixir\u002FPhoenix):",{"type":39,"value":623},"\nIncoming events are written to ClickHouse (time-series database). Plausible self-hosted deployments default to ClickHouse; the cloud version uses managed ClickHouse. Table schema:",{"type":34,"tag":84,"props":625,"children":629},{"className":626,"code":627,"language":628,"meta":17,"style":17},"language-sql shiki shiki-themes github-dark","CREATE TABLE events (\n  timestamp DateTime,\n  domain String,\n  pathname String,\n  referrer String,\n  session_hash String,\n  event_name String,\n  props Map(String, String),\n  user_agent String,\n  country String,\n  device_type Enum8('desktop'=1, 'mobile'=2, 'tablet'=3)\n) ENGINE = MergeTree()\nPARTITION BY toYYYYMM(timestamp)\nORDER BY (domain, toDate(timestamp), session_hash);\n","sql",[630],{"type":34,"tag":91,"props":631,"children":632},{"__ignoreMap":17},[633,656,674,682,690,698,706,714,722,730,738,802,819,846],{"type":34,"tag":95,"props":634,"children":635},{"class":97,"line":98},[636,641,646,651],{"type":34,"tag":95,"props":637,"children":638},{"style":118},[639],{"type":39,"value":640},"CREATE",{"type":34,"tag":95,"props":642,"children":643},{"style":118},[644],{"type":39,"value":645}," TABLE",{"type":34,"tag":95,"props":647,"children":648},{"style":177},[649],{"type":39,"value":650}," events",{"type":34,"tag":95,"props":652,"children":653},{"style":112},[654],{"type":39,"value":655}," (\n",{"type":34,"tag":95,"props":657,"children":658},{"class":97,"line":108},[659,664,669],{"type":34,"tag":95,"props":660,"children":661},{"style":118},[662],{"type":39,"value":663},"  timestamp",{"type":34,"tag":95,"props":665,"children":666},{"style":118},[667],{"type":39,"value":668}," DateTime",{"type":34,"tag":95,"props":670,"children":671},{"style":112},[672],{"type":39,"value":673},",\n",{"type":34,"tag":95,"props":675,"children":676},{"class":97,"line":129},[677],{"type":34,"tag":95,"props":678,"children":679},{"style":112},[680],{"type":39,"value":681},"  domain String,\n",{"type":34,"tag":95,"props":683,"children":684},{"class":97,"line":160},[685],{"type":34,"tag":95,"props":686,"children":687},{"style":112},[688],{"type":39,"value":689},"  pathname String,\n",{"type":34,"tag":95,"props":691,"children":692},{"class":97,"line":227},[693],{"type":34,"tag":95,"props":694,"children":695},{"style":112},[696],{"type":39,"value":697},"  referrer String,\n",{"type":34,"tag":95,"props":699,"children":700},{"class":97,"line":236},[701],{"type":34,"tag":95,"props":702,"children":703},{"style":112},[704],{"type":39,"value":705},"  session_hash String,\n",{"type":34,"tag":95,"props":707,"children":708},{"class":97,"line":279},[709],{"type":34,"tag":95,"props":710,"children":711},{"style":112},[712],{"type":39,"value":713},"  event_name String,\n",{"type":34,"tag":95,"props":715,"children":716},{"class":97,"line":318},[717],{"type":34,"tag":95,"props":718,"children":719},{"style":112},[720],{"type":39,"value":721},"  props Map(String, String),\n",{"type":34,"tag":95,"props":723,"children":724},{"class":97,"line":28},[725],{"type":34,"tag":95,"props":726,"children":727},{"style":112},[728],{"type":39,"value":729},"  user_agent String,\n",{"type":34,"tag":95,"props":731,"children":732},{"class":97,"line":345},[733],{"type":34,"tag":95,"props":734,"children":735},{"style":112},[736],{"type":39,"value":737},"  country String,\n",{"type":34,"tag":95,"props":739,"children":740},{"class":97,"line":354},[741,746,751,756,761,765,770,774,779,783,788,792,797],{"type":34,"tag":95,"props":742,"children":743},{"style":112},[744],{"type":39,"value":745},"  device_type Enum8(",{"type":34,"tag":95,"props":747,"children":748},{"style":149},[749],{"type":39,"value":750},"'desktop'",{"type":34,"tag":95,"props":752,"children":753},{"style":118},[754],{"type":39,"value":755},"=",{"type":34,"tag":95,"props":757,"children":758},{"style":138},[759],{"type":39,"value":760},"1",{"type":34,"tag":95,"props":762,"children":763},{"style":112},[764],{"type":39,"value":262},{"type":34,"tag":95,"props":766,"children":767},{"style":149},[768],{"type":39,"value":769},"'mobile'",{"type":34,"tag":95,"props":771,"children":772},{"style":118},[773],{"type":39,"value":755},{"type":34,"tag":95,"props":775,"children":776},{"style":138},[777],{"type":39,"value":778},"2",{"type":34,"tag":95,"props":780,"children":781},{"style":112},[782],{"type":39,"value":262},{"type":34,"tag":95,"props":784,"children":785},{"style":149},[786],{"type":39,"value":787},"'tablet'",{"type":34,"tag":95,"props":789,"children":790},{"style":118},[791],{"type":39,"value":755},{"type":34,"tag":95,"props":793,"children":794},{"style":138},[795],{"type":39,"value":796},"3",{"type":34,"tag":95,"props":798,"children":799},{"style":112},[800],{"type":39,"value":801},")\n",{"type":34,"tag":95,"props":803,"children":804},{"class":97,"line":363},[805,810,814],{"type":34,"tag":95,"props":806,"children":807},{"style":112},[808],{"type":39,"value":809},") ENGINE ",{"type":34,"tag":95,"props":811,"children":812},{"style":118},[813],{"type":39,"value":755},{"type":34,"tag":95,"props":815,"children":816},{"style":112},[817],{"type":39,"value":818}," MergeTree()\n",{"type":34,"tag":95,"props":820,"children":821},{"class":97,"line":372},[822,827,832,837,842],{"type":34,"tag":95,"props":823,"children":824},{"style":118},[825],{"type":39,"value":826},"PARTITION",{"type":34,"tag":95,"props":828,"children":829},{"style":118},[830],{"type":39,"value":831}," BY",{"type":34,"tag":95,"props":833,"children":834},{"style":112},[835],{"type":39,"value":836}," toYYYYMM(",{"type":34,"tag":95,"props":838,"children":839},{"style":118},[840],{"type":39,"value":841},"timestamp",{"type":34,"tag":95,"props":843,"children":844},{"style":112},[845],{"type":39,"value":801},{"type":34,"tag":95,"props":847,"children":848},{"class":97,"line":386},[849,854,859,863],{"type":34,"tag":95,"props":850,"children":851},{"style":118},[852],{"type":39,"value":853},"ORDER BY",{"type":34,"tag":95,"props":855,"children":856},{"style":112},[857],{"type":39,"value":858}," (domain, toDate(",{"type":34,"tag":95,"props":860,"children":861},{"style":118},[862],{"type":39,"value":841},{"type":34,"tag":95,"props":864,"children":865},{"style":112},[866],{"type":39,"value":867},"), session_hash);\n",{"type":34,"tag":35,"props":869,"children":870},{},[871],{"type":39,"value":872},"Aggregation queries run very fast in ClickHouse's MergeTree engine: a \"daily unique sessions\" query on a table with 100M events returns in 200-400 ms.",{"type":34,"tag":42,"props":874,"children":876},{"id":875},"server-side-aggregation-session-cohort-retention",[877],{"type":39,"value":878},"Server-Side Aggregation: Session → Cohort → Retention",{"type":34,"tag":35,"props":880,"children":881},{},[882,884,889],{"type":39,"value":883},"The Plausible dashboard shows \"unique sessions\" rather than \"unique visitors.\" But marketing analysis needs more than sessions—cohort-based retention, LTV projection, campaign attribution all require user identity. The cookieless way to do this: ",{"type":34,"tag":78,"props":885,"children":886},{},[887],{"type":39,"value":888},"server-side identity resolution + aggregation layer",{"type":39,"value":305},{"type":34,"tag":35,"props":891,"children":892},{},[893,895,901],{"type":39,"value":894},"Scenario: E-commerce site collecting events with Plausible and exporting to BigQuery. When a user logs in, ",{"type":34,"tag":91,"props":896,"children":898},{"className":897},[],[899],{"type":39,"value":900},"user_id",{"type":39,"value":902}," is sent as a custom property:",{"type":34,"tag":84,"props":904,"children":906},{"className":86,"code":905,"language":88,"meta":17,"style":17},"\u002F\u002F On checkout page after login\nplausible('Login', { props: { user_id: '{{user.id}}' } });\n",[907],{"type":34,"tag":91,"props":908,"children":909},{"__ignoreMap":17},[910,918],{"type":34,"tag":95,"props":911,"children":912},{"class":97,"line":98},[913],{"type":34,"tag":95,"props":914,"children":915},{"style":102},[916],{"type":39,"value":917},"\u002F\u002F On checkout page after login\n",{"type":34,"tag":95,"props":919,"children":920},{"class":97,"line":108},[921,925,929,934,939,944],{"type":34,"tag":95,"props":922,"children":923},{"style":177},[924],{"type":39,"value":24},{"type":34,"tag":95,"props":926,"children":927},{"style":112},[928],{"type":39,"value":115},{"type":34,"tag":95,"props":930,"children":931},{"style":149},[932],{"type":39,"value":933},"'Login'",{"type":34,"tag":95,"props":935,"children":936},{"style":112},[937],{"type":39,"value":938},", { props: { user_id: ",{"type":34,"tag":95,"props":940,"children":941},{"style":149},[942],{"type":39,"value":943},"'{{user.id}}'",{"type":34,"tag":95,"props":945,"children":946},{"style":112},[947],{"type":39,"value":948}," } });\n",{"type":34,"tag":35,"props":950,"children":951},{},[952,954,959],{"type":39,"value":953},"A daily batch job in BigQuery merges Plausible events with ",{"type":34,"tag":91,"props":955,"children":957},{"className":956},[],[958],{"type":39,"value":900},{"type":39,"value":960},":",{"type":34,"tag":84,"props":962,"children":964},{"className":626,"code":963,"language":628,"meta":17,"style":17},"-- dbt model: user_sessions_daily.sql\nWITH raw_events AS (\n  SELECT\n    timestamp,\n    session_hash,\n    JSON_EXTRACT_SCALAR(props, '$.user_id') AS user_id,\n    pathname,\n    event_name\n  FROM `analytics.plausible_events`\n  WHERE DATE(timestamp) = CURRENT_DATE - 1\n),\nidentified_sessions AS (\n  SELECT\n    session_hash,\n    FIRST_VALUE(user_id IGNORE NULLS) OVER (\n      PARTITION BY session_hash ORDER BY timestamp\n    ) AS resolved_user_id\n  FROM raw_events\n)\nSELECT\n  e.timestamp,\n  e.session_hash,\n  COALESCE(i.resolved_user_id, e.session_hash) AS user_key,\n  e.pathname,\n  e.event_name\nFROM raw_events e\nLEFT JOIN identified_sessions i USING (session_hash);\n",[965],{"type":34,"tag":91,"props":966,"children":967},{"__ignoreMap":17},[968,976,998,1006,1018,1026,1052,1060,1068,1081,1125,1133,1149,1156,1163,1199,1225,1242,1254,1261,1269,1289,1309,1364,1384,1400,1413],{"type":34,"tag":95,"props":969,"children":970},{"class":97,"line":98},[971],{"type":34,"tag":95,"props":972,"children":973},{"style":102},[974],{"type":39,"value":975},"-- dbt model: user_sessions_daily.sql\n",{"type":34,"tag":95,"props":977,"children":978},{"class":97,"line":108},[979,984,989,994],{"type":34,"tag":95,"props":980,"children":981},{"style":118},[982],{"type":39,"value":983},"WITH",{"type":34,"tag":95,"props":985,"children":986},{"style":112},[987],{"type":39,"value":988}," raw_events ",{"type":34,"tag":95,"props":990,"children":991},{"style":118},[992],{"type":39,"value":993},"AS",{"type":34,"tag":95,"props":995,"children":996},{"style":112},[997],{"type":39,"value":655},{"type":34,"tag":95,"props":999,"children":1000},{"class":97,"line":129},[1001],{"type":34,"tag":95,"props":1002,"children":1003},{"style":118},[1004],{"type":39,"value":1005},"  SELECT\n",{"type":34,"tag":95,"props":1007,"children":1008},{"class":97,"line":160},[1009,1014],{"type":34,"tag":95,"props":1010,"children":1011},{"style":118},[1012],{"type":39,"value":1013},"    timestamp",{"type":34,"tag":95,"props":1015,"children":1016},{"style":112},[1017],{"type":39,"value":673},{"type":34,"tag":95,"props":1019,"children":1020},{"class":97,"line":227},[1021],{"type":34,"tag":95,"props":1022,"children":1023},{"style":112},[1024],{"type":39,"value":1025},"    session_hash,\n",{"type":34,"tag":95,"props":1027,"children":1028},{"class":97,"line":236},[1029,1034,1039,1043,1047],{"type":34,"tag":95,"props":1030,"children":1031},{"style":112},[1032],{"type":39,"value":1033},"    JSON_EXTRACT_SCALAR(props, ",{"type":34,"tag":95,"props":1035,"children":1036},{"style":149},[1037],{"type":39,"value":1038},"'$.user_id'",{"type":34,"tag":95,"props":1040,"children":1041},{"style":112},[1042],{"type":39,"value":500},{"type":34,"tag":95,"props":1044,"children":1045},{"style":118},[1046],{"type":39,"value":993},{"type":34,"tag":95,"props":1048,"children":1049},{"style":112},[1050],{"type":39,"value":1051}," user_id,\n",{"type":34,"tag":95,"props":1053,"children":1054},{"class":97,"line":279},[1055],{"type":34,"tag":95,"props":1056,"children":1057},{"style":112},[1058],{"type":39,"value":1059},"    pathname,\n",{"type":34,"tag":95,"props":1061,"children":1062},{"class":97,"line":318},[1063],{"type":34,"tag":95,"props":1064,"children":1065},{"style":112},[1066],{"type":39,"value":1067},"    event_name\n",{"type":34,"tag":95,"props":1069,"children":1070},{"class":97,"line":28},[1071,1076],{"type":34,"tag":95,"props":1072,"children":1073},{"style":118},[1074],{"type":39,"value":1075},"  FROM",{"type":34,"tag":95,"props":1077,"children":1078},{"style":149},[1079],{"type":39,"value":1080}," `analytics.plausible_events`\n",{"type":34,"tag":95,"props":1082,"children":1083},{"class":97,"line":345},[1084,1089,1094,1098,1102,1106,1110,1115,1120],{"type":34,"tag":95,"props":1085,"children":1086},{"style":118},[1087],{"type":39,"value":1088},"  WHERE",{"type":34,"tag":95,"props":1090,"children":1091},{"style":118},[1092],{"type":39,"value":1093}," DATE",{"type":34,"tag":95,"props":1095,"children":1096},{"style":112},[1097],{"type":39,"value":115},{"type":34,"tag":95,"props":1099,"children":1100},{"style":118},[1101],{"type":39,"value":841},{"type":34,"tag":95,"props":1103,"children":1104},{"style":112},[1105],{"type":39,"value":500},{"type":34,"tag":95,"props":1107,"children":1108},{"style":118},[1109],{"type":39,"value":755},{"type":34,"tag":95,"props":1111,"children":1112},{"style":112},[1113],{"type":39,"value":1114}," CURRENT_DATE ",{"type":34,"tag":95,"props":1116,"children":1117},{"style":118},[1118],{"type":39,"value":1119},"-",{"type":34,"tag":95,"props":1121,"children":1122},{"style":138},[1123],{"type":39,"value":1124}," 1\n",{"type":34,"tag":95,"props":1126,"children":1127},{"class":97,"line":354},[1128],{"type":34,"tag":95,"props":1129,"children":1130},{"style":112},[1131],{"type":39,"value":1132},"),\n",{"type":34,"tag":95,"props":1134,"children":1135},{"class":97,"line":363},[1136,1141,1145],{"type":34,"tag":95,"props":1137,"children":1138},{"style":112},[1139],{"type":39,"value":1140},"identified_sessions ",{"type":34,"tag":95,"props":1142,"children":1143},{"style":118},[1144],{"type":39,"value":993},{"type":34,"tag":95,"props":1146,"children":1147},{"style":112},[1148],{"type":39,"value":655},{"type":34,"tag":95,"props":1150,"children":1151},{"class":97,"line":372},[1152],{"type":34,"tag":95,"props":1153,"children":1154},{"style":118},[1155],{"type":39,"value":1005},{"type":34,"tag":95,"props":1157,"children":1158},{"class":97,"line":386},[1159],{"type":34,"tag":95,"props":1160,"children":1161},{"style":112},[1162],{"type":39,"value":1025},{"type":34,"tag":95,"props":1164,"children":1165},{"class":97,"line":400},[1166,1171,1176,1181,1186,1190,1195],{"type":34,"tag":95,"props":1167,"children":1168},{"style":138},[1169],{"type":39,"value":1170},"    FIRST_VALUE",{"type":34,"tag":95,"props":1172,"children":1173},{"style":112},[1174],{"type":39,"value":1175},"(user_id ",{"type":34,"tag":95,"props":1177,"children":1178},{"style":118},[1179],{"type":39,"value":1180},"IGNORE",{"type":34,"tag":95,"props":1182,"children":1183},{"style":118},[1184],{"type":39,"value":1185}," NULLS",{"type":34,"tag":95,"props":1187,"children":1188},{"style":112},[1189],{"type":39,"value":500},{"type":34,"tag":95,"props":1191,"children":1192},{"style":118},[1193],{"type":39,"value":1194},"OVER",{"type":34,"tag":95,"props":1196,"children":1197},{"style":112},[1198],{"type":39,"value":655},{"type":34,"tag":95,"props":1200,"children":1201},{"class":97,"line":409},[1202,1207,1211,1216,1220],{"type":34,"tag":95,"props":1203,"children":1204},{"style":118},[1205],{"type":39,"value":1206},"      PARTITION",{"type":34,"tag":95,"props":1208,"children":1209},{"style":118},[1210],{"type":39,"value":831},{"type":34,"tag":95,"props":1212,"children":1213},{"style":112},[1214],{"type":39,"value":1215}," session_hash ",{"type":34,"tag":95,"props":1217,"children":1218},{"style":118},[1219],{"type":39,"value":853},{"type":34,"tag":95,"props":1221,"children":1222},{"style":118},[1223],{"type":39,"value":1224}," timestamp\n",{"type":34,"tag":95,"props":1226,"children":1227},{"class":97,"line":418},[1228,1233,1237],{"type":34,"tag":95,"props":1229,"children":1230},{"style":112},[1231],{"type":39,"value":1232},"    ) ",{"type":34,"tag":95,"props":1234,"children":1235},{"style":118},[1236],{"type":39,"value":993},{"type":34,"tag":95,"props":1238,"children":1239},{"style":112},[1240],{"type":39,"value":1241}," resolved_user_id\n",{"type":34,"tag":95,"props":1243,"children":1244},{"class":97,"line":426},[1245,1249],{"type":34,"tag":95,"props":1246,"children":1247},{"style":118},[1248],{"type":39,"value":1075},{"type":34,"tag":95,"props":1250,"children":1251},{"style":112},[1252],{"type":39,"value":1253}," raw_events\n",{"type":34,"tag":95,"props":1255,"children":1256},{"class":97,"line":448},[1257],{"type":34,"tag":95,"props":1258,"children":1259},{"style":112},[1260],{"type":39,"value":801},{"type":34,"tag":95,"props":1262,"children":1263},{"class":97,"line":456},[1264],{"type":34,"tag":95,"props":1265,"children":1266},{"style":118},[1267],{"type":39,"value":1268},"SELECT\n",{"type":34,"tag":95,"props":1270,"children":1271},{"class":97,"line":465},[1272,1277,1281,1285],{"type":34,"tag":95,"props":1273,"children":1274},{"style":138},[1275],{"type":39,"value":1276},"  e",{"type":34,"tag":95,"props":1278,"children":1279},{"style":112},[1280],{"type":39,"value":305},{"type":34,"tag":95,"props":1282,"children":1283},{"style":138},[1284],{"type":39,"value":841},{"type":34,"tag":95,"props":1286,"children":1287},{"style":112},[1288],{"type":39,"value":673},{"type":34,"tag":95,"props":1290,"children":1291},{"class":97,"line":513},[1292,1296,1300,1305],{"type":34,"tag":95,"props":1293,"children":1294},{"style":138},[1295],{"type":39,"value":1276},{"type":34,"tag":95,"props":1297,"children":1298},{"style":112},[1299],{"type":39,"value":305},{"type":34,"tag":95,"props":1301,"children":1302},{"style":138},[1303],{"type":39,"value":1304},"session_hash",{"type":34,"tag":95,"props":1306,"children":1307},{"style":112},[1308],{"type":39,"value":673},{"type":34,"tag":95,"props":1310,"children":1311},{"class":97,"line":546},[1312,1317,1321,1326,1330,1335,1339,1343,1347,1351,1355,1359],{"type":34,"tag":95,"props":1313,"children":1314},{"style":138},[1315],{"type":39,"value":1316},"  COALESCE",{"type":34,"tag":95,"props":1318,"children":1319},{"style":112},[1320],{"type":39,"value":115},{"type":34,"tag":95,"props":1322,"children":1323},{"style":138},[1324],{"type":39,"value":1325},"i",{"type":34,"tag":95,"props":1327,"children":1328},{"style":112},[1329],{"type":39,"value":305},{"type":34,"tag":95,"props":1331,"children":1332},{"style":138},[1333],{"type":39,"value":1334},"resolved_user_id",{"type":34,"tag":95,"props":1336,"children":1337},{"style":112},[1338],{"type":39,"value":262},{"type":34,"tag":95,"props":1340,"children":1341},{"style":138},[1342],{"type":39,"value":495},{"type":34,"tag":95,"props":1344,"children":1345},{"style":112},[1346],{"type":39,"value":305},{"type":34,"tag":95,"props":1348,"children":1349},{"style":138},[1350],{"type":39,"value":1304},{"type":34,"tag":95,"props":1352,"children":1353},{"style":112},[1354],{"type":39,"value":500},{"type":34,"tag":95,"props":1356,"children":1357},{"style":118},[1358],{"type":39,"value":993},{"type":34,"tag":95,"props":1360,"children":1361},{"style":112},[1362],{"type":39,"value":1363}," user_key,\n",{"type":34,"tag":95,"props":1365,"children":1366},{"class":97,"line":568},[1367,1371,1375,1380],{"type":34,"tag":95,"props":1368,"children":1369},{"style":138},[1370],{"type":39,"value":1276},{"type":34,"tag":95,"props":1372,"children":1373},{"style":112},[1374],{"type":39,"value":305},{"type":34,"tag":95,"props":1376,"children":1377},{"style":138},[1378],{"type":39,"value":1379},"pathname",{"type":34,"tag":95,"props":1381,"children":1382},{"style":112},[1383],{"type":39,"value":673},{"type":34,"tag":95,"props":1385,"children":1386},{"class":97,"line":577},[1387,1391,1395],{"type":34,"tag":95,"props":1388,"children":1389},{"style":138},[1390],{"type":39,"value":1276},{"type":34,"tag":95,"props":1392,"children":1393},{"style":112},[1394],{"type":39,"value":305},{"type":34,"tag":95,"props":1396,"children":1397},{"style":138},[1398],{"type":39,"value":1399},"event_name\n",{"type":34,"tag":95,"props":1401,"children":1402},{"class":97,"line":586},[1403,1408],{"type":34,"tag":95,"props":1404,"children":1405},{"style":118},[1406],{"type":39,"value":1407},"FROM",{"type":34,"tag":95,"props":1409,"children":1410},{"style":112},[1411],{"type":39,"value":1412}," raw_events e\n",{"type":34,"tag":95,"props":1414,"children":1416},{"class":97,"line":1415},27,[1417,1422,1427,1432],{"type":34,"tag":95,"props":1418,"children":1419},{"style":118},[1420],{"type":39,"value":1421},"LEFT JOIN",{"type":34,"tag":95,"props":1423,"children":1424},{"style":112},[1425],{"type":39,"value":1426}," identified_sessions i ",{"type":34,"tag":95,"props":1428,"children":1429},{"style":118},[1430],{"type":39,"value":1431},"USING",{"type":34,"tag":95,"props":1433,"children":1434},{"style":112},[1435],{"type":39,"value":1436}," (session_hash);\n",{"type":34,"tag":35,"props":1438,"children":1439},{},[1440,1442,1448,1450,1455,1457,1462,1464,1469],{"type":39,"value":1441},"In this model, ",{"type":34,"tag":91,"props":1443,"children":1445},{"className":1444},[],[1446],{"type":39,"value":1447},"user_key",{"type":39,"value":1449}," is ",{"type":34,"tag":91,"props":1451,"children":1453},{"className":1452},[],[1454],{"type":39,"value":900},{"type":39,"value":1456}," for logged-in users and ",{"type":34,"tag":91,"props":1458,"children":1460},{"className":1459},[],[1461],{"type":39,"value":1304},{"type":39,"value":1463}," for anonymous sessions. Retention calculations now work on ",{"type":34,"tag":91,"props":1465,"children":1467},{"className":1466},[],[1468],{"type":39,"value":1447},{"type":39,"value":960},{"type":34,"tag":84,"props":1471,"children":1473},{"className":626,"code":1472,"language":628,"meta":17,"style":17},"-- 7-day retention cohort\nSELECT\n  DATE_TRUNC(first_seen, WEEK) AS cohort_week,\n  COUNT(DISTINCT user_key) AS cohort_size,\n  COUNT(DISTINCT CASE WHEN day_7_active THEN user_key END) AS retained_d7,\n  SAFE_DIVIDE(\n    COUNT(DISTINCT CASE WHEN day_7_active THEN user_key END),\n    COUNT(DISTINCT user_key)\n  ) AS retention_rate\nFROM user_retention_facts\nGROUP BY 1;\n",[1474],{"type":34,"tag":91,"props":1475,"children":1476},{"__ignoreMap":17},[1477,1485,1492,1518,1549,1607,1615,1659,1679,1696,1708],{"type":34,"tag":95,"props":1478,"children":1479},{"class":97,"line":98},[1480],{"type":34,"tag":95,"props":1481,"children":1482},{"style":102},[1483],{"type":39,"value":1484},"-- 7-day retention cohort\n",{"type":34,"tag":95,"props":1486,"children":1487},{"class":97,"line":108},[1488],{"type":34,"tag":95,"props":1489,"children":1490},{"style":118},[1491],{"type":39,"value":1268},{"type":34,"tag":95,"props":1493,"children":1494},{"class":97,"line":129},[1495,1500,1505,1509,1513],{"type":34,"tag":95,"props":1496,"children":1497},{"style":112},[1498],{"type":39,"value":1499},"  DATE_TRUNC(first_seen, ",{"type":34,"tag":95,"props":1501,"children":1502},{"style":118},[1503],{"type":39,"value":1504},"WEEK",{"type":34,"tag":95,"props":1506,"children":1507},{"style":112},[1508],{"type":39,"value":500},{"type":34,"tag":95,"props":1510,"children":1511},{"style":118},[1512],{"type":39,"value":993},{"type":34,"tag":95,"props":1514,"children":1515},{"style":112},[1516],{"type":39,"value":1517}," cohort_week,\n",{"type":34,"tag":95,"props":1519,"children":1520},{"class":97,"line":160},[1521,1526,1530,1535,1540,1544],{"type":34,"tag":95,"props":1522,"children":1523},{"style":138},[1524],{"type":39,"value":1525},"  COUNT",{"type":34,"tag":95,"props":1527,"children":1528},{"style":112},[1529],{"type":39,"value":115},{"type":34,"tag":95,"props":1531,"children":1532},{"style":118},[1533],{"type":39,"value":1534},"DISTINCT",{"type":34,"tag":95,"props":1536,"children":1537},{"style":112},[1538],{"type":39,"value":1539}," user_key) ",{"type":34,"tag":95,"props":1541,"children":1542},{"style":118},[1543],{"type":39,"value":993},{"type":34,"tag":95,"props":1545,"children":1546},{"style":112},[1547],{"type":39,"value":1548}," cohort_size,\n",{"type":34,"tag":95,"props":1550,"children":1551},{"class":97,"line":227},[1552,1556,1560,1564,1569,1574,1579,1584,1589,1594,1598,1602],{"type":34,"tag":95,"props":1553,"children":1554},{"style":138},[1555],{"type":39,"value":1525},{"type":34,"tag":95,"props":1557,"children":1558},{"style":112},[1559],{"type":39,"value":115},{"type":34,"tag":95,"props":1561,"children":1562},{"style":118},[1563],{"type":39,"value":1534},{"type":34,"tag":95,"props":1565,"children":1566},{"style":118},[1567],{"type":39,"value":1568}," CASE",{"type":34,"tag":95,"props":1570,"children":1571},{"style":118},[1572],{"type":39,"value":1573}," WHEN",{"type":34,"tag":95,"props":1575,"children":1576},{"style":112},[1577],{"type":39,"value":1578}," day_7_active ",{"type":34,"tag":95,"props":1580,"children":1581},{"style":118},[1582],{"type":39,"value":1583},"THEN",{"type":34,"tag":95,"props":1585,"children":1586},{"style":112},[1587],{"type":39,"value":1588}," user_key ",{"type":34,"tag":95,"props":1590,"children":1591},{"style":118},[1592],{"type":39,"value":1593},"END",{"type":34,"tag":95,"props":1595,"children":1596},{"style":112},[1597],{"type":39,"value":500},{"type":34,"tag":95,"props":1599,"children":1600},{"style":118},[1601],{"type":39,"value":993},{"type":34,"tag":95,"props":1603,"children":1604},{"style":112},[1605],{"type":39,"value":1606}," retained_d7,\n",{"type":34,"tag":95,"props":1608,"children":1609},{"class":97,"line":236},[1610],{"type":34,"tag":95,"props":1611,"children":1612},{"style":112},[1613],{"type":39,"value":1614},"  SAFE_DIVIDE(\n",{"type":34,"tag":95,"props":1616,"children":1617},{"class":97,"line":279},[1618,1623,1627,1631,1635,1639,1643,1647,1651,1655],{"type":34,"tag":95,"props":1619,"children":1620},{"style":138},[1621],{"type":39,"value":1622},"    COUNT",{"type":34,"tag":95,"props":1624,"children":1625},{"style":112},[1626],{"type":39,"value":115},{"type":34,"tag":95,"props":1628,"children":1629},{"style":118},[1630],{"type":39,"value":1534},{"type":34,"tag":95,"props":1632,"children":1633},{"style":118},[1634],{"type":39,"value":1568},{"type":34,"tag":95,"props":1636,"children":1637},{"style":118},[1638],{"type":39,"value":1573},{"type":34,"tag":95,"props":1640,"children":1641},{"style":112},[1642],{"type":39,"value":1578},{"type":34,"tag":95,"props":1644,"children":1645},{"style":118},[1646],{"type":39,"value":1583},{"type":34,"tag":95,"props":1648,"children":1649},{"style":112},[1650],{"type":39,"value":1588},{"type":34,"tag":95,"props":1652,"children":1653},{"style":118},[1654],{"type":39,"value":1593},{"type":34,"tag":95,"props":1656,"children":1657},{"style":112},[1658],{"type":39,"value":1132},{"type":34,"tag":95,"props":1660,"children":1661},{"class":97,"line":318},[1662,1666,1670,1674],{"type":34,"tag":95,"props":1663,"children":1664},{"style":138},[1665],{"type":39,"value":1622},{"type":34,"tag":95,"props":1667,"children":1668},{"style":112},[1669],{"type":39,"value":115},{"type":34,"tag":95,"props":1671,"children":1672},{"style":118},[1673],{"type":39,"value":1534},{"type":34,"tag":95,"props":1675,"children":1676},{"style":112},[1677],{"type":39,"value":1678}," user_key)\n",{"type":34,"tag":95,"props":1680,"children":1681},{"class":97,"line":28},[1682,1687,1691],{"type":34,"tag":95,"props":1683,"children":1684},{"style":112},[1685],{"type":39,"value":1686},"  ) ",{"type":34,"tag":95,"props":1688,"children":1689},{"style":118},[1690],{"type":39,"value":993},{"type":34,"tag":95,"props":1692,"children":1693},{"style":112},[1694],{"type":39,"value":1695}," retention_rate\n",{"type":34,"tag":95,"props":1697,"children":1698},{"class":97,"line":345},[1699,1703],{"type":34,"tag":95,"props":1700,"children":1701},{"style":118},[1702],{"type":39,"value":1407},{"type":34,"tag":95,"props":1704,"children":1705},{"style":112},[1706],{"type":39,"value":1707}," user_retention_facts\n",{"type":34,"tag":95,"props":1709,"children":1710},{"class":97,"line":354},[1711,1716,1721],{"type":34,"tag":95,"props":1712,"children":1713},{"style":118},[1714],{"type":39,"value":1715},"GROUP BY",{"type":34,"tag":95,"props":1717,"children":1718},{"style":138},[1719],{"type":39,"value":1720}," 1",{"type":34,"tag":95,"props":1722,"children":1723},{"style":112},[1724],{"type":39,"value":157},{"type":34,"tag":35,"props":1726,"children":1727},{},[1728],{"type":39,"value":1729},"Anonymous sessions are included in cohort analysis but excluded from long-term LTV calculations because we can't track the same user across different days. On a site with 30% login rate, you can still measure retention for that 30%—similar depth to GA4's 35-40% consent rate but with zero GDPR risk.",{"type":34,"tag":42,"props":1731,"children":1733},{"id":1732},"ga4-vs-plausible-compliance-vs-granularity",[1734],{"type":39,"value":1735},"GA4 vs. Plausible: Compliance vs. Granularity",{"type":34,"tag":35,"props":1737,"children":1738},{},[1739],{"type":34,"tag":78,"props":1740,"children":1741},{},[1742],{"type":39,"value":1743},"GA4 advantages:",{"type":34,"tag":1745,"props":1746,"children":1747},"ul",{},[1748,1754,1759,1764],{"type":34,"tag":1749,"props":1750,"children":1751},"li",{},[1752],{"type":39,"value":1753},"User ID + Google Signals cross-device tracking (with consent)",{"type":34,"tag":1749,"props":1755,"children":1756},{},[1757],{"type":39,"value":1758},"BigQuery export native, schema stable",{"type":34,"tag":1749,"props":1760,"children":1761},{},[1762],{"type":39,"value":1763},"Funnel and path exploration reports ready in UI",{"type":34,"tag":1749,"props":1765,"children":1766},{},[1767],{"type":39,"value":1768},"Google Ads integration one click away",{"type":34,"tag":35,"props":1770,"children":1771},{},[1772],{"type":34,"tag":78,"props":1773,"children":1774},{},[1775],{"type":39,"value":1776},"GA4 disadvantages:",{"type":34,"tag":1745,"props":1778,"children":1779},{},[1780,1785,1790,1795],{"type":34,"tag":1749,"props":1781,"children":1782},{},[1783],{"type":39,"value":1784},"Consent Mode v2 required → modeled data when consent_status=denied",{"type":34,"tag":1749,"props":1786,"children":1787},{},[1788],{"type":39,"value":1789},"360-day user ID retention (user_pseudo_id resets after 14 months)",{"type":34,"tag":1749,"props":1791,"children":1792},{},[1793],{"type":39,"value":1794},"Script size 43 KB (30× Plausible)",{"type":34,"tag":1749,"props":1796,"children":1797},{},[1798],{"type":39,"value":1799},"ClickStream export requires GA360 (annual $150K+)",{"type":34,"tag":35,"props":1801,"children":1802},{},[1803],{"type":34,"tag":78,"props":1804,"children":1805},{},[1806],{"type":39,"value":1807},"Plausible + server-side stack advantages:",{"type":34,"tag":1745,"props":1809,"children":1810},{},[1811,1816,1821,1826],{"type":34,"tag":1749,"props":1812,"children":1813},{},[1814],{"type":39,"value":1815},"No cookies → GDPR consent banner optional (massively simplified)",{"type":34,"tag":1749,"props":1817,"children":1818},{},[1819],{"type":39,"value":1820},"Event ownership: raw data under your control (ClickHouse, BigQuery, S3)",{"type":34,"tag":1749,"props":1822,"children":1823},{},[1824],{"type":39,"value":1825},"Lightweight script → \u003C5ms page load impact",{"type":34,"tag":1749,"props":1827,"children":1828},{},[1829],{"type":39,"value":1830},"Self-hosted option available (data stays in EU)",{"type":34,"tag":35,"props":1832,"children":1833},{},[1834],{"type":34,"tag":78,"props":1835,"children":1836},{},[1837],{"type":39,"value":1838},"Plausible disadvantages:",{"type":34,"tag":1745,"props":1840,"children":1841},{},[1842,1847,1852],{"type":34,"tag":1749,"props":1843,"children":1844},{},[1845],{"type":39,"value":1846},"No cross-device tracking (for non-logged-in users)",{"type":34,"tag":1749,"props":1848,"children":1849},{},[1850],{"type":39,"value":1851},"Funnel\u002Fpath analysis requires custom SQL",{"type":34,"tag":1749,"props":1853,"children":1854},{},[1855],{"type":39,"value":1856},"Google Ads\u002FMeta Conversion API integration needs custom pipeline",{"type":34,"tag":35,"props":1858,"children":1859},{},[1860],{"type":34,"tag":78,"props":1861,"children":1862},{},[1863],{"type":39,"value":1864},"Cost comparison (100M events\u002Fmonth):",{"type":34,"tag":1745,"props":1866,"children":1867},{},[1868,1873,1878,1883],{"type":34,"tag":1749,"props":1869,"children":1870},{},[1871],{"type":39,"value":1872},"GA4 standard: Free but no BigQuery export (GA360 $150K\u002Fyear)",{"type":34,"tag":1749,"props":1874,"children":1875},{},[1876],{"type":39,"value":1877},"Plausible Cloud: Business plan $200\u002Fmonth (200K pageview\u002Fmonth limit, excess self-host)",{"type":34,"tag":1749,"props":1879,"children":1880},{},[1881],{"type":39,"value":1882},"Self-hosted Plausible + ClickHouse (AWS c6g.2xlarge + 500GB SSD): ~$350\u002Fmonth",{"type":34,"tag":1749,"props":1884,"children":1885},{},[1886],{"type":39,"value":1887},"BigQuery batch job (daily aggregation): ~$80\u002Fmonth",{"type":34,"tag":35,"props":1889,"children":1890},{},[1891],{"type":39,"value":1892},"Total Plausible stack: ~$430\u002Fmonth. GA360: $12.5K\u002Fmonth. 30× cost difference.",{"type":34,"tag":42,"props":1894,"children":1896},{"id":1895},"identity-resolution-layer-probabilistic-match",[1897],{"type":39,"value":1898},"Identity Resolution Layer: Probabilistic Match",{"type":34,"tag":35,"props":1900,"children":1901},{},[1902,1904,1909],{"type":39,"value":1903},"To identify non-login users beyond a single session, you can use probabilistic identity resolution. Fingerprinting is prohibited (GDPR, ePrivacy), but ",{"type":34,"tag":78,"props":1905,"children":1906},{},[1907],{"type":39,"value":1908},"server-side signal aggregation",{"type":39,"value":1910}," yields similar results.",{"type":34,"tag":35,"props":1912,"children":1913},{},[1914,1916,1922],{"type":39,"value":1915},"In this example, a combination of ",{"type":34,"tag":91,"props":1917,"children":1919},{"className":1918},[],[1920],{"type":39,"value":1921},"user_agent + IP subnet + timezone + screen resolution",{"type":39,"value":1923}," creates a hash:",{"type":34,"tag":84,"props":1925,"children":1927},{"className":626,"code":1926,"language":628,"meta":17,"style":17},"-- BigQuery UDF: probabilistic_user_id\nCREATE TEMP FUNCTION probabilistic_user_id(ua STRING, ip STRING, tz STRING, res STRING)\nRETURNS STRING\nAS (\n  TO_BASE64(SHA256(CONCAT(\n    REGEXP_EXTRACT(ua, r'^[^\u002F]+'),  -- browser family\n    NET.IP_TRUNC(NET.SAFE_IP_FROM_STRING(ip), 24),  -- \u002F24 subnet\n    tz,\n    res\n  )))\n);\n\nSELECT\n  timestamp,\n  session_hash,\n  probabilistic_user_id(user_agent, ip_address, timezone, screen_resolution) AS prob_user_id\nFROM plausible_events;\n",[1928],{"type":34,"tag":91,"props":1929,"children":1930},{"__ignoreMap":17},[1931,1939,1961,1974,1985,2003,2026,2080,2088,2096,2104,2111,2120,2127,2138,2146,2163],{"type":34,"tag":95,"props":1932,"children":1933},{"class":97,"line":98},[1934],{"type":34,"tag":95,"props":1935,"children":1936},{"style":102},[1937],{"type":39,"value":1938},"-- BigQuery UDF: probabilistic_user_id\n",{"type":34,"tag":95,"props":1940,"children":1941},{"class":97,"line":108},[1942,1946,1951,1956],{"type":34,"tag":95,"props":1943,"children":1944},{"style":118},[1945],{"type":39,"value":640},{"type":34,"tag":95,"props":1947,"children":1948},{"style":112},[1949],{"type":39,"value":1950}," TEMP ",{"type":34,"tag":95,"props":1952,"children":1953},{"style":118},[1954],{"type":39,"value":1955},"FUNCTION",{"type":34,"tag":95,"props":1957,"children":1958},{"style":112},[1959],{"type":39,"value":1960}," probabilistic_user_id(ua STRING, ip STRING, tz STRING, res STRING)\n",{"type":34,"tag":95,"props":1962,"children":1963},{"class":97,"line":129},[1964,1969],{"type":34,"tag":95,"props":1965,"children":1966},{"style":118},[1967],{"type":39,"value":1968},"RETURNS",{"type":34,"tag":95,"props":1970,"children":1971},{"style":112},[1972],{"type":39,"value":1973}," STRING\n",{"type":34,"tag":95,"props":1975,"children":1976},{"class":97,"line":160},[1977,1981],{"type":34,"tag":95,"props":1978,"children":1979},{"style":118},[1980],{"type":39,"value":993},{"type":34,"tag":95,"props":1982,"children":1983},{"style":112},[1984],{"type":39,"value":655},{"type":34,"tag":95,"props":1986,"children":1987},{"class":97,"line":227},[1988,1993,1998],{"type":34,"tag":95,"props":1989,"children":1990},{"style":112},[1991],{"type":39,"value":1992},"  TO_BASE64(SHA256(",{"type":34,"tag":95,"props":1994,"children":1995},{"style":138},[1996],{"type":39,"value":1997},"CONCAT",{"type":34,"tag":95,"props":1999,"children":2000},{"style":112},[2001],{"type":39,"value":2002},"(\n",{"type":34,"tag":95,"props":2004,"children":2005},{"class":97,"line":236},[2006,2011,2016,2021],{"type":34,"tag":95,"props":2007,"children":2008},{"style":112},[2009],{"type":39,"value":2010},"    REGEXP_EXTRACT(ua, r",{"type":34,"tag":95,"props":2012,"children":2013},{"style":149},[2014],{"type":39,"value":2015},"'^[^\u002F]+'",{"type":34,"tag":95,"props":2017,"children":2018},{"style":112},[2019],{"type":39,"value":2020},"),  ",{"type":34,"tag":95,"props":2022,"children":2023},{"style":102},[2024],{"type":39,"value":2025},"-- browser family\n",{"type":34,"tag":95,"props":2027,"children":2028},{"class":97,"line":279},[2029,2034,2038,2043,2047,2052,2056,2061,2066,2071,2075],{"type":34,"tag":95,"props":2030,"children":2031},{"style":138},[2032],{"type":39,"value":2033},"    NET",{"type":34,"tag":95,"props":2035,"children":2036},{"style":112},[2037],{"type":39,"value":305},{"type":34,"tag":95,"props":2039,"children":2040},{"style":138},[2041],{"type":39,"value":2042},"IP_TRUNC",{"type":34,"tag":95,"props":2044,"children":2045},{"style":112},[2046],{"type":39,"value":115},{"type":34,"tag":95,"props":2048,"children":2049},{"style":138},[2050],{"type":39,"value":2051},"NET",{"type":34,"tag":95,"props":2053,"children":2054},{"style":112},[2055],{"type":39,"value":305},{"type":34,"tag":95,"props":2057,"children":2058},{"style":138},[2059],{"type":39,"value":2060},"SAFE_IP_FROM_STRING",{"type":34,"tag":95,"props":2062,"children":2063},{"style":112},[2064],{"type":39,"value":2065},"(ip), ",{"type":34,"tag":95,"props":2067,"children":2068},{"style":138},[2069],{"type":39,"value":2070},"24",{"type":34,"tag":95,"props":2072,"children":2073},{"style":112},[2074],{"type":39,"value":2020},{"type":34,"tag":95,"props":2076,"children":2077},{"style":102},[2078],{"type":39,"value":2079},"-- \u002F24 subnet\n",{"type":34,"tag":95,"props":2081,"children":2082},{"class":97,"line":318},[2083],{"type":34,"tag":95,"props":2084,"children":2085},{"style":112},[2086],{"type":39,"value":2087},"    tz,\n",{"type":34,"tag":95,"props":2089,"children":2090},{"class":97,"line":28},[2091],{"type":34,"tag":95,"props":2092,"children":2093},{"style":112},[2094],{"type":39,"value":2095},"    res\n",{"type":34,"tag":95,"props":2097,"children":2098},{"class":97,"line":345},[2099],{"type":34,"tag":95,"props":2100,"children":2101},{"style":112},[2102],{"type":39,"value":2103},"  )))\n",{"type":34,"tag":95,"props":2105,"children":2106},{"class":97,"line":354},[2107],{"type":34,"tag":95,"props":2108,"children":2109},{"style":112},[2110],{"type":39,"value":224},{"type":34,"tag":95,"props":2112,"children":2113},{"class":97,"line":363},[2114],{"type":34,"tag":95,"props":2115,"children":2117},{"emptyLinePlaceholder":2116},true,[2118],{"type":39,"value":2119},"\n",{"type":34,"tag":95,"props":2121,"children":2122},{"class":97,"line":372},[2123],{"type":34,"tag":95,"props":2124,"children":2125},{"style":118},[2126],{"type":39,"value":1268},{"type":34,"tag":95,"props":2128,"children":2129},{"class":97,"line":386},[2130,2134],{"type":34,"tag":95,"props":2131,"children":2132},{"style":118},[2133],{"type":39,"value":663},{"type":34,"tag":95,"props":2135,"children":2136},{"style":112},[2137],{"type":39,"value":673},{"type":34,"tag":95,"props":2139,"children":2140},{"class":97,"line":400},[2141],{"type":34,"tag":95,"props":2142,"children":2143},{"style":112},[2144],{"type":39,"value":2145},"  session_hash,\n",{"type":34,"tag":95,"props":2147,"children":2148},{"class":97,"line":409},[2149,2154,2158],{"type":34,"tag":95,"props":2150,"children":2151},{"style":112},[2152],{"type":39,"value":2153},"  probabilistic_user_id(user_agent, ip_address, timezone, screen_resolution) ",{"type":34,"tag":95,"props":2155,"children":2156},{"style":118},[2157],{"type":39,"value":993},{"type":34,"tag":95,"props":2159,"children":2160},{"style":112},[2161],{"type":39,"value":2162}," prob_user_id\n",{"type":34,"tag":95,"props":2164,"children":2165},{"class":97,"line":418},[2166,2170],{"type":34,"tag":95,"props":2167,"children":2168},{"style":118},[2169],{"type":39,"value":1407},{"type":34,"tag":95,"props":2171,"children":2172},{"style":112},[2173],{"type":39,"value":2174}," plausible_events;\n",{"type":34,"tag":35,"props":2176,"children":2177},{},[2178,2180,2189],{"type":39,"value":2179},"This method isn't 100% certain (different users can hash to the same value, collision rate ~2-4%), but within the ",{"type":34,"tag":2181,"props":2182,"children":2186},"a",{"href":2183,"rel":2184},"https:\u002F\u002Fwww.roibase.com.tr\u002Fen\u002Ffirstparty",[2185],"nofollow",[2187],{"type":39,"value":2188},"First-Party Data & Measurement Architecture",{"type":39,"value":2190}," framework, combining deterministic (user_id) and probabilistic (hash) signals creates \"fuzzy cohorts.\" These cohorts show less deviation in retention rates than GA4's modeled data (in our A\u002FB tests, average 8% deviation vs. 18-22% for GA4 modeled).",{"type":34,"tag":42,"props":2192,"children":2194},{"id":2193},"kvkk-compliance-data-processing-agreement-and-log-retention",[2195],{"type":39,"value":2196},"KVKK Compliance: Data Processing Agreement and Log Retention",{"type":34,"tag":35,"props":2198,"children":2199},{},[2200,2202,2208],{"type":39,"value":2201},"KVKK Article 5: \"Personal data must be processed for specific, explicit, and legitimate purposes.\" An IP address + user agent combination is classified as an \"indirect identifier.\" Plausible receives the IP at the server but doesn't store it in ClickHouse—it only extracts ",{"type":34,"tag":91,"props":2203,"children":2205},{"className":2204},[],[2206],{"type":39,"value":2207},"country",{"type":39,"value":2209}," via GeoIP lookup and drops the IP.",{"type":34,"tag":35,"props":2211,"children":2212},{},[2213],{"type":39,"value":2214},"In self-hosted deployments, you control this flow:",{"type":34,"tag":84,"props":2216,"children":2220},{"className":2217,"code":2218,"language":2219,"meta":17,"style":17},"language-elixir shiki shiki-themes github-dark","# lib\u002Fplausible\u002Fingestion\u002Fevent.ex (simplified)\ndefmodule Plausible.Ingestion.Event do\n  def process(conn, params) do\n    ip = get_ip_address(conn)\n    country = GeoIP.lookup(ip) |> Map.get(:country_code)\n    \n    event = %{\n      timestamp: DateTime.utc_now(),\n      domain: params[\"d\"],\n      session_hash: params[\"h\"],\n      country: country,\n      # IP dropped here\n    }\n    \n    ClickHouse.insert(\"events\", event)\n  end\nend\n","elixir",[2221],{"type":34,"tag":91,"props":2222,"children":2223},{"__ignoreMap":17},[2224,2232,2240,2248,2256,2264,2272,2280,2288,2296,2304,2312,2320,2327,2334,2342,2350],{"type":34,"tag":95,"props":2225,"children":2226},{"class":97,"line":98},[2227],{"type":34,"tag":95,"props":2228,"children":2229},{},[2230],{"type":39,"value":2231},"# lib\u002Fplausible\u002Fingestion\u002Fevent.ex (simplified)\n",{"type":34,"tag":95,"props":2233,"children":2234},{"class":97,"line":108},[2235],{"type":34,"tag":95,"props":2236,"children":2237},{},[2238],{"type":39,"value":2239},"defmodule Plausible.Ingestion.Event do\n",{"type":34,"tag":95,"props":2241,"children":2242},{"class":97,"line":129},[2243],{"type":34,"tag":95,"props":2244,"children":2245},{},[2246],{"type":39,"value":2247},"  def process(conn, params) do\n",{"type":34,"tag":95,"props":2249,"children":2250},{"class":97,"line":160},[2251],{"type":34,"tag":95,"props":2252,"children":2253},{},[2254],{"type":39,"value":2255},"    ip = get_ip_address(conn)\n",{"type":34,"tag":95,"props":2257,"children":2258},{"class":97,"line":227},[2259],{"type":34,"tag":95,"props":2260,"children":2261},{},[2262],{"type":39,"value":2263},"    country = GeoIP.lookup(ip) |> Map.get(:country_code)\n",{"type":34,"tag":95,"props":2265,"children":2266},{"class":97,"line":236},[2267],{"type":34,"tag":95,"props":2268,"children":2269},{},[2270],{"type":39,"value":2271},"    \n",{"type":34,"tag":95,"props":2273,"children":2274},{"class":97,"line":279},[2275],{"type":34,"tag":95,"props":2276,"children":2277},{},[2278],{"type":39,"value":2279},"    event = %{\n",{"type":34,"tag":95,"props":2281,"children":2282},{"class":97,"line":318},[2283],{"type":34,"tag":95,"props":2284,"children":2285},{},[2286],{"type":39,"value":2287},"      timestamp: DateTime.utc_now(),\n",{"type":34,"tag":95,"props":2289,"children":2290},{"class":97,"line":28},[2291],{"type":34,"tag":95,"props":2292,"children":2293},{},[2294],{"type":39,"value":2295},"      domain: params[\"d\"],\n",{"type":34,"tag":95,"props":2297,"children":2298},{"class":97,"line":345},[2299],{"type":34,"tag":95,"props":2300,"children":2301},{},[2302],{"type":39,"value":2303},"      session_hash: params[\"h\"],\n",{"type":34,"tag":95,"props":2305,"children":2306},{"class":97,"line":354},[2307],{"type":34,"tag":95,"props":2308,"children":2309},{},[2310],{"type":39,"value":2311},"      country: country,\n",{"type":34,"tag":95,"props":2313,"children":2314},{"class":97,"line":363},[2315],{"type":34,"tag":95,"props":2316,"children":2317},{},[2318],{"type":39,"value":2319},"      # IP dropped here\n",{"type":34,"tag":95,"props":2321,"children":2322},{"class":97,"line":372},[2323],{"type":34,"tag":95,"props":2324,"children":2325},{},[2326],{"type":39,"value":574},{"type":34,"tag":95,"props":2328,"children":2329},{"class":97,"line":386},[2330],{"type":34,"tag":95,"props":2331,"children":2332},{},[2333],{"type":39,"value":2271},{"type":34,"tag":95,"props":2335,"children":2336},{"class":97,"line":400},[2337],{"type":34,"tag":95,"props":2338,"children":2339},{},[2340],{"type":39,"value":2341},"    ClickHouse.insert(\"events\", event)\n",{"type":34,"tag":95,"props":2343,"children":2344},{"class":97,"line":409},[2345],{"type":34,"tag":95,"props":2346,"children":2347},{},[2348],{"type":39,"value":2349},"  end\n",{"type":34,"tag":95,"props":2351,"children":2352},{"class":97,"line":418},[2353],{"type":34,"tag":95,"props":2354,"children":2355},{},[2356],{"type":39,"value":2357},"end\n",{"type":34,"tag":35,"props":2359,"children":2360},{},[2361],{"type":39,"value":2362},"KVKK Article 7: \"Data may be retained as long as the processing purpose requires.\" For analytics, typical retention is 24-36 months. Set TTL in ClickHouse via partition:",{"type":34,"tag":84,"props":2364,"children":2366},{"className":626,"code":2365,"language":628,"meta":17,"style":17},"ALTER TABLE events\nMODIFY TTL toDate(timestamp) + INTERVAL 36 MONTH;\n",[2367],{"type":34,"tag":91,"props":2368,"children":2369},{"__ignoreMap":17},[2370,2387],{"type":34,"tag":95,"props":2371,"children":2372},{"class":97,"line":98},[2373,2378,2382],{"type":34,"tag":95,"props":2374,"children":2375},{"style":118},[2376],{"type":39,"value":2377},"ALTER",{"type":34,"tag":95,"props":2379,"children":2380},{"style":118},[2381],{"type":39,"value":645},{"type":34,"tag":95,"props":2383,"children":2384},{"style":112},[2385],{"type":39,"value":2386}," events\n",{"type":34,"tag":95,"props":2388,"children":2389},{"class":97,"line":108},[2390,2395,2400,2404,2408,2412,2417,2422,2427],{"type":34,"tag":95,"props":2391,"children":2392},{"style":118},[2393],{"type":39,"value":2394},"MODIFY",{"type":34,"tag":95,"props":2396,"children":2397},{"style":112},[2398],{"type":39,"value":2399}," TTL toDate(",{"type":34,"tag":95,"props":2401,"children":2402},{"style":118},[2403],{"type":39,"value":841},{"type":34,"tag":95,"props":2405,"children":2406},{"style":112},[2407],{"type":39,"value":500},{"type":34,"tag":95,"props":2409,"children":2410},{"style":118},[2411],{"type":39,"value":190},{"type":34,"tag":95,"props":2413,"children":2414},{"style":112},[2415],{"type":39,"value":2416}," INTERVAL ",{"type":34,"tag":95,"props":2418,"children":2419},{"style":138},[2420],{"type":39,"value":2421},"36",{"type":34,"tag":95,"props":2423,"children":2424},{"style":118},[2425],{"type":39,"value":2426}," MONTH",{"type":34,"tag":95,"props":2428,"children":2429},{"style":112},[2430],{"type":39,"value":157},{"type":34,"tag":35,"props":2432,"children":2433},{},[2434,2436,2442],{"type":39,"value":2435},"Partitions are automatically deleted after 36 months. GA4 resets ",{"type":34,"tag":91,"props":2437,"children":2439},{"className":2438},[],[2440],{"type":39,"value":2441},"user_pseudo_id",{"type":39,"value":2443}," after 14 months, but BigQuery export can be retained up to 60 months (though export requires GA360).",{"type":34,"tag":35,"props":2445,"children":2446},{},[2447],{"type":39,"value":2448},"KVKK Data Processing Agreement: Using Plausible Cloud requires signing a DPA. Plausible is hosted in the EU (Hetzner, Germany) and provides a GDPR-compliant DPA template. Self-hosted means data is yours alone—no \"data processor,\" only \"data controller.\"",{"type":34,"tag":42,"props":2450,"children":2452},{"id":2451},"conversion-api-integration-server-side-event-forwarding",[2453],{"type":39,"value":2454},"Conversion API Integration: Server-Side Event Forwarding",{"type":34,"tag":35,"props":2456,"children":2457},{},[2458],{"type":39,"value":2459},"You can forward Plausible events to Meta\u002FGoogle Ads via a webhook-based pipeline. Plausible doesn't have a native API, but streaming exports from ClickHouse to BigQuery can trigger a Cloud Function:",{"type":34,"tag":84,"props":2461,"children":2463},{"className":86,"code":2462,"language":88,"meta":17,"style":17},"\u002F\u002F Cloud Function: plausible-to-meta-capi\nconst axios = require('axios');\n\nexports.forwardEvent = async (event, context) => {\n  const pubsubMessage = Buffer.from(event.data, 'base64').toString();\n  const plausibleEvent = JSON.parse(pubsubMessage);\n  \n  if (plausibleEvent.event_name === 'Purchase') {\n    await axios.post('https:\u002F\u002Fgraph.facebook.com\u002Fv18.0\u002F{pixel_id}\u002Fevents', {\n      data: [{\n        event_name: 'Purchase',\n        event_time: Math.floor(plausibleEvent.timestamp \u002F 1000),\n        user_data: {\n          client_ip_address: plausibleEvent.ip_address,  \u002F\u002F hashed\n          client_user_agent: plausibleEvent.user_agent,\n        },\n        custom_data: {\n          value: plausibleEvent.props.order_value,\n          currency: 'EUR',\n        },\n      }],\n      access_token: process.env.META_ACCESS_TOKEN,\n    });\n  }\n};\n",[2464],{"type":34,"tag":91,"props":2465,"children":2466},{"__ignoreMap":17},[2467,2475,2510,2517,2574,2625,2660,2667,2695,2727,2735,2752,2784,2792,2805,2813,2821,2829,2837,2854,2861,2869,2886,2894,2901],{"type":34,"tag":95,"props":2468,"children":2469},{"class":97,"line":98},[2470],{"type":34,"tag":95,"props":2471,"children":2472},{"style":102},[2473],{"type":39,"value":2474},"\u002F\u002F Cloud Function: plausible-to-meta-capi\n",{"type":34,"tag":95,"props":2476,"children":2477},{"class":97,"line":108},[2478,2483,2488,2492,2497,2501,2506],{"type":34,"tag":95,"props":2479,"children":2480},{"style":118},[2481],{"type":39,"value":2482},"const",{"type":34,"tag":95,"props":2484,"children":2485},{"style":138},[2486],{"type":39,"value":2487}," axios",{"type":34,"tag":95,"props":2489,"children":2490},{"style":118},[2491],{"type":39,"value":146},{"type":34,"tag":95,"props":2493,"children":2494},{"style":177},[2495],{"type":39,"value":2496}," require",{"type":34,"tag":95,"props":2498,"children":2499},{"style":112},[2500],{"type":39,"value":115},{"type":34,"tag":95,"props":2502,"children":2503},{"style":149},[2504],{"type":39,"value":2505},"'axios'",{"type":34,"tag":95,"props":2507,"children":2508},{"style":112},[2509],{"type":39,"value":224},{"type":34,"tag":95,"props":2511,"children":2512},{"class":97,"line":129},[2513],{"type":34,"tag":95,"props":2514,"children":2515},{"emptyLinePlaceholder":2116},[2516],{"type":39,"value":2119},{"type":34,"tag":95,"props":2518,"children":2519},{"class":97,"line":160},[2520,2525,2529,2534,2538,2543,2548,2553,2557,2562,2566,2570],{"type":34,"tag":95,"props":2521,"children":2522},{"style":138},[2523],{"type":39,"value":2524},"exports",{"type":34,"tag":95,"props":2526,"children":2527},{"style":112},[2528],{"type":39,"value":305},{"type":34,"tag":95,"props":2530,"children":2531},{"style":177},[2532],{"type":39,"value":2533},"forwardEvent",{"type":34,"tag":95,"props":2535,"children":2536},{"style":118},[2537],{"type":39,"value":146},{"type":34,"tag":95,"props":2539,"children":2540},{"style":118},[2541],{"type":39,"value":2542}," async",{"type":34,"tag":95,"props":2544,"children":2545},{"style":112},[2546],{"type":39,"value":2547}," (",{"type":34,"tag":95,"props":2549,"children":2550},{"style":254},[2551],{"type":39,"value":2552},"event",{"type":34,"tag":95,"props":2554,"children":2555},{"style":112},[2556],{"type":39,"value":262},{"type":34,"tag":95,"props":2558,"children":2559},{"style":254},[2560],{"type":39,"value":2561},"context",{"type":34,"tag":95,"props":2563,"children":2564},{"style":112},[2565],{"type":39,"value":500},{"type":34,"tag":95,"props":2567,"children":2568},{"style":118},[2569],{"type":39,"value":505},{"type":34,"tag":95,"props":2571,"children":2572},{"style":112},[2573],{"type":39,"value":510},{"type":34,"tag":95,"props":2575,"children":2576},{"class":97,"line":227},[2577,2581,2586,2590,2595,2600,2605,2610,2615,2620],{"type":34,"tag":95,"props":2578,"children":2579},{"style":118},[2580],{"type":39,"value":135},{"type":34,"tag":95,"props":2582,"children":2583},{"style":138},[2584],{"type":39,"value":2585}," pubsubMessage",{"type":34,"tag":95,"props":2587,"children":2588},{"style":118},[2589],{"type":39,"value":146},{"type":34,"tag":95,"props":2591,"children":2592},{"style":112},[2593],{"type":39,"value":2594}," Buffer.",{"type":34,"tag":95,"props":2596,"children":2597},{"style":177},[2598],{"type":39,"value":2599},"from",{"type":34,"tag":95,"props":2601,"children":2602},{"style":112},[2603],{"type":39,"value":2604},"(event.data, ",{"type":34,"tag":95,"props":2606,"children":2607},{"style":149},[2608],{"type":39,"value":2609},"'base64'",{"type":34,"tag":95,"props":2611,"children":2612},{"style":112},[2613],{"type":39,"value":2614},").",{"type":34,"tag":95,"props":2616,"children":2617},{"style":177},[2618],{"type":39,"value":2619},"toString",{"type":34,"tag":95,"props":2621,"children":2622},{"style":112},[2623],{"type":39,"value":2624},"();\n",{"type":34,"tag":95,"props":2626,"children":2627},{"class":97,"line":236},[2628,2632,2637,2641,2646,2650,2655],{"type":34,"tag":95,"props":2629,"children":2630},{"style":118},[2631],{"type":39,"value":135},{"type":34,"tag":95,"props":2633,"children":2634},{"style":138},[2635],{"type":39,"value":2636}," plausibleEvent",{"type":34,"tag":95,"props":2638,"children":2639},{"style":118},[2640],{"type":39,"value":146},{"type":34,"tag":95,"props":2642,"children":2643},{"style":138},[2644],{"type":39,"value":2645}," JSON",{"type":34,"tag":95,"props":2647,"children":2648},{"style":112},[2649],{"type":39,"value":305},{"type":34,"tag":95,"props":2651,"children":2652},{"style":177},[2653],{"type":39,"value":2654},"parse",{"type":34,"tag":95,"props":2656,"children":2657},{"style":112},[2658],{"type":39,"value":2659},"(pubsubMessage);\n",{"type":34,"tag":95,"props":2661,"children":2662},{"class":97,"line":279},[2663],{"type":34,"tag":95,"props":2664,"children":2665},{"style":112},[2666],{"type":39,"value":233},{"type":34,"tag":95,"props":2668,"children":2669},{"class":97,"line":318},[2670,2675,2680,2685,2690],{"type":34,"tag":95,"props":2671,"children":2672},{"style":118},[2673],{"type":39,"value":2674},"  if",{"type":34,"tag":95,"props":2676,"children":2677},{"style":112},[2678],{"type":39,"value":2679}," (plausibleEvent.event_name ",{"type":34,"tag":95,"props":2681,"children":2682},{"style":118},[2683],{"type":39,"value":2684},"===",{"type":34,"tag":95,"props":2686,"children":2687},{"style":149},[2688],{"type":39,"value":2689}," 'Purchase'",{"type":34,"tag":95,"props":2691,"children":2692},{"style":112},[2693],{"type":39,"value":2694},") {\n",{"type":34,"tag":95,"props":2696,"children":2697},{"class":97,"line":28},[2698,2703,2708,2713,2717,2722],{"type":34,"tag":95,"props":2699,"children":2700},{"style":118},[2701],{"type":39,"value":2702},"    await",{"type":34,"tag":95,"props":2704,"children":2705},{"style":112},[2706],{"type":39,"value":2707}," axios.",{"type":34,"tag":95,"props":2709,"children":2710},{"style":177},[2711],{"type":39,"value":2712},"post",{"type":34,"tag":95,"props":2714,"children":2715},{"style":112},[2716],{"type":39,"value":115},{"type":34,"tag":95,"props":2718,"children":2719},{"style":149},[2720],{"type":39,"value":2721},"'https:\u002F\u002Fgraph.facebook.com\u002Fv18.0\u002F{pixel_id}\u002Fevents'",{"type":34,"tag":95,"props":2723,"children":2724},{"style":112},[2725],{"type":39,"value":2726},", {\n",{"type":34,"tag":95,"props":2728,"children":2729},{"class":97,"line":345},[2730],{"type":34,"tag":95,"props":2731,"children":2732},{"style":112},[2733],{"type":39,"value":2734},"      data: [{\n",{"type":34,"tag":95,"props":2736,"children":2737},{"class":97,"line":354},[2738,2743,2748],{"type":34,"tag":95,"props":2739,"children":2740},{"style":112},[2741],{"type":39,"value":2742},"        event_name: ",{"type":34,"tag":95,"props":2744,"children":2745},{"style":149},[2746],{"type":39,"value":2747},"'Purchase'",{"type":34,"tag":95,"props":2749,"children":2750},{"style":112},[2751],{"type":39,"value":673},{"type":34,"tag":95,"props":2753,"children":2754},{"class":97,"line":363},[2755,2760,2765,2770,2775,2780],{"type":34,"tag":95,"props":2756,"children":2757},{"style":112},[2758],{"type":39,"value":2759},"        event_time: Math.",{"type":34,"tag":95,"props":2761,"children":2762},{"style":177},[2763],{"type":39,"value":2764},"floor",{"type":34,"tag":95,"props":2766,"children":2767},{"style":112},[2768],{"type":39,"value":2769},"(plausibleEvent.timestamp ",{"type":34,"tag":95,"props":2771,"children":2772},{"style":118},[2773],{"type":39,"value":2774},"\u002F",{"type":34,"tag":95,"props":2776,"children":2777},{"style":138},[2778],{"type":39,"value":2779}," 1000",{"type":34,"tag":95,"props":2781,"children":2782},{"style":112},[2783],{"type":39,"value":1132},{"type":34,"tag":95,"props":2785,"children":2786},{"class":97,"line":372},[2787],{"type":34,"tag":95,"props":2788,"children":2789},{"style":112},[2790],{"type":39,"value":2791},"        user_data: {\n",{"type":34,"tag":95,"props":2793,"children":2794},{"class":97,"line":386},[2795,2800],{"type":34,"tag":95,"props":2796,"children":2797},{"style":112},[2798],{"type":39,"value":2799},"          client_ip_address: plausibleEvent.ip_address,  ",{"type":34,"tag":95,"props":2801,"children":2802},{"style":102},[2803],{"type":39,"value":2804},"\u002F\u002F hashed\n",{"type":34,"tag":95,"props":2806,"children":2807},{"class":97,"line":400},[2808],{"type":34,"tag":95,"props":2809,"children":2810},{"style":112},[2811],{"type":39,"value":2812},"          client_user_agent: plausibleEvent.user_agent,\n",{"type":34,"tag":95,"props":2814,"children":2815},{"class":97,"line":409},[2816],{"type":34,"tag":95,"props":2817,"children":2818},{"style":112},[2819],{"type":39,"value":2820},"        },\n",{"type":34,"tag":95,"props":2822,"children":2823},{"class":97,"line":418},[2824],{"type":34,"tag":95,"props":2825,"children":2826},{"style":112},[2827],{"type":39,"value":2828},"        custom_data: {\n",{"type":34,"tag":95,"props":2830,"children":2831},{"class":97,"line":426},[2832],{"type":34,"tag":95,"props":2833,"children":2834},{"style":112},[2835],{"type":39,"value":2836},"          value: plausibleEvent.props.order_value,\n",{"type":34,"tag":95,"props":2838,"children":2839},{"class":97,"line":448},[2840,2845,2850],{"type":34,"tag":95,"props":2841,"children":2842},{"style":112},[2843],{"type":39,"value":2844},"          currency: ",{"type":34,"tag":95,"props":2846,"children":2847},{"style":149},[2848],{"type":39,"value":2849},"'EUR'",{"type":34,"tag":95,"props":2851,"children":2852},{"style":112},[2853],{"type":39,"value":673},{"type":34,"tag":95,"props":2855,"children":2856},{"class":97,"line":456},[2857],{"type":34,"tag":95,"props":2858,"children":2859},{"style":112},[2860],{"type":39,"value":2820},{"type":34,"tag":95,"props":2862,"children":2863},{"class":97,"line":465},[2864],{"type":34,"tag":95,"props":2865,"children":2866},{"style":112},[2867],{"type":39,"value":2868},"      }],\n",{"type":34,"tag":95,"props":2870,"children":2871},{"class":97,"line":513},[2872,2877,2882],{"type":34,"tag":95,"props":2873,"children":2874},{"style":112},[2875],{"type":39,"value":2876},"      access_token: process.env.",{"type":34,"tag":95,"props":2878,"children":2879},{"style":138},[2880],{"type":39,"value":2881},"META_ACCESS_TOKEN",{"type":34,"tag":95,"props":2883,"children":2884},{"style":112},[2885],{"type":39,"value":673},{"type":34,"tag":95,"props":2887,"children":2888},{"class":97,"line":546},[2889],{"type":34,"tag":95,"props":2890,"children":2891},{"style":112},[2892],{"type":39,"value":2893},"    });\n",{"type":34,"tag":95,"props":2895,"children":2896},{"class":97,"line":568},[2897],{"type":34,"tag":95,"props":2898,"children":2899},{"style":112},[2900],{"type":39,"value":415},{"type":34,"tag":95,"props":2902,"children":2903},{"class":97,"line":577},[2904],{"type":34,"tag":95,"props":2905,"children":2906},{"style":112},[2907],{"type":39,"value":2908},"};\n",{"type":34,"tag":35,"props":2910,"children":2911},{},[2912],{"type":39,"value":2913},"This approach is similar to GA4's Measurement Protocol but with a key advantage: events from Plausible are already cookieless, so Consent Mode v2's \"denied\" state doesn't apply. Meta CAPI server events can be marked \"consented\" because IP\u002FUA were collected server-side, not from client cookies.",{"type":34,"tag":2915,"props":2916,"children":2917},"hr",{},[],{"type":34,"tag":35,"props":2919,"children":2920},{},[2921],{"type":39,"value":2922},"Privacy-first analytics stacks are no longer \"nice to have\" as of 2026—they're compliance requirements. Plausible + server-side aggregation delivers less deviation than GA4's modeled-data approach, lower cost, and complete data ownership. On sites with 30%+ login rates, cohort retention analysis is possible; probabilistic identity resolution can even bring anonymous users into fuzzy segments. KVKK\u002FGDPR compliance is default, consent-banner complexity vanishes. The only tradeoff: no cross-device tracking—but by 2026, ITP + Privacy Sandbox have made cross-device tracking an artifact anyway.",{"type":34,"tag":2924,"props":2925,"children":2926},"style",{},[2927],{"type":39,"value":2928},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":17,"searchDepth":129,"depth":129,"links":2930},[2931,2932,2933,2934,2935,2936,2937],{"id":44,"depth":108,"text":47},{"id":65,"depth":108,"text":68},{"id":875,"depth":108,"text":878},{"id":1732,"depth":108,"text":1735},{"id":1895,"depth":108,"text":1898},{"id":2193,"depth":108,"text":2196},{"id":2451,"depth":108,"text":2454},"markdown","content:en:data:privacy-first-analytics-plausible-server-side.md","content","en\u002Fdata\u002Fprivacy-first-analytics-plausible-server-side.md","en\u002Fdata\u002Fprivacy-first-analytics-plausible-server-side","md",1785967475784]