Writeups from client projects
Long-form breakdowns of attribution, server-side tracking and measurement infrastructure I built for banks, insurers and marketplaces. What the problem was, what shipped, what broke.
Learning the fundamentals instead? Start with Academia →
Marketing mix modeling: what it measures, how it works and when it pays off
What marketing mix modeling answers and what it cannot, how adstock and saturation work, ROI vs marginal ROI, and the data you need before you start.

Google Meridian: how the Bayesian MMM works and how to read its results
Google Meridian 2.1 explained: the model in its own notation, ROI priors and experiment calibration, health checks, and why mROI, not ROI, should move budget.

Geo experiments with GeoX and GeoLift: measuring incremental lift and calibrating MMM
How to prove a channel is incremental with a geo test: holdback, go-dark and heavy-up, TBR and synthetic control, power and MDE, and calibrating MMM.

Meridian vs Robyn vs PyMC-Marketing: which MMM framework to choose in 2026
Meridian, Robyn or PyMC-Marketing in 2026: status, estimation methods, calibration with experiments, geo support and which one fits your team.

Brand Lift studies: how to set one up, and how to read a result that says "+4 points"
A Brand Lift study holds your ad back from a random part of the audience and surveys both groups. On YouTube it starts at $5,000 in the first ten days for one question in Kazakhstan, and detecting a 2-point lift takes about 9,642 survey responses.

Conversion Lift: the holdout test that shows which conversions your ads caused
A conversion lift test withholds ads from a random holdout and compares conversion rates. In the worked example the platform attributes 3,000 conversions and the experiment finds 900, and detecting a 10% lift takes about 547 conversions in a 10% holdout.

Measuring brand awareness: top of mind, spontaneous, aided, and the math for reading a tracker
Brand awareness is three nested numbers: top of mind, spontaneous and aided. With 600 respondents per wave each carries up to 4.0 points of margin, and a change needs 5 to 8 points before it can be told from noise.

Superapp analytics: four ways measurement breaks inside a native shell, and what holds
Where superapp measurement breaks: the deep-link hop, paid versus internal WebView traffic, growth stuck on KYC, and in-app browsers. Plus the three rules that hold across all four.

GA4 vs Amplitude for a superapp: what the licence costs you, and what the taxonomy costs you
For a superapp, usually both: GA4 for ads and channels, Amplitude for funnels and retention. Where GA4's quotas break, what Amplitude charges for, and why the taxonomy is the real cost.

AppsFlyer vs Adjust vs Firebase-only: when an MMP is actually worth paying for
Three tests for whether you need an MMP or Firebase is enough, and the two AppsFlyer vs Adjust differences that mattered in a banking S2S integration: billing and event setup.

Do you actually need a CDP? Four tests before you sign anything
Most CDP requests are a taxonomy, identity or activation problem. Four tests to tell which one you have, when a CDP is the right buy, and the cheaper stack for everything else.

Two hundred events, thirty-five that matter: rebuilding an Amplitude taxonomy at superapp scale
How 200-plus Amplitude event types across 18-plus prefixes collapse to 35: one required product_type, a server-side payment event, typed properties and the migration step everyone skips.

GA4 has an AI Assistant channel now. It still won't tell you how much AI traffic you get
GA4's AI Assistant channel, added on 13 May 2026, only sees AI visits with a referrer. What it misses, the custom channel group that fills the gap, and how to size what lands in Direct.

Consent Mode v2 and server-side GTM: moving the tags didn't move the obligation
Why server-side GTM does not gate non-Google tags on consent, the four things to wire in the server container, the denied-state test, and the payload check consent never covers.

What server-side GTM actually costs to run
Cloud Run's floor is around $135/month by Google's own numbers. Published rates and arithmetic for Cloud Run, Stape, a VPS and Cloudflare Containers, plus the costs pricing pages leave out.

Attribution inside a SuperApp WebView: getting the source into Amplitude without polluting the paid channel
How to get each WebView session's layer and source into Amplitude from the native launch URL, keep internal traffic out of the paid channel, and count revenue server-side.

Instagram and Facebook leads straight into your CRM, with a Cloudflare Worker instead of Zapier or a VPS
A working Meta Lead Ads to CRM bridge on a Cloudflare Worker: signatures both ways, Graph API lookup, Meta's retries as the queue, and the form_name bug a test lead caught.

Google Ads sees the leads but not the money: fixing a broken gclid chain
Why Google Ads shows leads but no disbursements: a redirect tracker dropped the gclid on its 302 and the backend never read it. How we rebuilt the chain to a server-side purchase.

Tracking a funnel on a SPA you don't control, with a fetch/XHR interceptor in GTM
How a GTM tag that patches fetch and XMLHttpRequest qualifies leads on a SPA you can't change, feeds value-based bidding, and why passive capture can break without a single error.

O2O Banking: connecting digital advertising to branch visits, loan disbursements, and deposits
The full bank O2O architecture: click capture, branch handoff via lead_id, an offline event ledger, margin-based value and postbacks to Google Ads and Meta CAPI, with QA and SQL checks.

Deep links for a Halyk-class SuperApp: WebView services, cross-auth, and lossless UTM/MMP attribution
How to get an ad click onto the exact deposit, payment or WebView service in a banking SuperApp: link templates, a ctx_id ledger across login and KYC, and MMP merge rules.

A SuperApp cannot be grown on KYC alone: Firebase events, a value model, and tROAS for product growth
How to move a banking SuperApp's app campaigns from KYC to product value: event taxonomy, margin-based value instead of principal, Firebase setup, and when to switch to tROAS.

When TikTok and Instagram open your site inside the app: keeping attribution, events, and CAPI working without hacks
Why TikTok and Instagram in-app browsers lose click IDs and events, and a four-layer fix: a server-side landing bridge, first-party IDs, the Pixel, and CAPI with one shared event_id.

The end of rented audiences: why businesses are building their own DWHs and collecting First-Party Data
Why privacy rules turn rented Meta and Google audiences into a business risk, and how a warehouse plus Reverse ETL turns your own first-party data back into campaigns.

The end of the Pixel era: why businesses should move to CAPI and CAPIG
What Meta's CAPI and the CAPIG gateway do when the browser Pixel misses conversions, and when server-side GTM is the better choice for multi-channel buying.

How to connect online advertising with offline sales: building transparent O2O analytics
The general CRM loop for offline sales: save GCLID and Client ID with each lead in amoCRM or Bitrix24, then return won deals via GA4 Measurement Protocol and Google Ads.

How SKAdNetwork actually works: an iOS analytics guide without rose-tinted glasses
How SKAN timers delay postbacks by 24-48 hours, what the MMP does with conversion values from 0 to 63, and how to join SKAN, MMP and Firebase data in BigQuery for Blended ROAS.
Seeing this in your own funnel?
These are field notes from client work, not tutorials. If one of them reads like your own setup,