| name | kpi-dashboard-design |
| description | Design effective KPI dashboards with metrics selection, visualization best practices, and real-time monitoring patterns. Use when building business dashboards, selecting metrics, or designing data ... |
| risk | unknown |
| source | community |
KPI Dashboard Design
Comprehensive patterns for designing effective Key Performance Indicator (KPI) dashboards that drive business decisions.
Do not use this skill when
- The task is unrelated to kpi dashboard design
- You need a different domain or tool outside this scope
Instructions
- Clarify goals, constraints, and required inputs.
- Apply relevant best practices and validate outcomes.
- Provide actionable steps and verification.
- If detailed examples are required, open
resources/implementation-playbook.md.
Use this skill when
- Designing executive dashboards
- Selecting meaningful KPIs
- Building real-time monitoring displays
- Creating department-specific metrics views
- Improving existing dashboard layouts
- Establishing metric governance
Core Concepts
1. KPI Framework
| Level | Focus | Update Frequency | Audience |
|---|
| Strategic | Long-term goals | Monthly/Quarterly | Executives |
| Tactical | Department goals | Weekly/Monthly | Managers |
| Operational | Day-to-day | Real-time/Daily | Teams |
2. SMART KPIs
Specific: Clear definition
Measurable: Quantifiable
Achievable: Realistic targets
Relevant: Aligned to goals
Time-bound: Defined period
3. Dashboard Hierarchy
├── Executive Summary (1 page)
│ ├── 4-6 headline KPIs
│ ├── Trend indicators
│ └── Key alerts
├── Department Views
│ ├── Sales Dashboard
│ ├── Marketing Dashboard
│ ├── Operations Dashboard
│ └── Finance Dashboard
└── Detailed Drilldowns
├── Individual metrics
└── Root cause analysis
Common KPIs by Department
Sales KPIs
Revenue Metrics:
- Monthly Recurring Revenue (MRR)
- Annual Recurring Revenue (ARR)
- Average Revenue Per User (ARPU)
- Revenue Growth Rate
Pipeline Metrics:
- Sales Pipeline Value
- Win Rate
- Average Deal Size
- Sales Cycle Length
Activity Metrics:
- Calls/Emails per Rep
- Demos Scheduled
- Proposals Sent
- Close Rate
Marketing KPIs
Acquisition:
- Cost Per Acquisition (CPA)
- Customer Acquisition Cost (CAC)
- Lead Volume
- Marketing Qualified Leads (MQL)
Engagement:
- Website Traffic
- Conversion Rate
- Email Open/Click Rate
- Social Engagement
ROI:
- Marketing ROI
- Campaign Performance
- Channel Attribution
- CAC Payback Period
Product KPIs
Usage:
- Daily/Monthly Active Users (DAU/MAU)
- Session Duration
- Feature Adoption Rate
- Stickiness (DAU/MAU)
Quality:
- Net Promoter Score (NPS)
- Customer Satisfaction (CSAT)
- Bug/Issue Count
- Time to Resolution
Growth:
- User Growth Rate
- Activation Rate
- Retention Rate
- Churn Rate
Finance KPIs
Profitability:
- Gross Margin
- Net Profit Margin
- EBITDA
- Operating Margin
Liquidity:
- Current Ratio
- Quick Ratio
- Cash Flow
- Working Capital
Efficiency:
- Revenue per Employee
- Operating Expense Ratio
- Days Sales Outstanding
- Inventory Turnover
Dashboard Layout Patterns
Pattern 1: Executive Summary
┌─────────────────────────────────────────────────────────────┐
│ EXECUTIVE DASHBOARD [Date Range ▼] │
├─────────────┬─────────────┬─────────────┬─────────────────┤
│ REVENUE │ PROFIT │ CUSTOMERS │ NPS SCORE │
│ $2.4M │ $450K │ 12,450 │ 72 │
│ ▲ 12% │ ▲ 8% │ ▲ 15% │ ▲ 5pts │
├─────────────┴─────────────┴─────────────┴─────────────────┤
│ │
│ Revenue Trend │ Revenue by Product │
│ ┌───────────────────────┐ │ ┌──────────────────┐ │
│ │ /\ /\ │ │ │ ████████ 45% │ │
│ │ / \ / \ /\ │ │ │ ██████ 32% │ │
│ │ / \/ \ / \ │ │ │ ████ 18% │ │
│ │ / \/ \ │ │ │ ██ 5% │ │
│ └───────────────────────┘ │ └──────────────────┘ │
│ │
├─────────────────────────────────────────────────────────────┤
│ 🔴 Alert: Churn rate exceeded threshold (>5%) │
│ 🟡 Warning: Support ticket volume 20% above average │
└─────────────────────────────────────────────────────────────┘
Pattern 2: SaaS Metrics Dashboard
┌─────────────────────────────────────────────────────────────┐
│ SAAS METRICS Jan 2024 [Monthly ▼] │
├──────────────────────┬──────────────────────────────────────┤
│ ┌────────────────┐ │ MRR GROWTH │
│ │ MRR │ │ ┌────────────────────────────────┐ │
│ │ $125,000 │ │ │ /── │ │
│ │ ▲ 8% │ │ │ /────/ │ │
│ └────────────────┘ │ │ /────/ │ │
│ ┌────────────────┐ │ │ /────/ │ │
│ │ ARR │ │ │ /────/ │ │
│ │ $1,500,000 │ │ └────────────────────────────────┘ │
│ │ ▲ 15% │ │ J F M A M J J A S O N D │
│ └────────────────┘ │ │
├──────────────────────┼──────────────────────────────────────┤
│ UNIT ECONOMICS │ COHORT RETENTION │
│ │ │
│ CAC: $450 │ Month 1: ████████████████████ 100% │
│ LTV: $2,700 │ Month 3: █████████████████ 85% │
│ LTV/CAC: 6.0x │ Month 6: ████████████████ 80% │
│ │ Month 12: ██████████████ 72% │
│ Payback: 4 months │ │
├──────────────────────┴──────────────────────────────────────┤
│ CHURN ANALYSIS │
│ ┌──────────┬──────────┬──────────┬──────────────────────┐ │
│ │ Gross │ Net │ Logo │ Expansion │ │
│ │ 4.2% │ 1.8% │ 3.1% │ 2.4% │ │
│ └──────────┴──────────┴──────────┴──────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
Pattern 3: Real-time Operations
┌─────────────────────────────────────────────────────────────┐
│ OPERATIONS CENTER Live ● Last: 10:42:15 │
├────────────────────────────┬────────────────────────────────┤
│ SYSTEM HEALTH │ SERVICE STATUS │
│ ┌──────────────────────┐ │ │
│ │ CPU MEM DISK │ │ ● API Gateway Healthy │
│ │ 45% 72% 58% │ │ ● User Service Healthy │
│ │ ███ ████ ███ │ │ ● Payment Service Degraded │
│ │ ███ ████ ███ │ │ ● Database Healthy │
│ │ ███ ████ ███ │ │ ● Cache Healthy │
│ └──────────────────────┘ │ │
├────────────────────────────┼────────────────────────────────┤
│ REQUEST THROUGHPUT │ ERROR RATE │
│ ┌──────────────────────┐ │ ┌──────────────────────────┐ │
│ │ ▁▂▃▄▅▆▇█▇▆▅▄▃▂▁▂▃▄▅ │ │ │ ▁▁▁▁▁▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁ │ │
│ └──────────────────────┘ │ └──────────────────────────┘ │
│ Current: 12,450 req/s │ Current: 0.02% │
│ Peak: 18,200 req/s │ Threshold: 1.0% │
├────────────────────────────┴────────────────────────────────┤
│ RECENT ALERTS │
│ 10:40 🟡 High latency on payment-service (p99 > 500ms) │
│ 10:35 🟢 Resolved: Database connection pool recovered │
│ 10:22 🔴 Payment service circuit breaker tripped │
└─────────────────────────────────────────────────────────────┘
Implementation Patterns
SQL for KPI Calculations
WITH mrr_calculation AS (
SELECT
DATE_TRUNC('month', billing_date) AS month,
SUM(
CASE subscription_interval
WHEN 'monthly' THEN amount
WHEN 'yearly' THEN amount / 12
WHEN 'quarterly' THEN amount / 3
END
) AS mrr
FROM subscriptions
WHERE status = 'active'
GROUP BY DATE_TRUNC('month', billing_date)
)
SELECT
month,
mrr,
LAG(mrr) OVER (ORDER BY month) AS prev_mrr,
(mrr - LAG(mrr) OVER (ORDER BY month)) / LAG(mrr) OVER (ORDER BY month) * 100 growth_pct
mrr_calculation;
cohorts (
user_id,
DATE_TRUNC(, created_at) cohort_month
users
),
activity (
user_id,
DATE_TRUNC(, event_date) activity_month
user_events
event_type
)
c.cohort_month,
( age(a.activity_month, c.cohort_month)) months_since_signup,
( a.user_id) active_users,
( a.user_id):: ( c.user_id) retention_rate
cohorts c
activity a c.user_id a.user_id
a.activity_month c.cohort_month
c.cohort_month, ( age(a.activity_month, c.cohort_month))
c.cohort_month, months_since_signup;
DATE_TRUNC(, acquired_date) ,
(marketing_spend) ((new_customers), ) cac,
(marketing_spend) total_spend,
(new_customers) customers_acquired
(
DATE_TRUNC(, u.created_at) acquired_date,
u.id new_customers,
m.spend marketing_spend
users u
marketing_spend m DATE_TRUNC(, u.created_at) m.month
u.source
) acquisition
DATE_TRUNC(, acquired_date);
Python Dashboard Code (Streamlit)
import streamlit as st
import pandas as pd
import plotly.express as px
import plotly.graph_objects as go
st.set_page_config(page_title="KPI Dashboard", layout="wide")
col1, col2 = st.columns([3, 1])
with col1:
st.title("Executive Dashboard")
with col2:
date_range = st.selectbox(
"Period",
["Last 7 Days", "Last 30 Days", "Last Quarter", "YTD"]
)
def metric_card(label, value, delta, prefix="", suffix=""):
delta_color = "green" if delta >= 0 else "red"
delta_arrow = "▲" if delta >= 0 else "▼"
st.metric(
label=label,
value=f"{prefix}{value:,.0f}{suffix}",
delta=f"{delta_arrow} {abs(delta):.1f}%"
)
col1, col2, col3, col4 = st.columns(4)
with col1:
metric_card("Revenue", 2400000, , prefix=)
col2:
metric_card(, , )
col3:
metric_card(, , )
col4:
metric_card(, , -, suffix=)
col1, col2 = st.columns()
col1:
st.subheader()
revenue_data = pd.DataFrame({
: pd.date_range(, periods=, freq=),
: [, , , , , ,
, , , , , ]
})
fig = px.line(revenue_data, x=, y=,
line_shape=, markers=)
fig.update_layout(height=)
st.plotly_chart(fig, use_container_width=)
col2:
st.subheader()
product_data = pd.DataFrame({
: [, , , ],
: [, , , ]
})
fig = px.pie(product_data, values=, names=,
hole=)
fig.update_layout(height=)
st.plotly_chart(fig, use_container_width=)
st.subheader()
cohort_data = pd.DataFrame({
: [, , , , ],
: [, , , , ],
: [, , , , ],
: [, , , , ],
: [, , , , ],
: [, , , , ],
})
fig = go.Figure(data=go.Heatmap(
z=cohort_data.iloc[:, :].values,
x=[, , , , ],
y=cohort_data[],
colorscale=,
text=cohort_data.iloc[:, :].values,
texttemplate=,
textfont={: },
))
fig.update_layout(height=)
st.plotly_chart(fig, use_container_width=)
st.subheader()
alerts = [
{: , : },
{: , : },
]
alert alerts:
alert[] == :
st.error()
alert[] == :
st.warning()
Best Practices
Do's
- Limit to 5-7 KPIs - Focus on what matters
- Show context - Comparisons, trends, targets
- Use consistent colors - Red=bad, green=good
- Enable drilldown - From summary to detail
- Update appropriately - Match metric frequency
Don'ts
- Don't show vanity metrics - Focus on actionable data
- Don't overcrowd - White space aids comprehension
- Don't use 3D charts - They distort perception
- Don't hide methodology - Document calculations
- Don't ignore mobile - Ensure responsive design
Resources