Metric Intelligence Guide
Every number tells a story.
Start with what the data says. Then decide what to do about it.
View Strategy Dashboard →Net Revenue by Market
Shopify AnalyticsKey Insights
Revenue Velocity
Week-over-week revenue growth signals whether acquisition spend is landing. A US weekly run rate below $35K suggests either traffic quality issues or conversion drop-off that needs immediate channel attribution.
Market Concentration Risk
If US revenue exceeds 80% of total, the business is single-market vulnerable. UK revenue below 12% of total flags under-investment in a market with proven 2.8× LTV premium.
Seasonality Baseline
Q4 (Oct–Dec) typically delivers 38–42% of annual revenue. Any month in that window running below the prior year's same month is a structural signal, not a noise event.
Revenue per Active Customer
Divide net revenue by unique paying customers that month. Below $42/active customer in the US signals AOV compression or frequency drop, not volume problems.
Discount Drag
If total_discounts / gross_revenue exceeds 18%, margin compression is becoming structural. Track this monthly; it inflects before gross margin does.
Currency Normalisation
UK revenue reported in GBP means a 5% FX move creates phantom growth. Always view UK metrics in USD-equivalent before comparing MoM.
Combination Insights
Warning Signals
DuckDB Query
SELECT DATE_TRUNC('month', processed_at) AS month, CASE WHEN shipping_country = 'US' THEN 'US' WHEN shipping_country = 'GB' THEN 'UK' ELSE 'Other' END AS market, ROUND(SUM(total_price_usd), 2) AS net_revenue, ROUND(SUM(total_discounts_usd), 2) AS total_discounts, COUNT(DISTINCT order_id) AS order_count, ROUND(AVG(total_price_usd), 2) AS avg_order_value, LAG(SUM(total_price_usd)) OVER ( PARTITION BY shipping_country ORDER BY DATE_TRUNC('month', processed_at) ) AS prev_month_revenue, ROUND( (SUM(total_price_usd) - LAG(SUM(total_price_usd)) OVER ( PARTITION BY shipping_country ORDER BY DATE_TRUNC('month', processed_at) )) * 100.0 / NULLIF(LAG(SUM(total_price_usd)) OVER ( PARTITION BY shipping_country ORDER BY DATE_TRUNC('month', processed_at) ), 0), 1 ) AS mom_growth_pct FROM matrixify.orders WHERE payment_status = 'paid' AND cancelled_at IS NULL GROUP BY 1, 2 ORDER BY 1 DESC, 2
Decision Cards
Gross Margin %
Shopify AnalyticsKey Insights
Target Floor
Gross margin below 55% signals COGS is compressing profitability faster than revenue growth can compensate. The 55% floor is the minimum needed to sustain 20%+ EBITDA at current overhead ratios.
SKU-Level Variance
Aggregate margin masks product-mix effects. Darjeeling First Flush typically runs 68–72% GM; gift sets run 44–48%. A portfolio shift toward gift sets in Q4 will show a 4–6pp aggregate margin drop that is structural, not operational.
Shipping Cost Absorption
Free shipping thresholds directly erode margin at the $35–55 AOV band. Every 1% increase in orders hitting the free threshold reduces blended GM by ~0.4pp.
Discount vs Margin Interaction
A 15% discount on a 65% GM product drops that SKU to ~55% GM. Running win-back campaigns at 15% off on already-thin SKUs destroys unit economics.
FX Impact on Sourcing
Tea is sourced and invoiced in INR. A 5% INR/USD move affects COGS by approximately 1.8pp on blended margin. Track monthly with FX-adjusted COGS.
Combination Insights
Warning Signals
DuckDB Query
SELECT DATE_TRUNC('month', o.processed_at) AS month, ROUND(SUM(li.total), 2) AS gross_revenue, ROUND(SUM(li.total) - SUM(li.total * 0.42), 2) AS gross_profit, ROUND((1 - 0.42) * 100, 1) AS gross_margin_pct, ROUND(SUM(o.total_discounts_usd), 2) AS total_discounts, ROUND(SUM(o.total_discounts_usd) * 100.0 / NULLIF(SUM(li.total), 0), 1) AS discount_rate_pct FROM matrixify.order_line_items li JOIN matrixify.orders o USING(order_id) WHERE o.payment_status = 'paid' AND o.cancelled_at IS NULL GROUP BY 1 ORDER BY 1 DESC LIMIT 6
Decision Cards
AOV Trend
Shopify AnalyticsKey Insights
AOV Segmentation Gap
New customer AOV and returning customer AOV tell different stories. New buyers entering at $38–42 who don't repurchase within 90 days signal the product-market fit isn't translating to habit. Returning buyer AOV above $58 confirms the loyalty premium exists — the problem is getting there.
Bundle Uplift Signal
If your AOV is flat at $48 but bundle attachment rate (orders with ≥2 SKUs) is below 22%, you're leaving $8–12 per order on the table. AOV can be moved by cross-sell sequencing in email flows, not just on-site.
Free Shipping Threshold Effect
A free shipping threshold at $50 creates a natural AOV cluster just above and just below. If median AOV sits at $47–49, the threshold is working as an AOV floor. If median sits at $38, threshold pressure isn't being felt.
US vs UK AOV Delta
UK buyers typically transact at a 15–20% higher AOV (partly GBP denomination, partly gift culture). If UK AOV in USD terms drops below US AOV, something is wrong with UK merchandising or discount strategy.
Seasonal AOV Compression
Holiday gifting (Nov–Dec) brings in net-new gift buyers with one-time baskets skewed toward single SKU. Expect AOV to compress 12–18% in Dec vs Oct. This is structural, not a conversion problem.
Product Recommendation Quality
If post-purchase email sequences include cross-sell recommendations, measure AOV of customers who clicked a recommendation vs those who didn't. Delta above $15 means the recommendation algorithm is working.
AOV and Churn Correlation
Customers whose AOV drops 25%+ on their 2nd order versus 1st are 3.2× more likely to churn within 6 months. This is an early churn signal 60 days before the customer goes dark.
Combination Insights
Warning Signals
DuckDB Query
SELECT DATE_TRUNC('month', o.processed_at) AS month, ROUND(AVG(o.total_price_usd), 2) AS avg_order_value, ROUND(AVG(CASE WHEN c.order_number = 1 THEN o.total_price_usd END), 2) AS new_customer_aov, ROUND(AVG(CASE WHEN c.order_number > 1 THEN o.total_price_usd END), 2) AS returning_customer_aov, COUNT(o.order_id) AS total_orders, ROUND(AVG(li.item_count), 1) AS avg_items_per_order FROM matrixify.orders o JOIN ( SELECT email, ROW_NUMBER() OVER (PARTITION BY email ORDER BY processed_at) AS order_number FROM matrixify.orders WHERE payment_status = 'paid' AND cancelled_at IS NULL ) c ON o.email = c.email JOIN ( SELECT order_id, COUNT(*) AS item_count FROM matrixify.order_line_items GROUP BY order_id ) li USING(order_id) WHERE o.payment_status = 'paid' AND o.cancelled_at IS NULL GROUP BY 1 ORDER BY 1 DESC LIMIT 6
Decision Cards
Revenue per Session
Shopify Analytics + WebEngageKey Insights
Conversion Efficiency
Revenue per session (RPS) = AOV × conversion rate. A flat RPS with rising conversion and falling AOV means you're converting more low-value browsers. A flat RPS with falling conversion and rising AOV means you're converting fewer high-intent visitors.
Channel RPS Spread
Email traffic should deliver RPS 3–4× higher than paid social. If email RPS < $1.80, either the email audience is degrading or landing pages are mismatched to the email offer.
Mobile vs Desktop Split
Mobile sessions convert at 60–70% the rate of desktop for premium tea. If mobile sessions exceed 65% of traffic but mobile RPS is below $0.90, mobile UX is a revenue leak.
Session Quality Degradation
If sessions grow 20% MoM but RPS falls 15%, new traffic is low-intent. This often precedes a CAC increase by 30–45 days as paid platforms optimise toward volume over quality.
Combination Insights
Warning Signals
DuckDB Query
SELECT DATE_TRUNC('month', r.report_date) AS month, r.net_sales, t.total_sessions, ROUND(r.net_sales / NULLIF(t.total_sessions, 0), 2) AS revenue_per_session, t.bounce_rate, ROUND(r.orders * 100.0 / NULLIF(t.total_sessions, 0), 2) AS conversion_rate_pct FROM shopify_analytics.revenue_metrics r JOIN shopify_analytics.traffic_metrics t ON DATE_TRUNC('month', r.report_date) = DATE_TRUNC('month', t.report_date) AND r.report_period = 'month' AND t.report_period = 'month' ORDER BY 1 DESC LIMIT 6
Decision Cards
Repeat Purchase Rate 90d
MatrixifyKey Insights
The 90-Day Window
90 days is the empirical repurchase window for premium tea: sufficient for a 100g pack to be consumed, and short enough that the brand is still top-of-mind without intervention. A 30% repeat rate at 90 days is the threshold between a transactional brand and a ritual brand.
First-Order Cohort Decay
Customers who made their first purchase in a promotional event (BFCM, Diwali sale) repurchase at 40–50% the rate of organic first-time buyers. Cohort the repeat rate by acquisition channel to see true health.
SKU-Driven Repeatability
Customers whose first order included a loose-leaf tea repeat within 90 days at 2.3× the rate of customers whose first order was a gift set. Product selection on first purchase is the strongest predictor of retention.
Email Trigger Impact
A post-purchase email sequence (Day 7 education, Day 21 reorder nudge, Day 45 win-back) lifts 90-day repeat rate by 8–14 percentage points versus no flow. This metric directly reflects the engine you're running.
Geo Repeat Variance
UK buyers repeat within 90 days at 34–38% vs 26–30% for US buyers. If US 90-day repeat rate falls below 25%, US-specific retention flows need to be activated.
Discount Dependency
If >60% of second purchases are made with a discount code, the repeat behaviour is price-triggered, not habit-driven. This predicts higher eventual churn.
Subscription Conversion Proxy
Customers who repeat within 45 days (not 90) are subscription candidates. Track the 45-day sub-window separately as a conversion trigger.
Multi-Product Expansion
Customers who bought different SKUs on their 1st and 2nd orders have 2.8× higher 12-month LTV than customers who reordered the same SKU. Cross-category expansion is a stronger predictor than raw repeat rate.
Combination Insights
Warning Signals
DuckDB Query
WITH first_orders AS ( SELECT customer_id, email, MIN(processed_at) AS first_order_date, MIN(order_id) AS first_order_id FROM matrixify.orders WHERE payment_status = 'paid' AND cancelled_at IS NULL GROUP BY customer_id, email ), second_orders AS ( SELECT DISTINCT o.customer_id FROM matrixify.orders o JOIN first_orders f USING(customer_id) WHERE o.order_id != f.first_order_id AND o.payment_status = 'paid' AND DATEDIFF('day', f.first_order_date, o.processed_at) BETWEEN 1 AND 90 ) SELECT DATE_TRUNC('month', f.first_order_date) AS cohort_month, COUNT(f.customer_id) AS cohort_size, COUNT(s.customer_id) AS repeated_90d, ROUND(COUNT(s.customer_id) * 100.0 / NULLIF(COUNT(f.customer_id), 0), 1) AS repeat_rate_90d_pct FROM first_orders f LEFT JOIN second_orders s USING(customer_id) GROUP BY 1 ORDER BY 1 DESC LIMIT 6
Decision Cards
Cohort Retention 30/60/90d
MatrixifyKey Insights
30-Day Window
30-day retention is product-satisfaction driven. Customers who return within 30 days discovered a use case they didn't have before (morning ritual vs afternoon break). Below 12% at 30 days signals weak product-discovery in post-purchase emails.
30→60 Drop-off Rate
The steepness of the curve from 30-day to 60-day retention is a habit formation signal. A drop of <8pp from 30→60 day means habits are forming. A drop >15pp means first-purchase enthusiasm is fading without reinforcement.
Cohort Quality by Acquisition Month
Holiday cohorts (Nov–Dec acquisitions) typically show 30–40% lower 90-day retention than organic summer cohorts. Segment cohorts by acquisition channel to isolate structural vs seasonal effects.
Gender and Geography of Retention
UK cohorts retain at consistently higher rates across all three windows. If a month shows US cohort retention close to UK levels, investigate what drove that anomaly — it's replicable.
Retention Recovery Signal
A cohort that shows low 30-day retention but recovers at 60 days (uncommon but real) signals that the post-purchase sequence is working but with a delay. This happens when Day 21 reorder emails convert a few weeks late.
Baseline Setting
Three consecutive cohorts below target are a structural problem; one cohort below target is noise. Policy decisions should only be triggered after 2 consecutive below-target cohorts.
Retained Customer LTV Ratio
Customers retained at 90 days have average 12-month LTV 4.2× that of single-purchase customers. Each percentage point of 90-day retention is worth approximately $18K in incremental annual revenue per 1,000 cohort members.
Combination Insights
Warning Signals
DuckDB Query
WITH first_orders AS ( SELECT customer_id, DATE_TRUNC('month', MIN(processed_at)) AS cohort_month, MIN(processed_at) AS first_date FROM matrixify.orders WHERE payment_status = 'paid' AND cancelled_at IS NULL GROUP BY customer_id ), retention AS ( SELECT f.customer_id, f.cohort_month, MAX(CASE WHEN DATEDIFF('day', f.first_date, o.processed_at) BETWEEN 1 AND 30 THEN 1 ELSE 0 END) AS retained_30, MAX(CASE WHEN DATEDIFF('day', f.first_date, o.processed_at) BETWEEN 1 AND 60 THEN 1 ELSE 0 END) AS retained_60, MAX(CASE WHEN DATEDIFF('day', f.first_date, o.processed_at) BETWEEN 1 AND 90 THEN 1 ELSE 0 END) AS retained_90 FROM first_orders f LEFT JOIN matrixify.orders o ON f.customer_id = o.customer_id AND o.processed_at > f.first_date AND o.payment_status = 'paid' GROUP BY f.customer_id, f.cohort_month ) SELECT cohort_month, COUNT(*) AS cohort_size, ROUND(AVG(retained_30) * 100, 1) AS retention_30d_pct, ROUND(AVG(retained_60) * 100, 1) AS retention_60d_pct, ROUND(AVG(retained_90) * 100, 1) AS retention_90d_pct FROM retention GROUP BY cohort_month ORDER BY cohort_month DESC LIMIT 6
Decision Cards
Time to 2nd Purchase
MatrixifyKey Insights
Median vs Mean
Use median time-to-2nd, not mean. A small segment of customers buying again within 3 days (gift buyers) skews the mean down dramatically. The median gives you the central habit formation window.
The 45-Day Threshold
Customers who make a second purchase within 45 days have 3.8× higher 6-month LTV than those who repurchase between 46–90 days. The first 45 days is the critical habit formation window.
Email Flow Attribution
If you run a Day-21 reorder email and the P50 time-to-2nd shifts from 68 days to 52 days across two cohorts, the flow is working. This metric is your flow efficiency signal.
SKU-Driven Time Variation
Loose-leaf 100g packs drive repurchase at median 38 days (pack consumption rate). Teabag formats drive repurchase at median 28 days. Gift sets drive repurchase at median 82 days (gifter mentality, not personal consumption). SKU mix on first order explains most of the variance.
Percentile Distribution
P25, P50, P75 together tell the story: a tight P25–P75 range (say 25–55 days) means predictable habit formation. A wide range (15–110 days) means mixed purchase intent — some are personal consumers, some are gift buyers who return for themselves later.
Subscription Conversion Window
Customers who haven't repurchased by Day 30 but haven't churned by Day 45 are your highest-probability subscription conversion targets. This is the optimal send window for subscription upsell emails.
Combination Insights
Warning Signals
DuckDB Query
WITH first_orders AS ( SELECT customer_id, MIN(processed_at) AS first_date, MIN(order_id) AS first_order_id FROM matrixify.orders WHERE payment_status = 'paid' AND cancelled_at IS NULL GROUP BY customer_id ), second_orders AS ( SELECT o.customer_id, MIN(o.processed_at) AS second_date FROM matrixify.orders o JOIN first_orders f USING(customer_id) WHERE o.order_id != f.first_order_id AND o.payment_status = 'paid' AND o.cancelled_at IS NULL GROUP BY o.customer_id ) SELECT PERCENTILE_CONT(0.25) WITHIN GROUP (ORDER BY DATEDIFF('day', f.first_date, s.second_date)) AS p25_days, PERCENTILE_CONT(0.50) WITHIN GROUP (ORDER BY DATEDIFF('day', f.first_date, s.second_date)) AS p50_days, PERCENTILE_CONT(0.75) WITHIN GROUP (ORDER BY DATEDIFF('day', f.first_date, s.second_date)) AS p75_days, ROUND(AVG(DATEDIFF('day', f.first_date, s.second_date)), 1) AS mean_days, COUNT(*) AS sample_size FROM first_orders f JOIN second_orders s USING(customer_id) WHERE DATEDIFF('day', f.first_date, s.second_date) BETWEEN 1 AND 180
Decision Cards
LTV by Market
Matrixify + KlaviyoKey Insights
US LTV Target
$180 is the 12-month LTV target for US customers. Below $140 signals acquisition cohort quality is declining or retention flows are underperforming. The gap between current LTV and target multiplied by the active customer base is your retention revenue opportunity.
UK LTV Premium
UK customers historically carry a £130–£150 LTV (USD equivalent $155–$180), driven by higher AOV and stronger gifting culture. UK LTV below $140 USD is a structural alert, not seasonal noise.
LTV Quartile Distribution
The top 20% of customers typically deliver 65–70% of total revenue. If the top-quartile LTV is falling, you're losing your highest-value customers to churn before they've been fully monetised.
Channel LTV Variance
Customers acquired via email referral or organic search have 40–60% higher LTV than customers acquired via paid social. LTV by acquisition channel is the true paid channel ROI metric.
Subscription LTV Multiplier
Subscription customers have approximately 3.2× the LTV of equivalent one-time customers over 12 months. Rising subscription mix should show directly in blended LTV.
LTV Trajectory
A customer's 90-day spend is the best predictor of their 12-month LTV (R² ≈ 0.73). If average 90-day spend is falling, 12-month LTV will follow with a 3-month lag.
Predicted vs Actual
Klaviyo's predicted_clv_1y field is your leading indicator. If predicted LTV across the active base is falling, intervene with retention campaigns before actual LTV reflects it.
Combination Insights
Warning Signals
DuckDB Query
WITH customer_ltv AS ( SELECT o.email, p.churn_risk, p.predicted_clv_1y, CASE WHEN o.shipping_country = 'US' THEN 'US' WHEN o.shipping_country = 'GB' THEN 'UK' ELSE 'Other' END AS market, SUM(o.total_price_usd) AS actual_ltv, COUNT(o.order_id) AS total_orders, DATEDIFF('day', MIN(o.processed_at), MAX(o.processed_at)) AS customer_tenure_days FROM matrixify.orders o LEFT JOIN klaviyo.profiles p USING(email) WHERE o.payment_status = 'paid' AND o.cancelled_at IS NULL GROUP BY o.email, p.churn_risk, p.predicted_clv_1y, market ) SELECT market, ROUND(AVG(actual_ltv), 2) AS avg_actual_ltv, ROUND(AVG(predicted_clv_1y), 2) AS avg_predicted_ltv, ROUND(PERCENTILE_CONT(0.75) WITHIN GROUP (ORDER BY actual_ltv), 2) AS p75_ltv, ROUND(AVG(total_orders), 1) AS avg_orders, COUNT(*) AS customer_count FROM customer_ltv WHERE market IN ('US', 'UK') GROUP BY market ORDER BY market
Decision Cards
New vs Returning Mix
MatrixifyKey Insights
Health Ratio
A healthy D2C brand at Vahdam's stage should see 35–45% new customer revenue and 55–65% returning customer revenue. New > 60% of revenue means retention is weak; returning < 50% means growth has stalled.
Acquisition Dependency
If new customer revenue is growing but total revenue is flat, returning customer revenue is declining in absolute terms — classic leaky bucket. The new customer % metric will look fine while the business degrades.
Seasonal Shifts
Q4 holiday campaigns skew the mix toward new buyers (gift purchasers). New customer % of 55–60% in November is expected; maintaining that through February is an alarm signal.
New Cohort Quality Trending
Track new customers' average predicted LTV (from Klaviyo) at acquisition. Falling predicted LTV at acquisition means the acquisition machine is drawing lower-quality traffic — usually a sign of audience saturation or creative fatigue.
Returning Revenue per Customer
Divide returning customer revenue by returning customer count. If this ratio is falling, your retained base is spending less per visit — cross-sell is not working, or the product range is being perceived as complete.
Combination Insights
Warning Signals
DuckDB Query
WITH customer_orders AS ( SELECT email, order_id, processed_at, total_price_usd, ROW_NUMBER() OVER (PARTITION BY email ORDER BY processed_at) AS order_seq FROM matrixify.orders WHERE payment_status = 'paid' AND cancelled_at IS NULL ) SELECT DATE_TRUNC('month', processed_at) AS month, ROUND(SUM(CASE WHEN order_seq = 1 THEN total_price_usd ELSE 0 END), 2) AS new_customer_revenue, ROUND(SUM(CASE WHEN order_seq > 1 THEN total_price_usd ELSE 0 END), 2) AS returning_customer_revenue, COUNT(CASE WHEN order_seq = 1 THEN 1 END) AS new_customers, COUNT(CASE WHEN order_seq > 1 THEN 1 END) AS returning_customers, ROUND(SUM(CASE WHEN order_seq = 1 THEN total_price_usd ELSE 0 END) * 100.0 / NULLIF(SUM(total_price_usd), 0), 1) AS new_revenue_pct FROM customer_orders GROUP BY 1 ORDER BY 1 DESC LIMIT 6
Decision Cards
LTV:CAC by Channel
Matrixify + Shopify AnalyticsKey Insights
The 3x Rule
LTV:CAC of 3× or above means each acquired customer will generate $3 in LTV for every $1 spent acquiring them. Below 3×, the channel is not profitable at current scale. Below 2×, the channel is actively destroying value.
Payback Period Companion
LTV:CAC ratio alone doesn't tell you when you break even. A 4× ratio with a 14-month payback is worse than a 3× ratio with a 6-month payback. Always pair with payback period.
Channel-Level Variance
Email acquisition typically delivers the highest LTV:CAC (8–15×) because cost is near-zero for organic list growth. Paid social may run 2.5–4×. Influencer varies widely. Knowing channel-level ratios tells you where to shift marginal budget.
Scale Sensitivity
LTV:CAC ratios compress as channels scale. A Facebook campaign delivering 4× at $5K/month may deliver 2.8× at $25K/month as audience quality declines. Monitor ratio trend, not just current snapshot.
Blended vs Marginal
Blended LTV:CAC is the historical average. Marginal LTV:CAC (on the last $1 spent) is the decision variable. If blended is 3.5× but last month dropped to 2.4×, you're at inflection — cut before it blends further down.
Seasonal Adjustment
Q4 acquisition has structurally lower LTV:CAC because holiday cohorts retain poorly. Don't apply the standard 3× threshold to November acquisitions — use a 2.2× floor adjusted for the holiday retention discount.
Combination Insights
Warning Signals
DuckDB Query
SELECT acquisition_channel, ROUND(AVG(predicted_clv_1y), 2) AS avg_predicted_ltv, ROUND(AVG(acquisition_cost_usd), 2) AS avg_cac, ROUND(AVG(predicted_clv_1y) / NULLIF(AVG(acquisition_cost_usd), 0), 2) AS ltv_cac_ratio, CASE WHEN AVG(predicted_clv_1y) / NULLIF(AVG(acquisition_cost_usd), 0) >= 4 THEN 'SCALE' WHEN AVG(predicted_clv_1y) / NULLIF(AVG(acquisition_cost_usd), 0) >= 3 THEN 'HOLD' WHEN AVG(predicted_clv_1y) / NULLIF(AVG(acquisition_cost_usd), 0) >= 2 THEN 'REVIEW' ELSE 'PAUSE' END AS channel_action, COUNT(*) AS customer_count FROM klaviyo.profiles WHERE acquisition_channel IS NOT NULL AND acquisition_cost_usd > 0 GROUP BY acquisition_channel ORDER BY ltv_cac_ratio DESC
Decision Cards
CAC by Channel
Shopify Analytics + KlaviyoKey Insights
Absolute CAC Benchmarks
Acceptable CAC for Vahdam's price point and LTV profile: Paid Search $18–28, Paid Social $22–38, Influencer $15–45 (wide range by creator tier), Email/Organic $2–8. Anything above these ranges needs creative or targeting justification.
CAC Trend Matters More Than Level
A $32 CAC that has been stable for 6 months is better than a $28 CAC rising 8% month-over-month. CAC trajectory predicts payback period compression before it shows in profitability.
New Creative Cycle Impact
CAC on paid social tends to rise 15–25% after 6–8 weeks of running the same creative (audience fatigue). Monitoring CAC by channel gives you the earliest signal to refresh creative before CPMs spike.
Geography CAC Delta
UK customer acquisition costs are typically 20–35% higher than US due to smaller addressable audience and higher CPMs. UK CAC should be evaluated against UK LTV (£-denominated) rather than a blended USD benchmark.
First-Touch vs Multi-Touch
Last-touch attribution inflates paid social CAC (it captures the final click before purchase). Multi-touch or data-driven attribution typically reduces apparent paid social CAC by 15–20%. Be consistent in attribution model when tracking trends.
Combination Insights
Warning Signals
DuckDB Query
SELECT DATE_TRUNC('month', o.processed_at) AS month, p.acquisition_channel, COUNT(DISTINCT o.email) AS new_customers, ROUND(SUM(p.acquisition_cost_usd) / NULLIF(COUNT(DISTINCT o.email), 0), 2) AS cac, ROUND(AVG(p.predicted_clv_1y), 2) AS avg_predicted_ltv, ROUND(AVG(p.predicted_clv_1y) / NULLIF(AVG(p.acquisition_cost_usd), 0), 2) AS ltv_cac_ratio FROM matrixify.orders o JOIN klaviyo.profiles p USING(email) WHERE o.payment_status = 'paid' AND o.cancelled_at IS NULL AND p.acquisition_channel IS NOT NULL AND o.email IN ( SELECT email FROM ( SELECT email, ROW_NUMBER() OVER (PARTITION BY email ORDER BY processed_at) AS rn FROM matrixify.orders WHERE payment_status = 'paid' ) WHERE rn = 1 ) GROUP BY 1, 2 ORDER BY 1 DESC, cac DESC
Decision Cards
Checkout Conversion Rate
WebEngageKey Insights
Funnel Benchmarks
Premium tea D2C benchmarks: add-to-cart → checkout initiation: 45–55%, checkout initiation → purchase complete: 62–72%. Below these thresholds, either the cart experience or the payment step has friction.
Mobile Checkout Drop
Mobile checkout completion typically runs 12–18pp below desktop for purchase amounts over $45. Adding Apple Pay / Shop Pay can recover 6–9pp of mobile checkout conversion.
Shipping Cost Shock
The single largest cause of checkout abandonment for Vahdam's price range is unexpected shipping costs. Test free shipping threshold messaging in the cart view ('$8 away from free shipping') to reduce shock-based abandonment.
Guest Checkout Impact
Requiring account creation at checkout typically increases abandonment by 10–15%. Monitor what percentage of checkouts are initiated by logged-in vs guest users and whether account-gating correlates with abandonment.
Payment Method Distribution
Track conversion rate by payment method availability. Markets with higher digital wallet adoption (UK) will show higher conversion when Apple Pay/Google Pay are prominently featured.
Cart Size and Conversion
Carts with >3 items convert at a lower rate (customers second-guess large orders). Implement a 'Save for Later' feature or offer to split the order if cart value exceeds $80.
Return Visitor Conversion Premium
Returning visitors who've browsed before convert at 2.4× the rate of first-time visitors. Segment checkout conversion by visitor type to avoid blending these very different populations.
Time-of-Day Conversion
Checkout conversion peaks 7–9pm local time in both US and UK. Email sends that drive traffic at off-peak hours will show lower attached conversion rates.
Combination Insights
Warning Signals
DuckDB Query
SELECT DATE_TRUNC('week', event_date) AS week, SUM(CASE WHEN event_name = 'Checkout Initiated' THEN event_count ELSE 0 END) AS checkout_starts, SUM(CASE WHEN event_name = 'Order created' THEN event_count ELSE 0 END) AS purchases, ROUND( SUM(CASE WHEN event_name = 'Order created' THEN event_count ELSE 0 END) * 100.0 / NULLIF(SUM(CASE WHEN event_name = 'Checkout Initiated' THEN event_count ELSE 0 END), 0), 1) AS checkout_conversion_pct FROM webengage.event_summary WHERE event_date >= CURRENT_DATE - INTERVAL '56 days' GROUP BY 1 ORDER BY 1 DESC
Decision Cards
Cart Abandonment Rate
WebEngageKey Insights
Abandonment Benchmark
Industry average cart abandonment for D2C FMCG is 68–72%. Vahdam's target ceiling is 80%. Above 80%, the add-to-cart action is functioning as a wishlist, not purchase intent.
Recovery Flow Economics
A 3-email cart abandonment flow (1hr, 24hr, 72hr) typically recovers 8–15% of abandoned carts. At Vahdam's blended AOV of $48, each percentage point of recovery on 1,000 abandoned carts = $480 in incremental revenue.
Abandonment by Cart Value
Carts valued over $65 abandon at higher rates (43% above benchmark) due to purchase hesitation. Consider adding a 'low-stock' or 'ships tomorrow' indicator for these high-value carts.
Abandonment vs Checkout Initiation
Distinguish 'added to cart but never started checkout' (awareness abandonment) from 'started checkout but didn't complete' (friction abandonment). These require different interventions.
Repeat Abandoner Segment
Customers who abandon 2+ times in 30 days are 3.8× more likely to purchase if offered a small incentive (free shipping or 10% off) than standard reminder messaging. Identify this segment in Klaviyo.
Time-to-Abandonment
If median time between add-to-cart and session end is <90 seconds, the customer was price-checking, not abandoning due to friction. If median is >8 minutes, checkout friction is the issue.
Combination Insights
Warning Signals
DuckDB Query
SELECT DATE_TRUNC('week', event_date) AS week, SUM(CASE WHEN event_name = 'Added To Cart' THEN event_count ELSE 0 END) AS add_to_cart, SUM(CASE WHEN event_name = 'Order created' THEN event_count ELSE 0 END) AS completed_orders, ROUND( (1.0 - SUM(CASE WHEN event_name = 'Order created' THEN event_count ELSE 0 END) * 1.0 / NULLIF(SUM(CASE WHEN event_name = 'Added To Cart' THEN event_count ELSE 0 END), 0) ) * 100, 1 ) AS abandonment_pct FROM webengage.event_summary WHERE event_date >= CURRENT_DATE - INTERVAL '56 days' GROUP BY 1 ORDER BY 1 DESC
Decision Cards
Email Revenue %
KlaviyoKey Insights
The 25% Floor
Email should contribute a minimum 25% of total D2C revenue for a brand at Vahdam's email maturity. Below 25% means either the list is underleveraged, send frequency is too low, or the audience is disengaged.
Flow vs Campaign Split
Of the email revenue total, flows (automated sequences) should contribute 55–65% and campaigns (manual sends) 35–45%. Heavy campaign dependence means revenue is manual and unpredictable; heavy flow dependence is scalable but needs regular content refresh.
Revenue per Recipient
Track revenue per recipient (RPR) per campaign. Below $0.08 RPR signals list fatigue or poor segmentation. Above $0.25 RPR indicates a high-performing campaign worth repeating or A/B testing.
Klaviyo Attribution Window
Klaviyo's default attribution window is 5-day click, 1-day open. This tends to over-attribute compared to a 1-day click model. Ensure you're using a consistent attribution window across reports.
List Size vs Revenue Efficiency
Revenue per recipient is more useful than total email revenue for tracking performance. A growing list with flat RPR means added subscribers are less engaged — review acquisition source quality.
Email Contribution to Retention
Post-purchase flows should generate 12–18% of total email revenue. If this percentage is low, post-purchase sequences are underperforming and retention is being missed.
Unsubscribe Rate Impact
Each percentage point of list health decline reduces total email revenue by approximately 1.5× that rate, compounded over 12 months. Email list health (M16) is the leading indicator for this metric.
Combination Insights
Warning Signals
DuckDB Query
SELECT DATE_TRUNC('month', k.sent_at) AS month, ROUND(SUM(k.revenue_attributed), 2) AS email_revenue, ROUND(MAX(r.net_sales), 2) AS total_revenue, ROUND(SUM(k.revenue_attributed) * 100.0 / NULLIF(MAX(r.net_sales), 0), 1) AS email_revenue_pct, ROUND(SUM(k.revenue_attributed) / NULLIF(SUM(k.recipients), 0), 3) AS revenue_per_recipient, SUM(k.recipients) AS total_recipients FROM klaviyo.campaigns k JOIN shopify_analytics.revenue_metrics r ON DATE_TRUNC('month', k.sent_at) = r.report_date AND r.report_period = 'month' WHERE k.channel = 'email' GROUP BY 1 ORDER BY 1 DESC LIMIT 6
Decision Cards
Flow vs Campaign Split
KlaviyoKey Insights
Automation Health Ratio
Flows should generate 55–65% of email revenue. Below 50% means too much manual effort is sustaining email revenue — fragile and not scalable. Above 70% means campaigns are underperforming their potential.
Flow Types Breakdown
Of flow revenue, welcome series should contribute 8–12%, post-purchase 12–18%, win-back 10–15%, browse abandonment 6–10%, cart abandonment 15–20%. If any single flow is contributing >30%, other flows are likely misconfigured.
Campaign Frequency Baseline
2–3 campaigns per week to the full list will cause list fatigue within 6 months. Segment campaigns by engagement tier (highly engaged, engaged, at-risk) and reduce frequency for lower tiers.
Flow Conversion Rates
Track conversion rate per flow, not just revenue attribution. A high-revenue flow with low conversion may just have high send volume. A low-revenue flow with high conversion is an underutilised asset.
Seasonal Campaign Lift
Campaign revenue spikes in Q4 (Oct–Dec) are expected and healthy; this is the nature of promotional campaigns. The ratio should naturally shift toward campaigns during this period and recover in Q1.
Combination Insights
Warning Signals
DuckDB Query
SELECT DATE_TRUNC('month', sent_at) AS month, campaign_type, COUNT(campaign_id) AS send_count, SUM(recipients) AS total_recipients, ROUND(SUM(revenue_attributed), 2) AS revenue, ROUND(AVG(open_rate) * 100, 1) AS avg_open_rate_pct, ROUND(AVG(ctor) * 100, 1) AS avg_ctor_pct, ROUND(SUM(revenue_attributed) / NULLIF(SUM(recipients), 0), 3) AS revenue_per_recipient FROM klaviyo.campaigns WHERE channel = 'email' GROUP BY 1, 2 ORDER BY 1 DESC, revenue DESC
Decision Cards
Email List Health
KlaviyoKey Insights
Health Definition
Email list health is the proportion of subscribers who are deliverable (not bounced or spam-flagged) and have engaged (opened or clicked) within the last 90 days. Below 80% health triggers ISP reputation risk that can cascade into all sends, including flows.
Bounce Cascade Risk
Hard bounce rates above 2% across a single send can trigger Gmail/Yahoo bulk sender penalties that affect all future sends. Hard bounces should be removed from the list immediately after the first occurrence.
Spam Complaint Threshold
Google's bulk sender threshold is 0.10% spam complaint rate. Above this, deliverability is penalised across the domain. Above 0.30%, the domain may be temporarily blocked.
Re-engagement Window
Subscribers with no open in 180 days should be entered into a re-engagement flow before being sunset. Sending marketing emails to unengaged subscribers is the primary driver of list health degradation.
List Growth Quality
List health tells you about the existing subscriber base. If list health is falling while the list is growing, new subscriber quality is low — evaluate acquisition source and double opt-in status.
Segmentation Impact
Sending only to engaged segments (opens in 90 days) will show higher open rates but is also protecting list health. Aggressive full-list sends will suppress apparent open rates and degrade health.
Combination Insights
Warning Signals
DuckDB Query
SELECT DATE_TRUNC('month', last_active_date) AS month, COUNT(*) AS total_profiles, COUNT(CASE WHEN email_status = 'subscribed' THEN 1 END) AS subscribed, COUNT(CASE WHEN email_status = 'unsubscribed' THEN 1 END) AS unsubscribed, COUNT(CASE WHEN email_status = 'bounced' THEN 1 END) AS bounced, ROUND(COUNT(CASE WHEN email_status = 'subscribed' AND last_active_date >= CURRENT_DATE - INTERVAL '90 days' THEN 1 END) * 100.0 / NULLIF(COUNT(CASE WHEN email_status = 'subscribed' THEN 1 END), 0), 1) AS engaged_pct FROM klaviyo.profiles GROUP BY 1 ORDER BY 1 DESC LIMIT 6
Decision Cards
Churn Risk Distribution
KlaviyoKey Insights
Risk Tier Definitions
Klaviyo's churn risk model typically outputs: active (purchased in 30 days), at-risk (31–60 days no purchase), high risk (61–90 days), winback (90+ days). These correspond to decreasing probability of repeat purchase.
Revenue Concentration in Risk Tiers
If high-risk and winback segments collectively hold >35% of predicted CLV, the business has a structural retention problem, not a marketing problem. Customer success or product intervention is needed.
High-CLV Churn Signal
Customers with predicted CLV > $200 moving into high-risk/winback tier represent recoverable revenue. This is the trigger for the P1 win_back_vip campaign in the mailer engine.
Churn Leading Indicators
Email engagement drops 3–4 weeks before churn risk increases. Customers who stop opening emails but haven't yet churned are the ideal intervention target — still reachable, not yet lost.
Winback Recovery Rate Benchmark
Industry winback recovery rate for premium D2C is 8–15%. At Vahdam's CLV profile, even 10% recovery of a $200K at-risk cohort generates $20K incremental revenue — typically well above flow cost.
Seasonal Churn Pattern
Post-holiday (Jan–Feb) typically shows a churn spike as gift buyers don't convert to personal buyers. Proactive January reactivation campaigns for December new cohorts can halve this spike.
Risk Distribution Stability
Track the distribution monthly: % active, % at-risk, % high-risk, % winback. A stable distribution with active > 60% is healthy. Active declining month-over-month is the most important early warning.
Combination Insights
Warning Signals
DuckDB Query
SELECT churn_risk, COUNT(*) AS profile_count, ROUND(AVG(predicted_clv_1y), 2) AS avg_predicted_clv, ROUND(SUM(predicted_clv_1y), 2) AS total_at_risk_clv, ROUND(COUNT(*) * 100.0 / SUM(COUNT(*)) OVER (), 1) AS pct_of_list, COUNT(CASE WHEN predicted_clv_1y > 200 THEN 1 END) AS high_clv_count FROM klaviyo.profiles WHERE email_status = 'subscribed' GROUP BY churn_risk ORDER BY CASE churn_risk WHEN 'active' THEN 1 WHEN 'at_risk' THEN 2 WHEN 'high' THEN 3 WHEN 'winback' THEN 4 ELSE 5 END
Decision Cards
At-Risk Revenue
KlaviyoKey Insights
The $50K Trigger
When predicted CLV of customers in high-risk + winback tiers exceeds $50K, the win_back_vip campaign trigger fires automatically. This threshold was calibrated against Vahdam's average win-back campaign cost and recovery rate.
Recoverable vs Lost Revenue
Not all at-risk CLV is recoverable. Empirical recovery rate for premium D2C win-back campaigns is 8–15%. Apply this range to at-risk CLV to estimate the campaign's revenue opportunity: $50K at-risk × 12% recovery = $6K incremental revenue.
Segmentation Depth
At-risk revenue should be segmented by: last SKU purchased (product-specific re-engagement), days since last order (urgency calibration), and predicted CLV tier (offer calibration — high CLV gets 15% off, mid CLV gets free shipping).
Campaign ROI Calculation
Win-back campaign ROI = (at-risk CLV × recovery rate × gross margin) - campaign cost. At Vahdam's 55%+ GM and a $2K email campaign cost, the ROI is positive at recovery rates above 4%.
At-Risk Revenue Trend
If at-risk revenue grows month-over-month even after win-back campaigns, the acquisition machine is adding customers faster than retention is keeping them. Address the retention system, not just the win-back symptom.
Time-Decay Factor
The probability of winback declines with time: 12% at 60 days, 8% at 90 days, 4% at 120 days. Send win-back campaigns at 60–75 days since last purchase — not earlier (intrusive) and not later (probability too low).
Combination Insights
Warning Signals
DuckDB Query
SELECT churn_risk, COUNT(*) AS at_risk_count, ROUND(SUM(predicted_clv_1y), 2) AS total_at_risk_revenue, ROUND(AVG(predicted_clv_1y), 2) AS avg_clv, ROUND(AVG(total_orders), 1) AS avg_orders, ROUND(AVG(DATEDIFF('day', last_order_date::DATE, CURRENT_DATE)), 0) AS avg_days_since_order, COUNT(CASE WHEN predicted_clv_1y > 200 THEN 1 END) AS high_clv_at_risk FROM klaviyo.profiles WHERE churn_risk IN ('high', 'winback') AND email_status = 'subscribed' GROUP BY churn_risk ORDER BY total_at_risk_revenue DESC
Decision Cards
Product Repeat Rate
MatrixifyKey Insights
SKU-Level Retention Signal
Product repeat rate measures how frequently customers reorder the same SKU. A rate above 35% for a loose-leaf product signals it has become a habit product. Below 20% means it's being experienced as a one-time purchase.
Portfolio Architecture
High-repeat SKUs should anchor subscription offerings. Low-repeat SKUs should be positioned as discovery or gift items. Matching subscription promotion to repeat-rate data prevents over-subscribing products with natural variety-seeking behaviour.
First-Order SKU Impact
The repeat rate of the first SKU purchased predicts overall customer retention. Darjeeling First Flush as a first-order SKU drives 2.3× repeat rate vs gift sets. This data should inform acquisition creative featuring product-led (not set-led) messaging.
Cross-SKU Progression
Customers who repeat-purchase within category (e.g., Darjeeling → Assam → Nilgiri) have higher LTV than same-SKU repeaters. Track cross-category expansion as a retention quality metric.
Seasonal SKU Rotation
Some SKUs have inherent seasonality (First Flush is spring/summer, autumnal blends are Q3/Q4). Low repeat rate in off-season is expected; track trailing 12-month repeat rate for seasonal products.
Bundle Fragmentation
Bundles rarely repeat as-is (customers want variety). Track bundle component SKU repeat separately from bundle-as-item repeat to avoid artificially deflating repeat rate for high-performing ingredients.
Subscription Conversion by Repeat Rate
SKUs with >40% repeat rate AND >200 subscription subscribers should be reviewed for subscription pricing — they may be underpriced for auto-replenishment demand.
Combination Insights
Warning Signals
DuckDB Query
SELECT li.title AS product_name, COUNT(DISTINCT o.email) AS unique_buyers, COUNT(*) AS total_orders, ROUND(COUNT(*) * 1.0 / NULLIF(COUNT(DISTINCT o.email), 0), 2) AS orders_per_buyer, COUNT(DISTINCT CASE WHEN o.email IN ( SELECT email FROM matrixify.orders WHERE payment_status = 'paid' GROUP BY email HAVING COUNT(*) > 1 ) THEN o.email END) AS repeat_buyers, ROUND(COUNT(DISTINCT CASE WHEN o.email IN ( SELECT email FROM matrixify.orders WHERE payment_status = 'paid' GROUP BY email HAVING COUNT(*) > 1 ) THEN o.email END) * 100.0 / NULLIF(COUNT(DISTINCT o.email), 0), 1) AS repeat_buyer_pct FROM matrixify.order_line_items li JOIN matrixify.orders o USING(order_id) WHERE o.payment_status = 'paid' AND o.cancelled_at IS NULL GROUP BY li.title HAVING COUNT(DISTINCT o.email) >= 50 ORDER BY repeat_buyer_pct DESC LIMIT 10
Decision Cards
Subscription Mix %
MatrixifyKey Insights
The 15% Target
Subscription orders should represent at least 15% of total monthly order volume. Below 15%, subscription infrastructure is underutilised. Above 30%, subscription has likely become a discount channel rather than a convenience-and-habit driver.
Subscription Revenue Stability
Subscription revenue is predictable: it buffers total revenue against promotional cycles and campaign variability. A 15% subscription mix creates a predictable monthly revenue floor that improves forecasting and reduces paid campaign dependency.
Subscription AOV Premium
Subscription orders consistently run 8–12% higher AOV than one-time orders because customers add complementary SKUs during subscription setup. This AOV premium is captured at setup, not at renewal.
Churn Rate Within Subscription
Active subscriptions have a monthly churn rate of 3–6% for premium D2C. Below 3% is excellent. Above 8% means subscribers aren't experiencing the value proposition (product quality, convenience, or perceived savings).
Subscription Conversion Window
The highest-conversion window for subscription upsell is immediately post-purchase (checkout upsell) and Day 14–30 post-purchase (habit formation window). Outside these windows, conversion rates drop significantly.
Subscription SKU Concentration
If >60% of subscription revenue comes from a single SKU, the subscription programme is fragile. Diversification across 3–5 SKUs is the healthier model.
Cancellation Reason Distribution
Track subscription cancellation reasons: 'too much tea' (frequency issue), 'too expensive' (price issue), 'switching product' (assortment issue). Each has a different intervention: frequency change, discount, or cross-SKU recommendation.
Subscriber LTV Multiplier
Subscription customers have 3.2× the 12-month LTV of comparable one-time customers. Each 1pp increase in subscription mix improves blended LTV by approximately $4–7 depending on cohort CLV distribution.
Combination Insights
Warning Signals
DuckDB Query
SELECT DATE_TRUNC('month', o.processed_at) AS month, COUNT(o.order_id) AS total_orders, SUM(CASE WHEN li.properties::TEXT ILIKE '%subscription%' OR li.properties::TEXT ILIKE '%frequency%' THEN 1 ELSE 0 END) AS subscription_orders, ROUND(SUM(CASE WHEN li.properties::TEXT ILIKE '%subscription%' OR li.properties::TEXT ILIKE '%frequency%' THEN 1 ELSE 0 END) * 100.0 / NULLIF(COUNT(o.order_id), 0), 1) AS subscription_mix_pct, ROUND(AVG(CASE WHEN li.properties::TEXT ILIKE '%subscription%' THEN o.total_price_usd END), 2) AS subscription_aov, ROUND(AVG(CASE WHEN li.properties::TEXT NOT ILIKE '%subscription%' THEN o.total_price_usd END), 2) AS onetime_aov FROM matrixify.orders o JOIN matrixify.order_line_items li USING(order_id) WHERE o.payment_status = 'paid' AND o.cancelled_at IS NULL GROUP BY 1 ORDER BY 1 DESC LIMIT 6