All posts
Tools

Unifying Google Ads, Meta, and LinkedIn spend with your CRM: a RevOps guide

The Elir Team·RevOps playbooks·April 20, 2026·7 min read

Here's a problem every mid-market RevOps team hits eventually:

The CFO asks: "What was our Google Ads ROI last quarter?"

Marketing pulls a Google Ads report showing spend. Someone else pulls a HubSpot report showing customers. A third person pulls finance's revenue numbers. Thirty minutes later, they're arguing about whether the conversion attribution windows match, whether revenue should be booked or recognized, and why the "new customers" number in HubSpot is different from the "accounts" count in Salesforce.

This is the unified ad spend + CRM problem. It's solvable. It's also where most teams quietly give up because the architecture isn't obvious.

This post walks through what the unified view needs to include, the data joins that make it work, the three architecture options, and the tradeoffs of each.

What the unified view needs to include

A proper unified ad-spend + CRM view answers these questions:

  1. Spend by platform, campaign, and ad group (from ad platforms)
  2. Leads by source attribution (from CRM)
  3. Opportunities by source attribution (from CRM)
  4. Closed-won by source attribution (from CRM)
  5. Revenue by sourcebooked, invoiced, recognized, all three
  6. The joins — spend → leads → opportunities → revenue, all tied to the same channel/campaign taxonomy

The last one is where implementations fail. Spend data lives in Google Ads, Meta, LinkedIn. Lead data lives in HubSpot or Salesforce. Revenue data lives in Stripe, QuickBooks, or a data warehouse. Getting all of it into one view with consistent taxonomy is the hard part.

The joins that break

Join 1: UTM to ad campaign

Ad platforms produce spend data at the campaign and ad group level. Your CRM captures leads with UTM parameters. The join is utm_campaign → ad platform campaign name.

Why it breaks: UTMs are human-entered. One misspelled UTM campaign name ("brand-google-ads" vs "brand_google_ads") and the join fails silently. The lead shows up in your CRM with "brand_google_ads" but no matching spend row in the ad platform data. Revenue attributed, cost missing → the channel looks free.

Fix: auto-generate UTM campaign values from the ad platform, don't let people hand-type them. Tools like Google Analytics Campaign URL Builder help. Better: generate UTMs from a taxonomy layer that's synced with the ad platforms.

Join 2: lead to opportunity to customer

Classic CRM data model problem. Your CRM has a Contact, which may or may not be tied to an Account, which may or may not have Opportunities, which may or may not have Closed-won attribution.

Why it breaks: Contact duplicates (same person, different records) mean one real person attributed to 3 leads. Account merges sometimes break opportunity links. Sales reassigns opportunities mid-cycle without updating source attribution.

Fix: rigorous dedupe (see our post on attribution data problems), and store first-touch attribution at the Account level, not just Contact.

Join 3: customer to revenue

"Customer" in your CRM doesn't necessarily match "customer" in your billing system. Different internal IDs, different company name spellings.

Why it breaks: a customer's CRM record ID is "4729" but their billing ID is "cust_abc123." The join is on email or company name, which is fragile.

Fix: push a canonical customer ID from CRM to billing at closed-won, and use it as the join key thereafter. This requires engineering work most RevOps teams skip.

The three architecture options

Option 1: spreadsheet month-end

Someone on the RevOps team pulls ad spend CSVs, exports CRM lead/revenue data, pulls finance's revenue, and manually stitches it in a Google Sheet once a month.

Pros: works immediately, no engineering needed Cons: breaks weekly; always 4–6 weeks stale; no drill-down; impossible to scale past 2–3 channels

This is how 60% of mid-market RevOps teams operate. Not because they like it, but because nothing else has worked.

Option 2: data warehouse + BI tool

Pull ad spend (via tools like Supermetrics or Fivetran), CRM data (native connector), and revenue data (from the billing system) into a warehouse (BigQuery, Snowflake, Redshift). Build joins in dbt. Report in Looker, Tableau, or Metabase.

Pros: flexible, scales well, produces real analyst-grade reports Cons: requires data engineering. Usually $200K+/year in tooling + 1–2 FTE to build and maintain. Implementation time 3–6 months.

This is the right answer for companies past ~200 employees with a real data team. For everyone else, it's overkill.

Option 3: purpose-built RevOps platform

A platform that connects to ad platforms + CRM + billing natively, handles the joins, and produces the unified view without a warehouse.

Pros: fast to deploy (days, not months), no data team required, purpose-built for RevOps reports Cons: less flexible than a full warehouse — you get the reports the platform ships with

This is what Elir is. It's also what HubSpot Reporting, Salesforce Einstein, Breadcrumbs, and a handful of other tools try to do with varying depth.

The specific integrations to wire up

For a typical mid-market B2B stack:

Ad platforms:

  • Google Ads (spend, clicks, campaigns)
  • Meta Ads (spend, conversions)
  • LinkedIn Ads (spend, lead gen forms)

Analytics:

CRM:

  • HubSpot or Salesforce (contacts, accounts, opportunities, deals)
  • Marketing automation if separate (Marketo, Pardot, ActiveCampaign)

Billing / finance:

  • Stripe (for SaaS billing data)
  • QuickBooks or NetSuite (for GAAP-recognized revenue)

Supporting:

  • Segment or similar CDP (if you have one) — helps with identity resolution

Each of these needs to join to a common attribution model. The "primary key" for attribution is usually the contact email or a session ID that resolves to contact email.

The reports the unified view enables

Once connected, the reports that become possible:

  1. Spend by channel → revenue by channel: the ROAS comparison across platforms that's impossible without unification.

  2. Channel CAC with full cost allocation: fully-loaded CAC by channel, including ad spend, people costs, and tools.

  3. Multi-touch attribution with cost: which channel contributed to each closed-won deal, and what did those contributions cost?

  4. Campaign-level profitability: not just "Google Ads was profitable" but "this specific campaign within Google Ads was profitable, and this other campaign was not."

  5. Cohort-based revenue: customers acquired in Q1 by channel, revenue generated over time. The base data for LTV:CAC.

These are reports that live in the CFO's "show me that quarterly" list, and they're expensive to produce manually.

Starting point

If you're currently on the spreadsheet approach and want to improve without going full warehouse:

  1. Fix your UTM taxonomy first. See attribution data problems for the full checklist.
  2. Connect ad platforms to your CRM directly using native integrations where possible (HubSpot has Google Ads, Meta, LinkedIn integrations). These aren't perfect but they're better than spreadsheets.
  3. Standardize conversion events between ad platforms and CRM. If Google Ads tracks "demo request" as a conversion, your CRM should have the same event with the same UTM taxonomy.
  4. Evaluate a purpose-built platform vs a warehouse. The right answer depends on your team's engineering capacity.

Where Elir fits

Elir natively integrates with Google Ads, Meta Ads, LinkedIn Ads, Google Analytics 4, Google Search Console, HubSpot, Salesforce, GoHighLevel, and billing systems. The joins happen automatically. The reports (channel CAC, multi-touch attribution, campaign profitability) are built-in. No warehouse required.

If you want to see what the unified view looks like on your own data, book a 20-minute walkthrough.

TL;DR

Unifying ad spend with CRM revenue requires three joins: UTM → ad campaign, lead → customer, customer → revenue. All three break in predictable ways. Three architecture options: spreadsheet (doesn't scale), warehouse (expensive and slow), or purpose-built platform (fast but less flexible). For mid-market teams without a data function, purpose-built wins. The hardest part is the UTM taxonomy — fix that first regardless of which architecture you pick.


See this in your own numbers.
Book a 20-minute walkthrough with the Elir team.
Book a demo