Skip to content

bchaoss/PMF-Semantics

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PMF Semantic Layer

Semantic layer implementation of the quantitative PMF framework from Tribe Capital: Growth Accounting × Cohort Analysis × Distribution

Implemented as a dbt package.


The Methodology: Accounting for Product-Market Fit

This dbt package implements the quantitative framework developed by Tribe Capital. As outlined in their essay, achieving Product-Market Fit (PMF) is not a binary status but a spectrum. Just as the 3 Financial Statements tell us the financial health of a company, this framework uses activity data to objectively break down PMF into three orthogonal, non-derivable pillars:

1. Growth Accounting & The Quick Ratio

Instead of looking at deceptive top-line growth, Growth Accounting dissects the exact atomic origins of metric velocity across 6 distinct buckets:

  • New: Volume from first-time entities in the current period.

  • Resurrected: Volume from entities who lapsed in the past but returned.

  • Expansion: Incremental volume from existing active entities spending/engaging more.

  • Retained: Baseline stable volume carried over from the previous period.

  • Contraction: Lost volume from existing active entities spending/engaging less.

  • Churned: Complete loss of an entity who was active in the previous period.

  • The Core Signal ($Quick Ratio$): The package automates the calculation of the Growth Quick Ratio:

    $$\text{Quick Ratio} = \frac{\text{New} + \text{Resurrected} + \text{Expansion}}{\text{Churned} + \text{Contraction}}$$

    A Quick Ratio $> 1.0x$ indicates efficient, structural growth. A ratio $< 1.0x$ implies a "leaking bucket" where top-line acquisition cannot outpace product churn.

2. Cohort Analysis & The Retention Flattener

While Growth Accounting flags top-line efficiency, Cohort Analysis explains the underlying customer lifetime behavior. It groups entities by their birth period and tracks both Logo (Count) and Value (Revenue/GMV) retention as they age.

  • The Core Signal: The ultimate mathematical proof of PMF is a cohort retention curve that flattens parallel to the x-axis at a non-zero asymptote. If curves continuously trend toward zero, the product lacks permanent value. Super-linear LTV curves (climbing upward) indicate powerful negative net churn.

3. Distribution (Concentration vs. Intensity)

A healthy average (ACV/AMU) can mask dangerous outliers. This pillar evaluates the risk and depth of your PMF spectrum:

  • Ordinal Metrics (Revenue/GMV): Computes a Cumulative Distribution Function (CDF) to quantify concentration risk. It answers: Is 90% of your value coming from a few "whales" (consulting risk), or is it healthily distributed across the long-tail?
  • Binary Engagement Metrics (MAU/DAU): Implements the L28 Intensity Distribution (tracking the exact fraction of users active $N$ days out of a 28-day window). This surfaces whether active users are deeply engaging with the product or barely scratching the surface.

Quickstart

# 1. Install dbt for your warehouse
pip install dbt-postgres      # or dbt-bigquery, dbt-snowflake, dbt-duckdb …

# 2. Configure your warehouse connection
#    Edit ~/.dbt/profiles.yml  (see profiles.yml.example in this repo)

# 3. Point the package at your tables
#    Edit dbt_project.yml → vars.metrics → source_table for each metric

# 4. Run
dbt run

dbt writes the output tables to your warehouse.


Project structure

pmf_dbt/
├── dbt_project.yml          # metric definitions live here (vars.metrics)
├── macros/
│   ├── pmf_growth_accounting.sql   # core logic — shared across all metrics
│   ├── pmf_cohort.sql
│   └── pmf_distribution.sql
└── models/                  # one-liner: calls the macro

The macros contain all the logic. The model files are one line each. You never need to edit the macros unless you want to extend the framework.


Adding a new metric

Step 1 — Add the metric definition to dbt_project.yml under vars.metrics:

vars:
  metrics:
    revenue:                              # your metric name
      source_table: "your_schema.payments"
      entity_id:    "merchant_id"         # the "who"
      time_column:  "paid_at"
      value_expr:   "SUM(net_amount)"
      is_binary:    false                 # false = ordinal (has expansion/contraction)
      time_grains:  ["monthly", "weekly"]
      row_filter:   "status = 'settled'"  # optional

Step 2 — Create model files (one per framework × grain):

# models/pmf/revenue__growth_accounting__monthly.sql
{{ pmf_growth_accounting('revenue', var('metrics')['revenue'], 'monthly') }}

# models/pmf/revenue__cohort__monthly.sql
{{ pmf_cohort('revenue', var('metrics')['revenue'], 'monthly') }}

# models/pmf/revenue__distribution__monthly.sql
{{ pmf_distribution('revenue', var('metrics')['revenue'], 'monthly') }}

Step 3 — Run:

dbt run --select revenue__*

Output tables

growth_accounting

column description
metric_name e.g. gmv
grain monthly / weekly
period truncated date
new value from new entities
resurrected value from returned entities
expansion incremental value from existing entities (null for binary)
retained value from stable existing entities
contraction lost value from existing entities (null for binary)
churned value from lost entities
total total this period
gross_retention retained / prev_total
net_churn (churned + contraction - resurrected - expansion) / prev_total
quick_ratio (new + resurrected + expansion) / (churned + contraction)
growth_rate (total - prev_total) / prev_total

cohort

column description
cohort_period first active period
cohort_age periods since cohort birth
logo_retention % of cohort still active
revenue_retention period value / birth value (can exceed 1.0)
ltv_per_entity cumulative value / cohort size

distribution

Ordinal metrics: CDF — entity_value, pct_entities_at_or_below, pct_value_at_or_below

Binary metrics: L-N — intensity_value (days active), pct_of_active_entities, cumulative_pct


Viewing multiple metrics together

All tables share the same schema. Union them for cross-metric dashboards:

select * from gmv__growth_accounting__monthly
union all
select * from mau__growth_accounting__monthly
order by metric_name, period

is_binary explained

is_binary: false (GMV, Revenue) is_binary: true (MAU, DAU)
expansion / contraction ✓ computed null
growth accounting full 6-bucket 4-bucket
distribution CDF of value L-N intensity
revenue_retention can exceed 1.0 always ≤ 1.0

About

Semantic layer / dbt package for quantitative Product-Market Fit (PMF) analytics — Growth Accounting, Cohort Analysis, and Distribution (Tribe Capital framework).

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors