s rather than scheduled batch jobs to ensure near-real-time accuracy.
- Revenue: Stripe/Chargebee webhooks
- Infrastructure: AWS Cost Explorer API, GCP Billing
- Product: PostHog/Mixpanel, PostgreSQL transactional data
- Normalize all payloads to a unified schema before storage.
Step 2: Metric Computation Engine
Compute capital efficiency metrics using deterministic, versioned functions. Avoid floating-point drift; use decimal libraries. Store historical snapshots for audit trails.
import { Decimal } from 'decimal.js';
export interface MetricSnapshot {
period: string; // ISO 8601 month format
mrr: Decimal;
burnRate: Decimal;
runwayMonths: Decimal;
burnMultiple: Decimal;
computedAt: Date;
formulaVersion: string;
}
export function computeBurnMultiple(
netNewArr: Decimal,
netBurn: Decimal
): Decimal {
if (netBurn.isZero()) return new Decimal(0);
return netBurn.div(netNewArr);
}
export function computeRunway(
cashBalance: Decimal,
monthlyBurn: Decimal
): Decimal {
if (monthlyBurn.isZero()) return new Decimal(999); // Cap for display
return cashBalance.div(monthlyBurn);
}
export function generateSnapshot(
cash: Decimal,
mrr: Decimal,
monthlyBurn: Decimal,
netNewArr: Decimal,
version: string
): MetricSnapshot {
return {
period: new Date().toISOString().slice(0, 7),
mrr,
burnRate: monthlyBurn,
runwayMonths: computeRunway(cash, monthlyBurn),
burnMultiple: computeBurnMultiple(netNewArr, monthlyBurn),
computedAt: new Date(),
formulaVersion: version
};
}
Step 3: Secure API Exposure
Expose metrics through a read-only, rate-limited API with JWT-based authentication. Implement row-level security for investor-specific data rooms.
import { FastifyInstance } from 'fastify';
export async function fundingMetricsRoute(fastify: FastifyInstance) {
fastify.get('/v1/funding/metrics', {
preHandler: [fastify.authenticate, fastify.verifyInvestorScope],
schema: {
response: {
200: {
type: 'object',
properties: {
period: { type: 'string' },
mrr: { type: 'number' },
burnMultiple: { type: 'number' },
runwayMonths: { type: 'number' },
formulaVersion: { type: 'string' }
}
}
}
}
}, async (request, reply) => {
const { investorId } = request.user;
const metrics = await fastify.db.query.fundingMetrics.findFirst({
where: (table, { eq }) => eq(table.investorId, investorId),
orderBy: (table, { desc }) => desc(table.createdAt)
});
if (!metrics) {
return reply.code(404).send({ error: 'No metrics available for this scope' });
}
return reply.code(200).send({
...metrics,
mrr: metrics.mrr.toNumber(),
burnMultiple: metrics.burnMultiple.toNumber(),
runwayMonths: metrics.runwayMonths.toNumber()
});
});
}
Step 4: Audit & Reconciliation
Implement immutable audit logs for every metric calculation. Use append-only tables or ledger-style storage. Reconcile daily against source systems to detect drift. Store raw payloads alongside computed results to enable forensic verification during due diligence.
Architecture Decisions & Rationale
- Time-series database (TimescaleDB) over standard RDBMS: Financial metrics are inherently temporal. Partitioning by month enables efficient historical queries without full table scans. Continuous aggregates reduce compute overhead for trend analysis.
- Decimal over float: Currency and ratio calculations require exact precision. Floating-point arithmetic introduces rounding errors that compound during due diligence and trigger investor skepticism.
- Event-driven over batch: Webhook-driven ingestion reduces latency between revenue recognition and metric updates, critical for real-time runway tracking and early warning systems.
- Versioned metric definitions: Store formula versions alongside snapshots. Investors will challenge metric definitions; versioning provides cryptographic proof of calculation methodology and enables backward-compatible updates.
- Separation of compute and storage: Keep metric calculation logic stateless and containerized. This allows horizontal scaling during peak due diligence periods without impacting core product databases.
Pitfall Guide
- Hardcoding financial formulas in application logic: Formulas change as funding stages evolve. Embedding them in service code creates technical debt and audit failures. Extract definitions to a configuration layer or DSL with Git-tracked versioning.
- Ignoring data lineage: VCs require source-to-sink traceability. Without explicit mapping from raw events to final metrics, reconciliation fails during due diligence. Implement explicit lineage tags in every pipeline stage and retain raw payloads for 12+ months.
- Optimizing for vanity metrics over capital efficiency: MRR growth without burn multiple context signals risk. Pipeline must enforce unit economics thresholds before exposing growth metrics. Flag anomalies where growth outpaces cash generation unsustainably.
- Exposing raw data without access controls: Data rooms leak when permissions are role-based rather than data-scoped. Implement tenant-isolated views and row-level security from day one. Never expose customer-level revenue data in investor endpoints.
- Neglecting multi-currency handling: Global startups transact in multiple currencies. Unnormalized FX rates distort burn rate and runway. Use daily midpoint rates from a verified provider (e.g., ECB, XE), never spot or end-of-day rates.
- Building custom BI instead of leveraging existing tools: Reinventing dashboards wastes engineering capacity. Use established BI connectors (Metabase, Looker, Cube.js) on top of the pipeline, not as replacements for the compute layer.
- Treating funding data as static: Runway and burn rate decay hourly during cash crunches. Static daily snapshots miss critical inflection points. Implement streaming updates for metrics below threshold boundaries and trigger PagerDuty/Slack alerts when runway drops under 6 months.
Best practices from production:
- Use idempotent webhook handlers to prevent duplicate metric inflation. Implement deduplication keys based on source event IDs.
- Store metric definitions as code with peer review. Treat formula changes like schema migrations.
- Run daily reconciliation jobs that flag >2% variance between pipeline and source systems. Auto-pause metric exposure if variance exceeds threshold.
- Implement metric deprecation policies; never delete historical calculations. Archive with
deprecated_at timestamps.
- Maintain a data dictionary API that returns current formula versions, definitions, and source mappings for investor onboarding.
Production Bundle
Action Checklist
Decision Matrix
| Scenario | Recommended Approach | Why | Cost Impact |
|---|
| Pre-seed (0–12 months) | Lightweight pipeline with CSV ingestion + basic API | Minimizes overhead while establishing data discipline and audit readiness | Low ($2K–$5K/mo engineering) |
| Series A (12–24 months) | Event-driven pipeline with TimescaleDB + audit ledger | Meets VC due diligence standards, handles multi-source reconciliation, scales with data volume | Medium ($8K–$15K/mo infra + tooling) |
| Growth/Scale (24+ months) | Multi-tenant data room with automated reconciliation + BI layer | Handles complex capital structures, multiple investor classes, compliance requirements, and cross-border FX | High ($20K–$40K/mo platform + security) |
Configuration Template
# funding-pipeline.config.yml
metrics:
definitions:
- name: burn_multiple
formula: net_burn / net_new_arr
precision: 4
version: v2.1
deprecated: false
- name: runway_months
formula: cash_balance / monthly_burn
precision: 2
version: v2.1
deprecated: false
sources:
revenue:
provider: stripe
webhook_secret_env: STRIPE_WEBHOOK_SECRET
idempotency_key: event.id
infrastructure:
provider: aws_cost_explorer
role_arn: ${AWS_BILLING_ROLE}
region: us-east-1
product:
provider: postgresql
connection_string: ${DB_URL}
tables: [subscriptions, invoices]
reconciliation:
frequency: daily
variance_threshold: 0.02
alert_channel: slack_ops
auto_pause: true
security:
api_rate_limit: 100/min
auth_method: jwt
data_room_scope: investor_tenant
retention_days: 365
fx:
provider: ecb
rate_type: midpoint
update_frequency: daily
Quick Start Guide
- Initialize a TypeScript project with
npm init @codcompass/funding-pipeline
- Configure source credentials in
.env and validate webhook connectivity using npm run pipeline:test:webhooks
- Run
npx funding-pipeline seed to generate baseline metric schemas, audit tables, and data dictionary endpoints
- Start the compute engine with
npm run pipeline:start and verify metrics at /v1/funding/metrics using a test JWT
- Export the data dictionary with
npx funding-pipeline export:docs for investor onboarding and schedule the first reconciliation job via cron
The funding landscape no longer rewards intuition. It rewards architecture. Treat capital efficiency as a first-class engineering domain, and the pipeline becomes your most valuable asset during due diligence.