What does a newsletter growth dashboard show in Metabase?
A newsletter growth dashboard shows whether a publication is compounding: net subscriber growth by acquisition source, engagement per post, referral performance, and revenue per send in one governed view. It's built from subscriber and post data synced out of beehiiv, Kit, or Mailchimp — history the platforms themselves don't keep.
Which cards belong on a newsletter growth dashboard?
- Net subscriber growth — subscribes vs. losses by month (combo)
- Growth rate trend on running list size (line)
- New subscribers by acquisition source (stacked bar)
- Retention by source cohort — who's still active (table)
- Click-through rate per post (table)
- Engaged-subscriber share — clicked in last 90 days (line)
- Referral program: invites and conversions (combo)
- Revenue per send — premium, products, ads (bar)
What data does the dashboard need?
subscription_events— subscribe, unsubscribe, and cleaned events with timestamps and acquisition source.subscribers— created date, status, source, tags or tier, referral counts.post_stats— one row per send: recipients, unique clicks, web views, unsubscribes.- Revenue rows where they exist — premium tiers, product sales, sponsorship income — joinable by month or by send.
How do you build it?
- Sync subscribers and post stats on a schedule — the beehiiv and Kit guides cover the API-script and connector routes. Start early: platforms expose current state, so the synced event streamis your history.
- Tag acquisition source on every subscriber at creation, and keep imports as their own series.
- Model monthly net growth (subscribes − unsubscribes − cleaned) and a running list size for the rate card.
- Add engagement and revenue cards, all filterable by source, tier, and period.
Example card SQL
WITH monthly AS (
SELECT
date_trunc('month', occurred_at) AS month,
acquisition_source,
COUNT(*) FILTER (WHERE event_type = 'subscribe') AS subscribes,
COUNT(*) FILTER (WHERE event_type = 'unsubscribe') AS unsubscribes,
COUNT(*) FILTER (WHERE event_type = 'cleaned') AS cleaned
FROM subscription_events
GROUP BY 1, 2
)
SELECT
month,
acquisition_source,
subscribes,
unsubscribes + cleaned AS losses,
subscribes - unsubscribes - cleaned AS net_growth
FROM monthly
ORDER BY month, net_growth DESC;