This recipe produces a live, auto-refreshing marketing dashboard that unifies data from GA4 (web traffic and conversions), ad platforms (Google Ads, Meta Ads, LinkedIn Ads spend and performance), CRM (pipeline and revenue attribution), and email marketing (campaign engagement and conversion) into a single interactive view — deployed in Looker Studio or Metabase with automated weekly PDF reports to stakeholders. [src1]
Which path?
├── User is non-technical AND budget = free
│ └── PATH A: Looker Studio + Native Connectors (GA4, Google Ads only)
├── User is non-technical AND budget > $0
│ └── PATH B: Looker Studio + Supermetrics (all sources)
├── User is semi-technical or developer AND budget = free
│ └── PATH C: Looker Studio + BigQuery + Free ETL (Airbyte/scripts)
└── User is developer AND budget > $0
└── PATH D: Metabase + BigQuery + Paid Connectors (full control)
| Path | Tools | Cost | Speed | Output Quality |
|---|---|---|---|---|
| A: No-Code Free | Looker Studio + native connectors | $0 | 2-3 hours | Basic — Google sources only |
| B: No-Code Paid | Looker Studio + Supermetrics | $39-200/mo | 3-5 hours | Good — all sources, limited modeling |
| C: Code + Free | Looker Studio + BigQuery + Airbyte | $0 | 6-8 hours | Excellent — full join control |
| D: Code + Paid | Metabase + BigQuery + Fivetran | $50-400/mo | 6-10 hours | Excellent — full SQL control |
Duration: 30-60 minutes · Tool: Spreadsheet
Catalog every data source, confirm access credentials, and document key metrics each source provides. This prevents mid-build discovery of missing access.
| Source | Key Metrics | Connector Type |
|---|---|---|
| GA4 | Sessions, users, conversions, revenue | Native or BigQuery export |
| Google Ads | Spend, clicks, impressions, CPA, ROAS | Native or API |
| Meta Ads | Spend, reach, CPM, CPA, conversions | Supermetrics or API |
| LinkedIn Ads | Spend, clicks, leads, CPL | Supermetrics or API |
| HubSpot/Salesforce | Leads, MQLs, SQLs, pipeline, revenue | API or Supermetrics |
| Email platform | Sends, opens, clicks, conversions | API or Supermetrics |
Verify: All data sources accessible and returning data. · If failed: Request missing credentials from the relevant team before proceeding.
Duration: 1-2 hours · Tool: Looker Studio, Supermetrics, or BigQuery
Path A/B: Add GA4 and Google Ads via native Looker Studio connectors. For Meta/LinkedIn/CRM/email, add Supermetrics connector (Path B).
Path C/D: Enable GA4 BigQuery export (GA4 Admin > BigQuery Links), then set up extraction scripts or Airbyte pipelines for each non-Google source. [src1]
-- Verify GA4 BigQuery export is working:
SELECT COUNT(*) as event_count,
FORMAT_DATE('%Y-%m-%d', PARSE_DATE('%Y%m%d', event_date)) as date
FROM `your-project.analytics_123456789.events_*`
WHERE _TABLE_SUFFIX >= FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE(), INTERVAL 7 DAY))
GROUP BY date ORDER BY date DESC;
Verify: Each data source returns recent data (within 48 hours). · If failed: GA4 BigQuery export takes up to 24 hours after enabling. For API errors, verify credentials.
Duration: 1-3 hours · Tool: BigQuery SQL (Path C/D) or Looker Studio blending (Path A/B)
Create a unified data model joining traffic, spend, conversions, pipeline, and email data on common keys (date, UTM campaign, source/medium).
-- Core marketing performance model (BigQuery)
CREATE OR REPLACE TABLE marketing_analytics.daily_channel_performance AS
WITH ga4_traffic AS (
SELECT PARSE_DATE('%Y%m%d', event_date) AS date,
traffic_source.source AS source, traffic_source.medium AS medium,
COUNT(DISTINCT user_pseudo_id) AS users,
COUNTIF(event_name = 'session_start') AS sessions,
COUNTIF(event_name IN ('purchase','sign_up','generate_lead')) AS conversions
FROM `your-project.analytics_123456789.events_*`
WHERE _TABLE_SUFFIX >= FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE(), INTERVAL 90 DAY))
GROUP BY 1, 2, 3
),
ad_spend AS (
SELECT date, source, medium, SUM(spend) AS spend, SUM(clicks) AS ad_clicks
FROM marketing_staging.unified_ad_spend GROUP BY 1, 2, 3
)
SELECT t.*, COALESCE(a.spend,0) AS spend, COALESCE(a.ad_clicks,0) AS ad_clicks,
SAFE_DIVIDE(COALESCE(a.spend,0), NULLIF(t.conversions,0)) AS cpa
FROM ga4_traffic t LEFT JOIN ad_spend a USING (date, source, medium);
Verify: Joined table has spend aligned with conversions. Check for UTM mismatches where spend > 0 but conversions = 0. · If failed: Apply LOWER() and TRIM() to all join keys.
Duration: 1-2 hours · Tool: Looker Studio or Metabase
Build the dashboard with 4 pages: Executive Summary (spend, revenue, ROAS, CPA scorecards and trends), Acquisition Channels (traffic by source, ad performance tables), Conversion Funnel (visitors > leads > MQLs > SQLs > closed-won), and Email Performance (open rate, CTR, campaign table). [src5] [src6]
Verify: All widgets display data. Date range filter updates all charts. Compare totals to native platform numbers (expect 5-15% variance). · If failed: Check data source connections and date range coverage.
Duration: 30-60 minutes · Tool: Looker Studio calculated fields or BigQuery views
| Metric | Formula | Purpose |
|---|---|---|
| Blended CPA | Total spend / total conversions | Overall cost efficiency |
| Blended ROAS | Total revenue / total spend | Return on ad investment |
| CAC | Total marketing spend / new customers | True acquisition cost |
| MQL-to-SQL rate | SQLs / MQLs | Funnel health indicator |
| Pipeline velocity | (SQLs × avg deal size × win rate) / avg cycle days | Revenue forecasting |
Verify: Calculated fields return reasonable values. · If failed: Wrap divisions in SAFE_DIVIDE or NULLIF.
Duration: 30 minutes · Tool: Looker Studio scheduled email or Metabase subscriptions
Schedule weekly PDF delivery (Mondays at 8 AM) to stakeholders. Set up anomaly alerts: spend exceeding daily budget by 20%, CPA exceeding target by 50% for 3 consecutive days, conversion rate dropping below historical average.
Verify: Trigger a test email. Confirm all pages render in PDF format. · If failed: Reduce widgets per page or switch to landscape orientation.
{
"output_type": "marketing_dashboard",
"format": "Interactive dashboard URL + scheduled PDF",
"pages": [
{"name": "Executive Summary", "widgets": ["total_spend","total_revenue","blended_roas","blended_cpa","spend_vs_revenue_trend","channel_breakdown"]},
{"name": "Acquisition Channels", "widgets": ["traffic_by_source","ad_performance_table","platform_comparison","cpl_by_channel"]},
{"name": "Conversion Funnel", "widgets": ["funnel_viz","stage_conversion_rates","pipeline_by_source"]},
{"name": "Email Performance", "widgets": ["email_scorecards","campaign_table","list_growth_trend"]}
],
"data_refresh": "daily (BigQuery export) or real-time (native connectors)",
"report_schedule": "weekly PDF via email"
}
| Quality Metric | Minimum Acceptable | Good | Excellent |
|---|---|---|---|
| Data source coverage | GA4 + 1 ad platform | GA4 + 2 ad platforms + CRM | GA4 + all ad platforms + CRM + email |
| Dashboard load time (90 days) | < 15 seconds | < 10 seconds | < 5 seconds |
| Data freshness | Daily refresh | 4-6 hour refresh | Near real-time (< 30 min) |
| Metric accuracy vs native platforms | Within 20% | Within 10% | Within 5% |
| Stakeholder adoption (weekly views) | > 2 viewers | > 5 viewers | > 10 viewers |
| Automated report delivery | Manual only | Weekly email | Weekly email + Slack + alerts |
If below minimum: Expand data source connections, pre-aggregate in BigQuery to improve load time, or simplify dashboard to fewer widgets per page.
| Error | Likely Cause | Recovery Action |
|---|---|---|
| Looker Studio "Data Set Configuration Error" | Data source permissions revoked or connector expired | Edit > Manage added data sources > Reconnect |
| BigQuery export missing recent dates | GA4 daily export delay (up to 72h) or link broken | Check GA4 Admin > BigQuery Links. Re-enable if unlinked |
| Supermetrics "Authorization Error" | OAuth token expired (Meta tokens expire every 60 days) | Re-authorize in Supermetrics: Data source > Reconnect |
| Dashboard shows $0 revenue | E-commerce tracking not configured in GA4 | Verify GA4 Events > Conversions includes "purchase" event |
| UTM mismatch: spend does not join with GA4 | Campaign names differ across platforms | Standardize UTMs: lowercase, hyphens, no spaces. Apply LOWER() to join keys |
| CRM API rate limit exceeded (429) | Too many requests during data sync | Implement exponential backoff. Use Bulk API for large exports |
| Dashboard timeout on large date ranges | Raw event-level queries too expensive | Create pre-aggregated summary tables at daily grain |
| Component | Free Tier | Paid Tier | At Scale |
|---|---|---|---|
| Looker Studio | $0 | $0 | $0 |
| Metabase Cloud | $0 (self-hosted) | $85/mo (Starter) | $440/mo (Pro) |
| BigQuery storage | 10 GB free | $0.02/GB/mo | $0.02/GB/mo |
| BigQuery queries | 1 TB/mo free | $6.25/TB | $6.25/TB |
| Supermetrics | 14-day trial | $39-99/mo per dest | $299/mo per dest |
| Airbyte (open source) | $0 (self-hosted) | $0 | Infra costs only |
| Total (Path A: Free) | $0 | $0 | $0 |
| Total (Path B: No-Code Paid) | $0 (trial) | $39-200/mo | $300-600/mo |
| Total (Path C: Code + Free) | $0 | $0-10/mo | $20-50/mo |
| Total (Path D: Code + Paid) | $85/mo | $125-385/mo | $500-1000/mo |
Campaign tracking codes that differ across platforms make it impossible to join spend data with conversion data. The dashboard shows disconnected silos instead of a unified view. [src2]
Create a UTM naming document with exact formats: lowercase, hyphens as separators, consistent structure. Audit all active campaigns before building the dashboard. Use LOWER() in SQL as a safety net.
GA4’s event-based schema with nested arrays causes slow queries and forces complex calculated fields. Dashboards with more than 3-4 widgets from raw GA4 data become unusably slow. [src1]
Use BigQuery export to flatten and aggregate GA4 data into clean tables. Point the dashboard at pre-modeled tables for 2-3 second loads instead of 30+.
Dashboards with 50+ widgets across 10 pages get ignored. Stakeholders cannot find the metrics that matter and stop checking within weeks. [src5]
Focus on metrics tied to business decisions: spend, revenue, ROAS, CPA, funnel conversion rates. Add detail pages only when stakeholders request them.
Use when an agent needs to produce a working multi-channel marketing dashboard — not a document describing what metrics to track. Requires active GA4 data collection and at least one ad platform running campaigns. Best executed after marketing strategy is defined and campaigns are live with 30+ days of data.