Investors do not lose confidence because your numbers are bad. They lose confidence because your numbers are different every time they ask. This is the story of how we fixed that - and why the fix had to happen 12 months before we needed it.


The Real Problem: You Cannot Build This During a Live Raise

Series B diligence runs 4-8 weeks of sustained, intense data requests. Due diligence teams from lead investors will ask for ARR reconciliations, cohort retention tables, unit economics by customer segment, historical burn rates, and revenue recognition methodology. All in the first week. Then they dig deeper. (Kruze Consulting's Series B due diligence checklist gives a useful breakdown of what to expect.)

The infrastructure to answer those requests correctly - to answer them the same way every time, with documentation that proves your methodology, with audit trails that survive scrutiny - takes 6-12 months to build.

You cannot compress that timeline during a live raise. You are simultaneously running the company, managing a fundraising process, preparing financial materials, and hosting investor meetings. There are not enough hours to reverse-engineer six months of data quality problems in the margins.

This is not a technology problem. It is a timing problem. The window to build investor-grade data infrastructure is 12 months before you need it. Every month earlier you start is leverage. Every month you delay is risk that compounds.


1.1 The Before State: Three Sources of Truth, Zero Agreement

At my last company, we were ~100 people, just under $10M ARR, preparing for a Series B raise. We had three systems that produced revenue numbers:

Salesforce showed ARR that included every deal "Closed Won" - the moment a sales representative declared the deal complete. Xero showed ARR as cash collected - revenue booked once payment cleared the bank. Finance had a spreadsheet that split the difference, manually reconciling based on which invoices had been issued and partially paid.

All three numbers were technically defensible. Salesforce was reporting booked business. Xero was reporting collected cash. The Finance spreadsheet was doing accrual accounting. But they produced different ARR figures. Ask the CFO for this month's ARR on Monday, and you might get one number. Ask again on Friday after a large deposit cleared, and you might get a different number.

The board pack required days of manual engineering each month - reconciling, recalculating, validating against manual records. Finance and the CEO had a process that worked for internal decision-making but fell apart the moment someone from outside asked "which of these three is right?"

This is the core problem most early-stage companies face: each system in your stack is correct for its own purpose. None of them were designed to be the single source of truth for investor reporting. And there is no bridge between them - no documented methodology, no audit trail, no definition of what counts as revenue recognition.

1.2 The Moment It Broke: When Salesforce and Xero Disagreed by Six Figures

During an informal conversation with a potential lead investor, the CFO mentioned our ARR. The investor asked a follow-up: "Is that cash collected or booked revenue?"

The CFO gave an answer. But internally, we had no way to verify it quickly. We had no documentation of our recognition methodology. We had no system-of-record that could answer the question definitively.

That conversation exposed the gap. Salesforce and Xero produced materially different numbers - not by a small margin but by a six-figure amount on our $10M ARR base. The difference came from timing: deals that Salesforce marked "Closed Won" but Xero hadn't recorded yet because the payment was still in transit. This is the revenue lifecycle misalignment - what stage of the customer journey counts as revenue recognition?

It was not a data quality problem. It was not a bug. Both systems were working correctly. But they were answering different questions, and nobody had defined which question mattered for the board.

1.3 The Decision: Build Investor-Grade Infrastructure Before You Need It

We made a decision that would have seemed premature a year earlier: build a complete data infrastructure from scratch. Ingest everything - Salesforce, Xero, external data sources. Establish single sources of truth for each metric. Build a transformation layer that defined every number defensibly. Produce Excel outputs that Finance and the CEO could use for board reporting and forward-looking financial modeling.

The internal selling point was not "we need this for the raise." It was "we need this for the board." Building investor-grade data infrastructure as a board requirement, not a fundraising requirement, made the project feel essential rather than tactical. And it was true - the CEO and Finance team needed better numbers regardless of whether we were raising.

The outcome: board packs went from requiring days of manual reconciliation to 3 hours of automated pipeline execution. That alone justified the build. The fact that it also made us investable was secondary.

The scope was clear: ingest, store, transform, output. Not a BI dashboard project. Not real-time analytics. Not a machine learning pipeline. This was a data quality and definitional integrity project - the unglamorous foundation that makes everything else possible.

1.4 The Result: What Happened in Diligence

When Series B diligence started six months later, investors were impressed by the data room - but not in the way we expected.

It was not that the numbers were exceptional. It was that they were consistent. Every metric could be traced back to a documented methodology. Entity resolution - which Salesforce deal matched which Xero invoice - was auditable. The CFO could explain the revenue recognition methodology in three sentences, and the diligence team could verify it independently.

What happened in practice: the diligence team asked fewer reconciliation questions than we anticipated. They asked deeper curiosity questions: tell us more about this cohort, why did churn spike in month seven, what drives the differences between SMB and enterprise payback periods. These are the questions that come when data trust exists.

The data room did not accelerate the diligence process by being flashy. It accelerated it by being boring - by doing exactly what we promised, consistently, every time. No surprises. No emergency re-pulls. No discovered inconsistencies that force the investor to question the underlying numbers.


2.1 ARR and MRR: The Recognition Problem Most Companies Get Wrong

Almost every early-stage SaaS company overstates ARR at some point, not through deception but through methodology choices that seem reasonable until an investor questions them.

The definition that survives investor scrutiny is this:

ARR = the annualised value of all active recurring revenue contracts, recognised at the point of service delivery commencement.

That last phrase is critical. Not at contract signature. Not at cash collection. At the point when you actually begin delivering the service.

What this excludes: setup fees (one-time, non-recurring). Professional services (non-recurring unless you have a contract guaranteeing renewal). Usage-based overages (unless you have a floor commitment). Any revenue that will not recur automatically next period.

Your ARR waterfall should show:

  • New ARR: ARR from contracts that did not exist in the prior period
  • Expansion ARR: ARR added to existing customers (price increases, additional seats, upsells)
  • Churn ARR: ARR lost from customers who did not renew
  • Net ARR: Opening ARR + New + Expansion - Churn

This is what goes into the board pack. And the methodology needs to be documented explicitly - not just the number, but the definition of what counts and why you chose that recognition date.

MRR is simply ARR divided by 12. Not calculated independently. Not pulled from a different source. This prevents divergence - if ARR and MRR ever disagree, you have a bug in the transformation layer.

2.2 Churn and Retention: Logo, Revenue, and Net Revenue Retention

Churn is the most scrutinised metric in SaaS diligence, and for good reason - it reveals whether your product is actually sticky. But there are three distinct metrics hiding under the word "churn," and blending them is a common mistake.

Logo Churn = (customers who did not renew this period) / (customers at the start of the period)

Revenue Churn = (ARR lost from churned customers) / (ARR at the start of the period)

Net Revenue Retention (NRR) = (ARR from customers who existed at the start of the period, measured at the end of the period) / (ARR from those same customers at the start) x 100

Why do all three matter? Because they tell different stories.

A company might have high logo churn (losing many small customers) but low revenue churn (those customers were low-value). That signals a viable enterprise business that is weak at SMB retention. Or you could have low logo churn but medium revenue churn - losing a few large customers is painful.

NRR is the meta-metric. If NRR is above 100%, it means expansion ARR + new ARR exceeded churn ARR - you are growing without acquiring new customers. This is not just a nice-to-have; it is a different business model. Investors price companies with NRR >100% at materially higher multiples.

For a Series B company, the benchmark from investors is typically this: NRR should be in the range of 105-115% (Bessemer's State of the Cloud benchmark). Below that, churn is consuming too much expansion upside. Above that, you have a rare machine.

The methodology matter: define your cohorts (monthly vs. annual; which customers count as "churned"). Be explicit about whether expansion is included in NRR or reported separately. Be prepared to explain downgrades - a customer who reduces spend is not a churn event but should show up in NRR calculation differently than a new expansion.

2.3 Unit Economics: LTV, CAC, and Payback Period Done Defensibly

Unit economics are the translator between your growth narrative and your profitability trajectory. Investors calculate these independently from your financial statements - they are not accepting your CAC number on faith.

CAC (Customer Acquisition Cost) = Total Sales and Marketing spend / New customers acquired (in the same period)

The devil is in the definition of "total S&M spend." Does it include quota-carrying rep salary? What about account management? What about marketing automation tools? The standard approach: include all direct S&M costs - salaries, commissions, tools, ads - for the team that brings in new business.

Document whether your CAC is "blended" (all customers averaged together) or "new-customer-only" (excluding logo expansion). For Series B, segment by customer type: SMB CAC, mid-market CAC, enterprise CAC. Blended CAC often masks a story - one segment might be wildly expensive, another might be land-and-expand efficient.

LTV (Lifetime Value) = (Average Contract Value x Gross Margin %) / Logo Churn Rate

This is the simplified version. It assumes customers have a certain lifetime (1 / churn rate) and generate revenue each period. The gross margin percentage accounts for the cost of serving them.

Gross margin matters because CAC has to be recovered from the contribution margin - not the top-line revenue. If your ACVis $100k but your gross margin is only 50%, the pool of money to recover CAC from is $50k. That changes payback dramatically.

Payback Period = CAC / (MRR per customer x Gross Margin %)

Expressed in months. A payback period under 12 months is strong. Under 18 months is acceptable. Over 24 months, and investors will ask hard questions about whether the unit economics ever work.

The key insight: you do not need exceptional unit economics at Series B. You need defensible unit economics. Show the calculation, show the methodology, show that you understand the math. a16z's GTM metrics framework confirms payback under 12 months is strong, 12-18 months is acceptable. Investors will restate it anyway using their preferred definitions, but if your numbers survive that restatement intact, you pass the test.

2.4 Burn Rate and Runway: The Numbers Investors Actually Calculate Themselves

Burn rate is perhaps the one metric where there is zero ambiguity. Investors pull your Xero file and calculate it directly from your bank statements. If your stated burn rate does not match what they derive from cash flow, it raises a red flag.

Gross Burn = Total cash outflows per month (operating expenses, COGS, everything)

Net Burn = Gross Burn - Cash collected from operations (revenue)

Runway = Current cash balance / Net burn rate

The methodology choice that matters: do you use revenue recognised (accrual accounting) or cash collected (cash accounting) for the revenue offset? At high-growth SaaS companies, the difference is material. You might have high recognised revenue but low collected cash if customers are on net-60 terms.

The answer: use cash collected. This is the conservative estimate. It matches what investors derive from bank data. It matches the cash flow statement. There is no ambiguity.

Include both "runway at current burn" and "runway at projected burn." This signals you understand your trajectory. If you are trending toward profitability, say so with numbers. If not, show that you have a path to funding the gap.

2.5 The Revenue Lifecycle: Deposit to Collection - The Hardest One

This is the section that separates adequate data infrastructure from investor-grade data infrastructure. This is why the single hardest engineering problem was entity resolution. This is the metric that most companies get wrong.

Revenue does not appear in your systems in one moment. It flows through four distinct stages:

Stage 1: Deposit Paid - A customer sends you money upfront, or a payment goes through. This is recorded in Xero (or your accounting system). Cash has moved. But this is NOT revenue recognition yet.

Stage 2: Invoice Sent - You issue an invoice corresponding to the deposit. An obligation is created. Xero records this event. But revenue still should not be recognised - the customer has paid, but you have not yet delivered service.

Stage 3: Service Delivery Commencement - You actually start providing the service. The customer's subscription goes live. Their access is activated. THIS is the correct GAAP-compliant revenue recognition point (per KPMG's SaaS revenue handbook). This is when you should recognise the deposit as revenue.

Stage 4: Cash Collection - The loop closes. You confirm the cash was good and has cleared. Or, for multi-period contracts, you collect subsequent payments.

Here is where most companies misalign:

Salesforce "Closed Won" fires at Stage 1 or Stage 2 - typically the moment a deal is committed or signed. So Salesforce shows ARR that includes business not yet delivered.

Xero records the transaction at Stage 4 - when cash actually clears the bank. So Xero shows revenue too conservatively, only recognising it after the service period is over (for invoices with payment net-30 or net-60 terms).

The correct GAAP-adjacent methodology recognises revenue at Stage 3.

So you have three dates for "when did this deal close?" - the signature date, the payment date, and the service start date. They are not the same. Investors will ask which one you use. Your data infrastructure needs to track all three.

Building a transformation layer that correctly maps a customer record from Salesforce (where the deal lives) to an invoice in Xero (where the cash event lives) back to the service start date (where revenue recognition happens) - that is the hardest engineering problem. And that is where entity resolution becomes critical.


3.1 The Stack: Ingestion, Orchestration, Storage, Transformation

The stack we built was straightforward, but each piece served a specific purpose:

Salesforce + Xero + Open-Source Datasets (FX rates)
  → Stitch Data (ingestion)
  → S3 (raw, immutable)
  → Redshift (raw tables)
  → Python on ECS via Airflow (transformation)
  → Redshift (clean tables)
  → Python on ECS (output generation)
  → Excel files
  → Finance / CEO / Board

Stitch Data for ingestion: Connectors for Salesforce and Xero that handle API authentication, incremental sync, and data validation. Avoids maintaining custom connectors for systems that change their APIs frequently. The connectors push data to S3 as raw JSON/CSV daily.

Astronomer (managed Airflow) for orchestration: Airflow's DAG model maps naturally to the dependency graph of financial metric calculations. Entity resolution must run before revenue lifecycle calculation; revenue lifecycle must run before metrics calculation. Astronomer removes infrastructure overhead - we did not have to manage Airflow deployments.

AWS S3 + Redshift for storage: S3 stores immutable raw extracts. This is critical - you can always reprocess if a transformation logic changes. Redshift is the query layer. Raw tables in Redshift hold unmodified API data. Clean tables in Redshift hold transformation outputs.

Python on AWS ECS for transformation: Full control over business logic, especially entity resolution. ECS provides containerised, stateless execution without the complexity of Spark or Databricks. Simple Python scripts doing data quality checks, business logic, and output generation.

The key principle: specific tools matter less than the pattern. The pattern is immutable raw storage, separation of ingestion from transformation, orchestration that makes failures visible, and outputs that match what Finance actually uses.

3.2 Entity Resolution: Matching a Salesforce Deal to a Xero Invoice

This was the hardest engineering problem, and the reason I am including it in detail is because it is the problem almost no one talks about, but every company with multiple operational systems faces.

The core problem: "Acme Corp Ltd" is recorded in Salesforce with an Account ID (SFDC:001d000000fXoxAAE). The same customer appears in Xero as "Acme Corporation Limited" with a Contact ID (xero:12345abc). There is no shared ID. The names are similar but not identical. There might be multiple invoices in Xero for one deal in Salesforce (deposit + final payment). There might be multi-currency complications.

Naive approach and why it fails: exact string match fails on name variations. Amount matching fails when an invoice for $50k is a partial payment on a $100k deal. Date matching fails because a deal could close before or after the first invoice.

The approach that actually worked:

  1. Normalise both name fields: lowercase, strip legal suffixes (Ltd, Corp, Inc, Limited, LLC), remove special characters, trim whitespace
  2. Compute similarity score: Levenshtein distance between the normalised names. This captures names that are similar but not identical.
  3. Secondary signal - amount match: Is the Xero invoice amount close to the Salesforce deal value? Within 10% tolerance? This catches partial payments and multi-invoice deals.
  4. Tertiary signal - date match: Is the invoice date within 30 days of the deal close date? This catches the timing gap between deal close and invoicing.
  5. Confidence tier: High confidence matches (all signals agree) → auto-accepted. Medium confidence (2 out of 3 signals) → flagged for Finance review. Low confidence → flagged as unmatched.

Critically: auditability is non-negotiable. Every match is traceable to which signals agreed and the confidence score. Finance can review and override matches. This is not a black-box ML model. It is a rule-based system that Finance understands and trusts.

The matching is a business logic problem disguised as an engineering problem. The rules encode decisions about what counts as "the same customer" across systems. Those decisions have to come from Finance, not engineering.

One additional detail: we used open-source FX conversion rate datasets to normalise multi-currency deals. A deal in USD and an invoice in EUR for the same customer at the same time needs to compare the converted amounts, not the raw amounts.

3.3 The Transformation Layer: From Raw Tables to Defensible Numbers

The architecture was simple: raw data never gets modified. Clean data is rebuilt from scratch on each run.

The Redshift schema looked like this:

Raw schema: tables like raw_salesforce_accounts, raw_xero_invoices, raw_xero_contacts. Exactly as they came from the API, with append-only ingestion.

Clean schema: tables like stg_customers (entity resolution output), stg_revenue_events (deposit, invoice, service start, collection mapped to the same customer), fct_arr, fct_churn, fct_unit_economics.

The Airflow DAG ran in this order:

  1. Entity resolution: raw_salesforce + raw_xero → stg_customers (with confidence scores)
  2. Revenue lifecycle: raw_salesforce + raw_xero + stg_customers → stg_revenue_events (with stage labels)
  3. Metrics calculation: stg_revenue_events → fct_arr, fct_churn, fct_nrr, fct_unit_economics
  4. Output generation: fact tables → Excel file

Each transformation step included data quality checks: assert row counts, check null matches above a threshold, validate ARR is non-negative, verify NRR produces a number in the expected range (60%-150%). Outside that range triggers an alert.

Every metric definition is a Python function with a docstring explaining the methodology. This matters because when an investor asks "how do you calculate NRR," the answer is not a paragraph of prose. The answer is a pointer to a function in the codebase with documented logic, tied to specific line numbers in the raw data transform.

3.4 The Excel Outputs: Why the Data Room Ended in Spreadsheets

We could have built a BI dashboard. We could have built a real-time reporting interface. Instead, we built Python scripts that load data into Excel files.

This was a deliberate choice, not a limitation.

Finance and the CEO were already working in Excel for modelling and scenario planning. Board packs were built in Excel. Forward-looking financial projections were in Excel. The goal was not to change their workflow - it was to remove the manual data entry step and replace it with validated data from the warehouse.

The Python script (using openpyxl or xlsxwriter) pulled final metrics from Redshift and loaded them into a pre-built Excel template with multiple sheets:

  • Board Pack Inputs: ARR waterfall (new / expansion / churn / net), cohort retention table (monthly cohorts vs. months since acquisition), unit economics by segment (SMB / mid-market / enterprise), burn rate and runway
  • Forward-Looking Modelling: pricing scenario analysis (what happens to ARR if we increase price 10% with 5% additional churn), cost structure scenarios, growth projection inputs

The output was a scheduled export - not a live dashboard. Daily or on-demand, the script ran, populated the latest data, and saved to a shared location. Finance team picked up the file, and their models updated automatically.

This is what went in the data room. A snapshot of current metrics with a clear audit trail to the source data. Investors could open the Excel file, see the numbers, and trace back through the methodology documents to understand how each metric was calculated.

3.5 Build Sequence: What to Build First and Why

The biggest mistake in data infrastructure projects is trying to build everything at once before anyone uses anything. The correct approach is phased delivery - each phase produces something that Finance or the CEO actually uses within 30 days. If a phase does not produce immediate value, the project drifts and loses internal support.

Phase 1 (Weeks 1-4): Establish Ingestion and Raw Storage

Connect Stitch Data to Salesforce and Xero. Verify data completeness - row counts match the source system. Store in S3 and load to Redshift raw schema. Nothing is transformed yet. Just raw data flowing reliably daily.

Business value: You now have a queryable historical record. Instead of "what was ARR last month," you can ask SQL questions and get answers immediately. Finance team might start using this to spot-check numbers against their spreadsheets.

Phase 2 (Weeks 5-8): Entity Resolution

Build the customer-match table. Run the multi-signal matching pipeline. Produce stg_customers with Salesforce Account linked to Xero Contact with confidence scores.

Have Finance review a sample of 50-100 matched records. Validate that the matching feels right. Iterate on the matching rules with Finance feedback. Do not proceed to revenue calculation until Finance is confident in the entity resolution.

Business value: You now have one customer identity across both systems. This is foundational - everything downstream depends on correct entity resolution.

Phase 3 (Weeks 9-14): Revenue Lifecycle and Reconciliation

Define the four stages (deposit, invoice, service start, collection) in code. Produce stg_revenue_events - one row per customer per month with the stage labels and dates assigned.

Have Finance reconcile the output against their manual spreadsheet. Target: agreement within 1-2%. If there are larger discrepancies, investigate and resolve them. This is where you catch definition misalignments.

Business value: You now have one defensible revenue number. Not the highest estimate, not the most conservative - the one that is defined and documented and can be justified to investors.

Phase 4 (Weeks 15-20): Metrics Layer

Calculate ARR, MRR, churn, NRR, unit economics from the clean revenue table. Produce first automated board pack input.

Finance switches from the manual process (days of reconciliation) to the automated pipeline (3 hours to validate and publish). This is the phase where the project pays for itself - board packs are suddenly easy.

Business value: Monthly board reporting is no longer a bottleneck. This creates immediate credibility for the project internally.

Phase 5 (Weeks 21-26): Data Room Package

Produce the full set of investor-facing outputs - metric tables, methodology documentation, audit trails, the Excel templates Finance uses.

Share with a friendly advisor investor or existing investor. Get feedback. Iterate before the formal raise process starts. This is stress-testing - you want to know what questions will come, and you want to have polished answers before the lead investors ask.

Business value: The data room is ready. It has been reviewed. It is defensible.


Conclusion: Build the Infrastructure Before the Process Starts

The reframe matters: investors do not lose confidence because your numbers are bad. They lose confidence because your numbers are different every time they ask. Because the methodology is undocumented. Because when they dig into the data, they find inconsistencies that force them to distrust everything else.

Building investor-grade data infrastructure takes 6-12 months. You cannot build it during a live raise. The window is 12 months before you need it.

If you are 12 months from your Series B, start now. If you are 6 months out, start this week. If you are already in process, finish the raise and build this immediately after - it will support your Series C fundraising and make you a more mature company operationally.

For founders: the data room signals how well you understand your own business. Investors trust founders who can produce consistent, auditable numbers. That trust is worth the 6-12 month investment.

For CTOs: this is your project to own. Finance will not build it without engineering. And it will not get built if you do not drive it. The infrastructure you build here becomes the foundation for every business decision the company makes - pricing, cost structure, headcount planning, profitability roadmap.

Preparing for a Series B raise and not confident in your revenue data? I help Series A and B-stage founders and CTOs build the data infrastructure that survives deep diligence. Schedule a consultation →