Why Google Ads Conversions Don’t Match WordPress Form Leads

Every month the same argument shows up in an agency Slack or a client call.

Google Ads reports 40 conversions. Meta has a different number. GA4 has a third. Someone opens the WordPress form inbox — or the CRM, or the shared mailbox — and counts 28 people with a name and an email.

The client wants to know which number is real. The account manager wants to know who is about to get blamed. The honest answer is that all of them can be “right” and still be useless for the question everyone actually asked: which ads produced actual form leads?

This is not a tracking-bug article. The pixels are probably firing. The problem is that “conversion”, “lead” and “named form fill” got treated as the same thing, and they are not.

What the ads platform is counting

A Google Ads conversion is a rule you set, plus a window, plus whatever Google could observe or model.

That rule might be a thank-you page view, a generate_lead event from Google Tag Manager, or a button click that usually precedes a submit. It might fire on a newsletter form and a quote form because both share one conversion action. It might fire twice if the thank-you page is refreshed, or if GTM and the native Google tag both send the event.

Then the window does its work. A 30-day click-through window will credit a form fill today to an ad click from three weeks ago. If view-through conversions are on, a person who saw the ad and later arrived some other way can still count. Enhanced conversions and consent-mode modelling fill in conversions Google did not directly see.

None of that is fraud. Platforms optimise spend against a signal, and they would rather over-count a fuzzy signal than under-count a clean one. Meta, Microsoft Ads, LinkedIn and TikTok do their own versions — different windows, different modelling. Add those dashboards together and you will invent people who do not exist.

Two more ways the Ads number quietly inflates:

  • “All conversions” is not “Conversions.” Primary, secondary and view-through sit in different columns. A screenshot of the wrong one starts the argument.
  • Calls, chats and form fills get lumped together. A click-to-call is a real outcome. It is not a named form row. If both are one “Lead” action, Ads will always outrun the inbox.

What Analytics is counting

GA4 is not a list of people. It is a list of events, attributed to sessions and users.

A form_submit event can fire when a form is sent, when validation fails, when a page-builder form fires on click instead of on a successful save, or when a search box was tagged by accident. Consent mode will model some of the events it could not collect. Session-scoped and user-scoped reports will disagree with each other, and both will disagree with Google Ads.

GA4 is good at “how did traffic behave this month?” It is a poor place to look up Sarah from the Tuesday enquiry. Even a clean generate_lead report by session source is still an aggregate. It will not give you the 28 names, and it will still include events that never became a stored form submission.

What a named form fill is

A named form fill is a row your form plugin stored: a name, an email, usually a message, a timestamp. Someone sales can ring. That is the only number that answers “how many people actually asked us something?”

Here is a worked example — not a statistic, a sketch of how a 40-to-28 gap typically forms. Say Google Ads reports 40 conversions against a “Lead” action.

  • Six are modelled or enhanced. Google is confident a conversion happened. You do not have a form row.
  • Three are duplicate fires: thank-you page refresh, back-button, or two tags on the same submit.
  • Two are a newsletter or PDF form sharing the same conversion action as the contact form.
  • One is an agency test that nobody excluded.

That leaves 28 named contact-form submissions. Rearrange the mix if you like. The point is the same: the platform is counting signals that usually mean a lead. The inbox is counting people.

The gap also runs the other way. Ad blockers, a broken tag, or a consent banner can leave you with a name and no conversion. That is why “just trust Ads” and “just trust the inbox” both fail. You need both numbers, and you need to know which question each one answers.

Why this wrecks budget conversations

Smart Bidding will chase whatever you told it a conversion is. If that includes newsletter signups, double-fires and modelled ghosts, budget moves toward those signals — not necessarily toward people you can call.

Agencies then report cost-per-lead off the Ads figure. Sales looks at 28 names. The client concludes someone is inflating results. Nobody is inflating results. The definition slipped.

Keep Ads. Use it for delivery, search terms and bidding. Then keep a second count that cannot be modelled away: successful form submissions, with the traffic source attached to each row. That count will not match Ads. It should not. Ads is allowed to take credit for a click 18 days ago. A same-session form log is only allowed to take credit for the visit that produced the enquiry. Both can be true.

Present them as one number and you will keep having the 40-versus-28 argument. Present them as two numbers with two definitions and the argument ends.

A sentence that works on a client call:

Ads reported 40 conversions on the Lead action (30-day click, includes modelled). We have 28 named form enquiries in the same dates. Of those 28, here is the source on the visit that produced each one.

That is a reconciliation. “The dashboards disagree, so tracking is broken” is not.

Reconcile on names, then attach the source

Three rules, none of them clever.

  1. Write down what “lead” means for this account. A successful form submission with a name and email — whichever plugin actually stores the row. Not a thank-you page view. Not a button click. Not a GA4 event that usually means the form worked.
  2. Count those rows. That is your named-lead number. Filter out your own tests. If two forms are both “leads” for bidding, keep them as two conversion actions in Ads and two lists in WordPress.
  3. Stamp the source on the row, not in a separate dashboard. UTM parameters and click IDs (gclid, fbclid, msclkid, li_fat_id, ttclid, yclid) already arrive on the landing URL. Keep them until the form is submitted, then store them with the name. “Google Ads, brand campaign” becomes a property of Sarah, not a bar in a channel report.

Then the next hour goes on lead quality, not on whether someone deleted 12 people.

If the forms are in WordPress

You do not need another analytics suite for step 3. You need the source to survive the visit and land on the submission.

That is what LeadSource does (https://wordpress.org/plugins/leadsource/). The free plugin stores UTMs and ad click IDs in a first-party session cookie, then attaches them to the form submission through the form plugin’s own hook. No hidden fields to add.

It works with Contact Form 7, WPForms, Gravity Forms, Ninja Forms, Formidable Forms, Fluent Forms, Elementor Pro Forms and Everest Forms. It is same-session last-click: the source from the visit that produced the enquiry, not a 30-day cookie still claiming last month’s click. It stores gclid on the lead so you can see a Google Ads click; it does not upload conversions back to Google Ads. If you want the mechanics, here is how to store the click ID on the lead in WordPress.

Install it from https://wordpress.org/plugins/leadsource/. If you later want journeys, routing and client reports, that is a separate Pro add-on — you do not need it to start counting names.

Keep Ads. Keep Analytics. Add a list of people with sources. The dashboards will still disagree. You will finally know why, and you will know which ads produced the 28 names.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *