DTC Food & Beverage

Crosswind Roasters — Coffee brand found $4k/mo in wasted Performance Max

How a coffee DTC brand found $4k/mo in wasted Performance Max spend with one Claude agent prompt

Crosswind Roasters' Google Performance Max campaign read 2.4x ROAS on the surface. One prompt to the Claude agent exposed that 47% of conversions were branded search terms the brand already ranked #1 for — $4,100/mo going to clicks they would have earned for free.

Crosswind Roasters — Coffee brand found $4k/mo in wasted Performance Max
## The situation Crosswind Roasters is a specialty coffee brand shipping single-origin beans nationwide. Revenue runs around $95k/mo, with a mix of subscription and one-time orders weighted roughly 60/40 — subscription revenue grows slowly, one-time orders spike around holidays and gift season. Their paid-media mix at onboarding was 55% Meta, 35% Google, 10% Meta/Instagram influencer whitelisting. The Google side was structured as a single Performance Max campaign ("all products") plus a separate branded Search campaign that the founder had kept running as a safety net. Ad ops was handled by the founder directly plus a fractional media buyer who logged in on Mondays and Thursdays. Performance Max looked like the strong campaign on the surface: 2.4x reported ROAS, steady spend at $8,500/mo, a conversion volume that had been climbing quarter over quarter. The branded Search campaign was tiny at $400/mo and reported 12x ROAS — the kind of number you don't question. The founder ran both on autopilot and focused their attention on the Meta side, which was more volatile. The thinking was reasonable: "Google Shopping is set-and-forget, Meta is where I lose sleep." That is true for most DTC founders, and it is exactly why this pattern is so widespread. This is a very common DTC Google setup. Performance Max gets turned on, Google's auto-targeting fills the ad delivery, and the operator treats the black-box campaign as a working system because the aggregate ROAS clears their threshold. The problem is that Google — who is being paid — is also the one deciding which search terms the campaign should chase. That incentive tension is exactly what the PPC community has been warning about for three years. Add to that the fact that Google's default 30-day attribution window versus Meta's 7-day click / 1-day view window creates further reporting asymmetry: if a buyer saw a Meta ad on day 1 and searched Crosswind on day 20, Google gets 100% of the credit and Meta gets zero. That asymmetry pushes operators to over-invest in Google — or more precisely, to over-invest in whatever Google campaign is capturing the end-of-journey clicks, which is almost always Performance Max. ## The problem A specific, measurable problem was buried in the Performance Max Insights tab: 47% of the campaign's reported conversions were coming from search terms that included the brand name "Crosswind" or close variants. The brand already ranked #1 organically for every single one of those terms. Performance Max was effectively buying clicks that would have landed on the site for free — a well-documented pattern: "10% of spend at a 20x branded ROAS plus 90% at a 0.5x non-brand ROAS blends to a 2.45x that looks fine, but you're incinerating 90% of the budget." Crosswind Roasters' blended non-brand P-Max ROAS, once branded terms were filtered out, was 0.6x. That means roughly $4,100/mo of the $8,500 spend was either (a) paying for traffic that would have arrived via organic search, or (b) buying non-brand traffic at a deeply unprofitable rate. Performance Max had been laundering the unprofitability under a blended reported number that made the campaign look steady. ## What they did with Admaxxer - **Step 1 — Connect Google Ads via OAuth.** Dropped in the refresh token + developer token, confirmed the customer_id matched the right MCC, and within 20 minutes the Performance Max campaign, its asset groups, and its served search terms were queryable via the Google Ads API (GAQL, `cost_micros` divided by 1e6 to normalize to dollars per Google's documented convention). - **Step 2 — Install the pixel for server-side conversion validation.** The pixel fired on every purchase, and Admaxxer cross-referenced server-side events against Google-reported conversions to catch attribution drift. This also seeded the `customer_id`-level event log that the cohort-LTV pipe uses to identify true new customers versus repeat buyers. - **Step 3 — Ask the Claude agent the key question.** Opened the chat panel and typed: *"Show me Performance Max search terms with more than $500 spend in the last 30 days and fewer than 2 new-customer conversions. Rank by spend."* The agent used `get_campaign_insights` and `query_metrics` against the cohort-LTV pipe (new-customer detection via first-order-only cohort — defined as first-ever purchase for a given `customer_id`, not any order in the window) and returned 18 branded search terms totaling $4,128 in monthly spend. The agent cited the underlying pipe and the 30-day window so the founder could verify the count against the Google Ads UI. - **Step 4 — Build brand-exclusion at campaign level.** Used Google's 2024 campaign-level negative keyword support to add 22 branded variants (Crosswind, crosswind coffee, crosswind roasters, common misspellings like "crosswinds" and "cross wind") as campaign-level negatives on the Performance Max campaign. Kept the dedicated branded Search campaign running as the intentional brand-defense lane, so if a competitor started bidding on "Crosswind" the brand still had a paid response available. - **Step 5 — Let the agent watch the reallocation.** Set up a weekly scheduled check via the `query_metrics` tool: *"alert me if P-Max new-customer CPA rises above $45 or if non-brand CPC spikes more than 20% week-over-week."* The agent posts the check result to a Slack webhook every Monday morning at 9 AM Pacific. Three weeks in, the check caught an inventory-driven bid escalation on one product feed and the founder pulled the bid back before P-Max overspent. - **Step 6 — Reallocate the freed budget.** The $4,100/mo saved was split roughly: $2,000 reinvested into non-brand search terms on P-Max, $1,500 moved to Meta prospecting (which had been under-funded), and $600 held back as buffer. Blended acquisition cost on the new-customer cohort dropped from $41 to $32 over the next 45 days. ## The results After 45 days: | Metric | Before | After | Change | |-------|--------|-------|--------| | Performance Max monthly spend | $8,500 | $6,400 | -25% | | Wasted branded spend (P-Max) | $4,128/mo | $90/mo | -98% | | P-Max reported ROAS (blended) | 2.4x | 3.1x | +29% | | P-Max non-brand ROAS | 0.6x | 1.7x | +183% | | New-customer CPA (overall Google) | $41 | $32 | -22% | | Organic branded clicks (month) | 3,200 | 4,800 | +50% | | Monthly revenue | $95,000 | $96,800 | +2% | The critical number is the new-customer CPA — down 22% because P-Max budget was now hunting actual new buyers instead of laundering brand-aware customers as "conversions." The 50% jump in organic branded clicks is those same customers now finding Crosswind for free. ## Why this worked The underlying insight isn't new to the PPC community — "exclude brand from P-Max" has been recommended loudly since Google enabled campaign-level negatives in 2024. What was missing for a solo-founder operator was the time and tooling to actually run the diagnostic. Opening the Google Ads UI, pulling the search terms report, filtering to >$500 spend, cross-referencing new-customer conversions, and summing the wasted spend is a 90-minute task done right. Most founders never run it, and "most founders never run it" is why branded-capture inside Performance Max is arguably the most common eight-figure leak in DTC Google spend right now. The [Claude agent](/features/claude-agent) turned that 90-minute task into one sentence, and the answer arrived in 30 seconds. `query_metrics` ran against the Tinybird [cohort LTV](/guides/cohort-ltv) pipe (specifically the new-customer attribution cut — defined as first-ever order for a given `customer_id`, not any order inside the window) and `get_campaign_insights` pulled the raw P-Max search-terms data from Google Ads via GAQL, with `cost_micros` divided by 1e6 to normalize. The agent joined them, ranked by spend, and returned a ready-to-act list. This generalizes beyond P-Max. Any time Google's auto-targeting is paid on blended numbers, the operator needs a fast way to decompose "why is this number what it is." That is the problem `query_metrics` plus a fluent-English interface actually solves. It is also the problem that every traditional BI tool has pushed onto the operator — "learn SQL, write the query, wait for the result" — and which an agent reverses: you describe the question in English, the agent writes the query, the answer comes back typed. The gap between question and answer shrinks from 90 minutes to 30 seconds, and that shrink is what actually changes what gets audited versus what stays hidden. The ongoing monitoring matters too. Once Crosswind had a handle on the problem, the Monday morning agent check kept it from recurring. P-Max's auto-targeting will drift back toward branded terms over time — it always does, because branded terms are the cheapest conversions on the network — and without a standing rule to catch the drift, the leak restarts within a quarter. The scheduled `query_metrics` rule turned the fix into a durable one. ## What other DTC food and beverage brands can learn - Never trust Performance Max blended ROAS without decomposing search terms. Branded queries inside P-Max almost always inflate the blend. - Use campaign-level negative keywords (Google enabled this in 2024) to exclude brand variants from P-Max. Keep brand defense in a dedicated Search campaign where you can control the budget. - Run the "search terms with >$X spend and

Frequently Asked Questions

Could my non-coffee DTC brand do this?

Yes — this is a Google Performance Max pattern, not a coffee pattern. Any brand with meaningful organic ranking for their own name is leaking budget into P-Max unless they've added campaign-level brand negatives.

How long did the initial diagnostic take?

The Claude agent returned the ranked list of wasted search terms in about 30 seconds. The campaign-level negative keyword setup in Google Ads took 15 minutes. Results stabilized over 3-4 weeks as Google re-optimized the campaign.

Do I need to pause Performance Max entirely?

No. Crosswind Roasters kept P-Max running — they just removed the branded-query leakage via campaign-level negatives. The campaign's non-brand ROAS nearly tripled once it stopped getting credit for brand-captured conversions.

Does the Claude agent make campaign changes automatically?

No. The agent can propose pauses and bid adjustments via update_campaign, but every destructive action requires explicit confirmed: true. Adding negative keywords still happens in the Google Ads UI or via a confirmed agent call.

What plan does this require?

Crosswind Roasters used the Pro plan at $79/mo — it includes the Claude agent, cohort LTV, and the query_metrics tool. A 7-day free trial is available with no credit card.