How to Build a Sales Pipeline Velocity Dashboard
Track deal velocity metrics in real-time to identify pipeline bottlenecks.
Jay Banlasan
The AI Systems Guy
Pipeline velocity tells you how fast deals move through your funnel. This sales pipeline velocity dashboard shows it in real time with the metrics that matter. I use this to spot bottlenecks the moment they form, not weeks later when revenue is already gone.
What You Need Before Starting
- Python 3.8+ with Flask
- CRM API access
- Chart.js or Plotly for visualization
- SQLite for storage
Step 1: Calculate Velocity Metrics
Pipeline velocity has four components: number of deals, average deal value, win rate, and average sales cycle length.
def calculate_velocity(deals_df):
won = deals_df[deals_df["status"] == "won"]
total = len(deals_df)
metrics = {
"deal_count": total,
"avg_value": deals_df["amount"].mean(),
"win_rate": len(won) / max(total, 1),
"avg_cycle_days": deals_df["cycle_days"].mean(),
}
metrics["velocity"] = (
metrics["deal_count"] * metrics["avg_value"] * metrics["win_rate"]
) / max(metrics["avg_cycle_days"], 1)
return metrics
Step 2: Track by Stage
Break velocity down by stage. This shows exactly where deals get stuck.
def velocity_by_stage(deals_df, stages):
stage_metrics = {}
for stage in stages:
stage_deals = deals_df[deals_df["current_stage"] == stage]
stage_metrics[stage] = {
"count": len(stage_deals),
"avg_days": stage_deals["days_in_stage"].mean(),
"total_value": stage_deals["amount"].sum(),
}
return stage_metrics
Step 3: Build the Dashboard API
Serve the data through a simple Flask API. The frontend fetches fresh numbers every time.
from flask import Flask, jsonify
from datetime import datetime
app = Flask(__name__)
@app.route("/api/velocity")
def get_velocity():
deals = fetch_deals_from_crm()
velocity = calculate_velocity(deals)
by_stage = velocity_by_stage(
deals, ["discovery", "demo", "proposal", "negotiation"]
)
return jsonify({
"overall": velocity,
"by_stage": by_stage,
"updated_at": datetime.now().isoformat(),
})
Step 4: Store Daily Snapshots
Save daily snapshots so you can show velocity trends over time.
import sqlite3
def save_daily_snapshot(velocity_data):
conn = sqlite3.connect("velocity.db")
conn.execute("""
INSERT INTO daily_velocity
(date, deal_count, avg_value, win_rate, cycle_days, velocity)
VALUES (?, ?, ?, ?, ?, ?)
""", (
datetime.now().date().isoformat(),
velocity_data["deal_count"],
velocity_data["avg_value"],
velocity_data["win_rate"],
velocity_data["avg_cycle_days"],
velocity_data["velocity"],
))
conn.commit()
Step 5: Set Up Velocity Alerts
When velocity drops below your 30-day average, send an alert immediately.
def check_velocity_alert(current, historical_avg):
if current["velocity"] < historical_avg * 0.8:
send_alert(
f"Pipeline velocity dropped to ${current['velocity']:,.0f}/day "
f"(benchmark: ${historical_avg:,.0f}/day)"
)
What to Build Next
Segment velocity by rep, territory, or product line. The overall number hides problems. The segmented view reveals them.
Related Reading
- AI for Sales Pipeline Management - ai sales pipeline management
- How to Automate Your Sales Pipeline Updates - automate sales pipeline updates
- Building a Reporting Dashboard from Scratch - reporting dashboard from scratch
Want this system built for your business?
Get a free assessment. We will map every system your business needs and show you the ROI.
Get Your Free Assessment