What is time to value, and how do you measure it?
Definition
Time to value is the elapsed time from the start of the relationship — contract start for sales-led, signup for self-serve — to the moment an account reaches a defined value milestone. Without an explicit milestone event the metric does not exist; "time to value" with a vague definition of value is a number people argue about rather than improve.
What data do you need?
- A single, written-down value milestone event (first dashboard shared, first integration live, tenth query run)
- The milestone emitted as a timestamped event at account grain
- Contract start dates for sales-led accounts, signup dates for self-serve
- Onboarding stage history if you want a stage-by-stage breakdown
- The cohort of accounts that never reached the milestone, tracked separately
SQL pattern
WITH first_milestone AS (
SELECT
account_id,
MIN(occurred_at) AS reached_at
FROM product_milestone_events
WHERE milestone = 'first_dashboard_shared'
GROUP BY account_id
)
SELECT
date_trunc('month', a.contract_start_date)::date AS cohort_month,
COUNT(*) AS accounts,
COUNT(m.account_id) AS reached_milestone,
ROUND(
100.0 * COUNT(m.account_id) / NULLIF(COUNT(*), 0), 1
) AS reached_pct,
-- Median, not mean: a few accounts that take a year would drag
-- the average somewhere no real customer lives.
ROUND(PERCENTILE_CONT(0.5) WITHIN GROUP (
ORDER BY EXTRACT(epoch FROM m.reached_at - a.contract_start_date) / 86400
)::numeric, 1) AS median_days_to_value,
ROUND(PERCENTILE_CONT(0.9) WITHIN GROUP (
ORDER BY EXTRACT(epoch FROM m.reached_at - a.contract_start_date) / 86400
)::numeric, 1) AS p90_days_to_value
FROM cs_accounts a
LEFT JOIN first_milestone m USING (account_id)
WHERE a.contract_start_date >= CURRENT_DATE - INTERVAL '18 months'
GROUP BY 1
ORDER BY 1;Common pitfalls
Where does this metric apply?
This metric commonly uses data from Gainsight, Vitally, Planhat, Amplitude, Segment, plus any warehouse models built on account, subscription, and product-usage tables at the same grain.