Skip to content

Field Sales Operations

Team Leaderboard + Live KPIs — Velocity X's Antidote to the Monday Sales Meeting

All articles
🏆 📈

Realtime scoreboard dashboards that motivate teams and kill the weekly meeting ritual

Monday morning. 9am. The entire sales team files into a conference room. Someone unmutes a Zoom call from the field. The manager reads last week's stats off a spreadsheet that was updated Friday at 5pm, which means it's already stale. Nothing gets decided because the data is yesterday's news. People scroll their phones. A rep's motivation dies a little bit. Everyone forgets the meeting happened by Wednesday.

There's a better way. Velocity X shows every rep their personal stats in realtime. It shows managers team rankings updated hourly. Everyone sees the same scoreboard. A rep can open the dashboard and see they're one deal away from hitting this week's target. A manager can see which team member is underperforming and needs a check-in—without a meeting. That's the antidote to the Monday sales meeting: a live leaderboard that tells the truth 24/7.

Why Live Beats Weekly Meetings

Weekly sales meetings feel mandatory but they solve almost nothing. The data's stale by the time you talk about it. Last week's loss is already forgotten by the time you discuss it. And the meeting itself is a tax on productivity—30 people × 1 hour = 30 hours of paid time to communicate information that could live on a dashboard.

A live leaderboard inverts the information flow. Instead of the manager pushing data at the team once a week, the data pulls attention from the team continuously. A rep checking the board sees their position, their streak, their target, their urgency—all without a meeting. A manager checks the board and spots the rep who's two jobs away from their quota, sends a quick Slack message with a referral or a lead, and moves on. No ceremony. No wasted time.

The psychology is different too. Weekly meetings are demoralizing because they anchor performance to the past. A leaderboard motivates because it's always live. If you missed a deal on Tuesday, you can still climb back up by Friday. The playing field resets in realtime, not once a week.

The Architecture: Supabase Channels + Hourly Rollups

Velocity X's leaderboard works like this: every job completion (a field rep closes a deal) is recorded in the jobs table. A Supabase realtime channel broadcasts that event. Connected dashboards subscribe to the channel and re-render. At the same time, an hourly cron job materialises a leaderboard_rollups table with aggregated stats for performance reporting.

{`create table jobs (
  id uuid primary key default gen_random_uuid(),
  org_id uuid references organizations(id),
  assigned_to uuid references auth.users(id),
  status text, -- 'assigned', 'in_progress', 'completed', 'failed'
  completed_at timestamp,
  claim_amount numeric,
  revenue numeric,
  created_at timestamp default now()
);

-- Realtime publication
create publication realtime_jobs for table jobs;

create table leaderboard_rollups (
  id uuid primary key default gen_random_uuid(),
  org_id uuid references organizations(id),
  rep_id uuid references auth.users(id),
  period text, -- 'this_week', 'this_month', etc
  jobs_completed int,
  deals_count int,
  total_revenue numeric,
  avg_claim_amount numeric,
  completion_rate numeric,
  streak_days int,
  rank int,
  updated_at timestamp default now()
);

create index on leaderboard_rollups(org_id, period, rank);
create index on leaderboard_rollups(rep_id, period);`}

On the client, a React dashboard subscribes to the realtime channel and listens for job updates:

{`import { useEffect, useState } from 'react';
import { supabase } from '@/lib/supabase';

export function RealtimeLeaderboard() {
  const [leaderboard, setLeaderboard] = useState([]);

  useEffect(() => {
    // Initial load
    const fetchLeaderboard = async () => {
      const { data } = await supabase
        .from('leaderboard_rollups')
        .select('*')
        .eq('period', 'this_week')
        .order('rank');
      setLeaderboard(data || []);
    };

    fetchLeaderboard();

    // Subscribe to realtime updates
    const subscription = supabase
      .channel('jobs:org_id=eq.' + orgId)
      .on(
        'postgres_changes',
        {
          event: 'UPDATE',
          schema: 'public',
          table: 'jobs',
          filter: 'status=eq.completed'
        },
        async (payload) => {
          // Job completed; refetch leaderboard
          const { data } = await supabase
            .from('leaderboard_rollups')
            .select('*')
            .eq('period', 'this_week')
            .order('rank');
          setLeaderboard(data || []);
        }
      )
      .subscribe();

    return () => {
      subscription.unsubscribe();
    };
  }, [orgId]);

  return (
    
{leaderboard.map((row, i) => (
{i + 1} {row.rep_name}
{row.deals_count} deals
\${row.total_revenue.toLocaleString()}
))}
); }`}

The hourly cron job (Netlify Edge Function or Supabase pg_cron) computes rollups and refreshes leaderboard_rollups:

{`// /api/update-leaderboards (cron: every hour)
import { createClient } from '@supabase/supabase-js';

const supabase = createClient(
  Deno.env.get('PUBLIC_SUPABASE_URL'),
  Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')
);

export default async (req: Request) => {
  const { org_id } = await req.json();

  // Fetch all reps' completed jobs this week
  const { data: jobs } = await supabase
    .from('jobs')
    .select('assigned_to, revenue, completed_at')
    .eq('org_id', org_id)
    .eq('status', 'completed')
    .gte('completed_at', getWeekStart());

  // Group by rep
  const stats = {};
  jobs.forEach(job => {
    if (!stats[job.assigned_to]) {
      stats[job.assigned_to] = { count: 0, revenue: 0 };
    }
    stats[job.assigned_to].count++;
    stats[job.assigned_to].revenue += job.revenue;
  });

  // Rank reps
  const ranked = Object.entries(stats)
    .sort(([, a], [, b]) => b.revenue - a.revenue)
    .map(([repId, s], idx) => ({
      org_id,
      rep_id: repId,
      period: 'this_week',
      deals_count: s.count,
      total_revenue: s.revenue,
      rank: idx + 1,
      updated_at: new Date()
    }));

  // Upsert into leaderboard_rollups
  await supabase.from('leaderboard_rollups').upsert(ranked);

  return new Response(JSON.stringify({ success: true }));
};`}

Two Views: Rep Dashboard and Manager Board

Rep Dashboard: A field rep opens Velocity X and immediately sees their personal stats. How many deals closed this week. Revenue generated. Completion rate. Position on the team leaderboard. Their streak (consecutive days with at least one completion). And critically: how many deals away they are from their target. A rep who's closed 8 deals and needs 12 to hit quota sees they need 4 more. That number is their north star for the day. No meeting required. No manager email. Just clarity.

Manager Board: A manager checks the team leaderboard and sees all reps ranked by revenue or deals closed. They can spot the top performer (should they be mentoring others?), the underperformer (do they need a lead, a pep talk, or a performance plan?), and the streaker (rep currently on a hot streak—reward it). Clicking a rep's row drills into their weekly detail: job history, conversion rate, average deal size, recent wins. A manager can diagnose "why is this rep slow?" in 30 seconds without asking them to come into an office.

Fair Scoring: Streaks, Recency, and Level Playing Fields

Leaderboards are demoralizing if they're rigged. If the same two people dominate week after week, everyone else stops trying. Velocity X addresses this with weighted scoring.

Streak weighting: A rep's current streak (consecutive days with at least one completion) is multiplied into their score. A rep with 4 deals this week scores differently if they closed them over 3 days versus 7 days. Closing 4 in 3 days means they're hot. Closing 4 in 7 days means they're coasting. Leaderboards should celebrate momentum, not just totals.

Recency weighting: Sales are weighted by day. A deal closed today counts more than a deal closed Monday. This keeps the board volatile and fresh. A rep who had a slow start can still climb back up this week because this week's not over.

Starting line fairness: If a new rep joins mid-week, they shouldn't be ranked against people who've been working for 5 days already. Leaderboards should only include reps who've been active for at least 3 days this period, or show two boards: "active reps" (3+ days) and "climbing" (new reps, ranked separately). Different periods require different rules. You'll discover what works for your team within the first month.

RLS: Rep Sees Only Themselves + Team, Manager Sees All

A field rep shouldn't see another rep's customer details or job assignments. But they absolutely should see the leaderboard (it motivates them). Supabase RLS enforces this:

{`-- Leaderboard is readable by all, but staff can only see their own detail
alter table leaderboard_rollups enable row level security;

create policy "staff_see_leaderboard"
  on leaderboard_rollups for select
  using (
    auth.jwt() ->> 'org_id' = org_id::text
    and auth.jwt() ->> 'role' = 'staff'
  );

-- But staff can only view their own detail (jobs, notes, customer info)
create policy "staff_see_own_jobs"
  on jobs for select
  using (
    auth.jwt() ->> 'org_id' = org_id::text
    and (
      assigned_to = auth.uid()
      or auth.jwt() ->> 'role' = 'admin'
    )
  );

-- Managers see all jobs and all leaderboards
create policy "manager_see_all"
  on jobs for select
  using (
    auth.jwt() ->> 'org_id' = org_id::text
    and auth.jwt() ->> 'role' in ('admin', 'manager')
  );`}

Avoiding Leaderboard Toxicity

Leaderboards can kill culture if you're not careful. A few rules: (1) celebrate the top performer publicly and weekly—a Slack shout-out, a small bonus, recognition that matters. (2) Never use leaderboards to fire or PIP someone. Use them to diagnose performance and offer support (more leads, territory adjustment, coaching). (3) Don't let leaderboards become the only metric. A rep with high volume but low quality is a problem. Leaderboards should show multiple columns: deals, revenue, quality score, customer satisfaction. (4) Reset regularly. Weekly leaderboards are great. Monthly is better for eliminating luck. Quarterly is best for spotting trends.

The goal isn't to humiliate underperformers. It's to make performance transparent so you can act on it. When a rep is slipping, you notice immediately and you can help instead of having a surprise during quarterly review.

Frequently Asked Questions

What if a rep doesn't want to be ranked?

Some teams prefer no leaderboard at all. That's fine. Use the same architecture to show personal dashboards (my stats vs. my quota) without ranking. The realtime channel and hourly rollups still work. You're just hiding the rank column.

Can I customize the metrics?

Yes. Some teams rank by deals closed. Some by revenue. Some by conversion rate. Some by customer satisfaction score. Define the metric in your rollup query and let managers choose what they want to see. The architecture supports multiple leaderboards—this_week_deals, this_week_revenue, this_month_satisfaction, etc.

How often should leaderboards reset?

Weekly is the standard. Monthly is better for eliminating luck and highlighting consistency. Quarterly is too slow to be motivating. Experiment with what your team responds to.

What if a rep completes a job but the data is wrong?

Managers should be able to adjust or void a job. When they do, the leaderboard recalculates. The hourly cron picks it up. No refresh needed—the realtime channel broadcasts the update and dashboards re-render.

Can I export the leaderboard history?

Yes. leaderboard_rollups is an audit trail. You can query it by period, by rep, by week, by team. Export it to CSV for exec reporting or store it in a data warehouse for long-term analysis. You've got a year of history within months. That history tells you which reps are consistently strong, which are improving, which are on their way out.

What if reps are competing so hard they stop helping each other?

This is cultural, not technical. Leaderboards can create tension. Mitigate it by: (1) celebrating team wins alongside individual wins, (2) rotating the top performer's role to mentor struggling teammates, (3) pairing new reps with veterans (they earn points together sometimes), (4) showing team-based leaderboards alongside individual ones. You control the incentives; the leaderboard just makes performance visible.

The Verdict

Monday sales meetings are theater. They feel productive but they're usually a waste of time. Live leaderboards solve the actual problem: making performance visible and actionable in realtime. A rep checking the board sees exactly where they stand. A manager checking the board sees exactly who needs help. No meeting required. No stale data. No wasted time. Just clarity, motivation, and the ability to act immediately when someone's struggling. That's how modern sales ops works. Velocity X does it. Your team should too. And if you're ready to ship this on your own platform, pricing shows how to build it on our stack.

For more on realtime architecture, see our guide to role-gated dashboards. And if your sales team is drowning in meetings, let's talk about how to replace them with data.

Let us make some quick suggestions?
Please provide your full name.
Please provide your phone number.
Please provide a valid phone number.
Please provide your email address.
Please provide a valid email address.
Please provide your brand name or website.
Please provide your brand name or website.