Back to blog
AutomationSeptember 1, 2026

We Eliminated Hours of Weekly Spreadsheet Hell for a Client's RevOps Team

Eliminated hours of weekly spreadsheet hell for a client's RevOps team.

We Eliminated Hours of Weekly Spreadsheet Hell for a Client's RevOps Team

A revenue operations team had a weekly ritual. Every Monday, [TEAM] people spent [HOURS] hours each pulling data from [N] systems, pasting it into Google Sheets, reconciling discrepancies, and building PowerPoint decks for the leadership meeting on Tuesday.

The sources: Stripe (subscriptions, churn, MRR), Salesforce (pipeline, forecasts, win rates), HubSpot (marketing qualified leads, email performance), Google Ads (spend, conversions, ROAS), Facebook Ads (spend, conversions, ROAS), the product database (usage, activation, retention), and a separate billing system for enterprise invoices.

Each system had its own definition of "customer," "revenue," and "conversion." The spreadsheet was where these definitions collided. The RevOps team wasn't analyzing — they were translating.

And every week, someone asked: "Why does the Stripe number not match the Salesforce number?" The answer was always some combination of timing differences, currency conversions, refund handling, and "that one enterprise deal that's in Salesforce but not Stripe yet."

The Audit: Mapping the Chaos

We spent [HOURS] hours with the RevOps team mapping their actual workflow.

Monday Morning: Data Collection ([HOURS] hours)

  1. Export Stripe subscriptions CSV (last [N] days)
  2. Export Salesforce opportunities report (filtered to this quarter)
  3. Export HubSpot contacts list (MQLs last week)
  4. Screenshot Google Ads dashboard (spend, conversions)
  5. Screenshot Facebook Ads Manager (spend, conversions)
  6. Run SQL query on product database (activation cohort)
  7. Check enterprise billing spreadsheet (manual, in accounting drive)

Monday Afternoon: Reconciliation ([HOURS] hours)

  1. Paste all data into the master spreadsheet
  2. VLOOKUP customers across Stripe and Salesforce
  3. Manually match "Acme Inc" (Stripe) to "Acme, Inc." (Salesforce)
  4. Convert currencies (some in USD, some in EUR, some in GBP)
  5. Handle refunds (Stripe shows negative, Salesforce shows zero)
  6. Deal with "that one enterprise deal" (always an exception)

Monday Evening: Deck Building ([HOURS] hours)

  1. Build pivot tables from the reconciled data
  2. Create charts (MRR trend, pipeline coverage, CAC by channel)
  3. Write commentary ("MRR up [PCT]% but churn also up [PCT]%")
  4. Format for leadership (hide the messy tabs, show the clean charts)

Tuesday: The Meeting

Present the deck. Answer questions. Promise to investigate discrepancies. Repeat next week.

The Solution: Automated RevOps Pipeline

We built a warehouse-native RevOps system that replaced the manual process with automated data pipelines and self-service dashboards.

Week 1: Data Ingestion

We connected all sources to their existing Snowflake warehouse: Stripe via Fivetran (already connected, just added more tables), Salesforce via Fivetran (already connected, fixed schema drift), HubSpot via Fivetran (new connection), Google Ads via Fivetran (new connection), Facebook Ads via custom pipeline (Fivetran didn't support the API version), product database via dbt source (already in warehouse), and enterprise billing via manual upload to S3, then Snowpipe.

Week 2: Identity Resolution

The core problem: "customer" meant different things in different systems.

SystemCustomer IdentifierIssues
Stripecustomer_idDifferent for each subscription
SalesforceAccount.NameInconsistent formatting
HubSpotemailWork vs. personal
Product DBuser_idOnly for logged-in users
Enterprise billingcompany_nameManual entry, typos

We built a matching table: email match (highest confidence), domain match (company email domain → company name), fuzzy name match ("Acme Inc" ≈ "Acme, Inc."), and manual override table (for the known exceptions).

The match rate was [COVERAGE]%. The remaining [PCT]% were flagged for manual review — usually new customers that hadn't appeared in all systems yet.

Week 3: Unified Models

We built dbt models that created single sources of truth: a unified customer profile with company name, primary email, MRR, ARR, plan type, pipeline stage, acquisition channel, first and last touch dates, activation date, usage score, and NPS score. And a revenue model with reconciliation flags showing whether Stripe and Salesforce matched, or which system had data the other didn't.

Week 4: Automated Reporting

We replaced the Monday morning ritual with scheduled dbt runs (every 6 hours, models refresh), dbt tests (data quality checks run automatically, revenue mismatches > $[N] flag for review), Preset/Metabase dashboards (self-service for the RevOps team), and Slack alerts (daily summary of key metrics, weekly summary for leadership).

The dashboards included executive summary (ARR, MRR, churn, NRR), sales pipeline (coverage, velocity, win rates), marketing funnel (MQL → SQL → closed won, by channel), product health (activation, retention, expansion), and revenue reconciliation (flagged mismatches with drill-down).

Week 5: Handoff and Training

We trained the RevOps team on how to read the dashboards (what each metric means, where it comes from), how to investigate discrepancies (drill-down paths, source system links), how to add new metrics (dbt model structure, where to add logic), and how to handle exceptions (the manual override table, escalation process).

The Results

MetricBeforeAfter
Weekly reporting time[HOURS] hours[HOURS] hours
People involved[TEAM][TEAM]
Data sources manually pulled[N]0 (automated)
Revenue reconciliation accuracy[COVERAGE]%[COVERAGE]%
Time to answer "what's our MRR?"[HOURS][MIN]
Leadership meeting prep[HOURS][MIN] (dashboard is live)
Reported discrepancies found[N]/week[N]/week (flagged automatically)

The biggest win wasn't the time saved — it was the shift from reactive to proactive. The RevOps team stopped building reports and started analyzing trends. They spotted a churn spike in Week 3 that they would have missed in the old spreadsheet. They identified a marketing channel with declining CAC before it became a problem.

What We Learned

Start with the questions, not the data. We spent the first day asking: what decisions does leadership make with this data? The answers shaped the models. If we'd started with "let's connect all the systems," we'd have built a data swamp.

Reconciliation is the hard part. Getting data into the warehouse is easy. Making Stripe revenue match Salesforce revenue is hard. We built reconciliation as a first-class feature, not an afterthought.

Manual exceptions never go away. "That one enterprise deal" became a manual override table. The goal isn't zero manual work — it's structured manual work that's visible and auditable.

Self-service beats perfect dashboards. The RevOps team wanted to ask their own questions, not just read ours. We built drill-down paths and documentation so they could explore without engineering help.

The spreadsheet wasn't the problem. The spreadsheet was a symptom of disconnected systems, inconsistent definitions, and no single source of truth. Fixing the spreadsheet meant fixing the underlying data architecture.

Bottom Line

This client's RevOps team went from spending [HOURS] hours/week on manual reporting to [HOURS] hours on analysis and optimization. The leadership meeting went from "here's what happened last week" to "here's what we should do next week."

The implementation took [HOURS] hours and runs on their existing warehouse. No new tools, no new licenses, no new complexity.

If your team is still pulling CSVs every Monday, you're not doing RevOps — you're doing data entry. The difference is architecture.