What goes in an event performance dashboard?
An event dashboard connects the number everyone quotes — registrations — to the number that matters: who actually showed up. That link only exists if you capture check-in data as well as sign-ups; without it, attendance and no-show rates are guesses dressed as metrics.
Which cards belong on this dashboard?
- Registrations per event and per month
- RSVP-to-attendance conversion by event
- No-show rate, with the check-in method stated
- Attendance by event type (webinar, meetup, workshop, conference)
- Ticket revenue and revenue per attendee for paid events
- Repeat attendees: share who attended a prior event
- Registration pacing: sign-ups by days before the event
- Cancellations and waitlist conversions
What data does this dashboard need?
- Event records with event ID, type, start time, capacity, and paid or free
- Registration records with registration time and RSVP status
- Check-in or attendance records — attendance is unknowable without them
- Ticket amounts, discounts, and refunds for paid events
- A member or contact key that survives across events, for repeat attendance
How do you build it?
- Land forum, community-platform, and event data in a database and keep member IDs, post timestamps, event IDs, and RSVP status.
- Build models at the grain this dashboard needs, with the active-member window and the check-in rule as explicit columns.
- Create one saved question per card and certify the shared models and definitions.
- Add dashboard filters for Date range, event type, region, paid vs. free, registration source.
- Show data freshness and the definitions in use — community exports run on a schedule, and every viewer should know what "active" means here.
Example card SQL
SELECT
e.event_id,
e.name,
e.event_type,
e.starts_at::date AS event_date,
COUNT(*) FILTER (WHERE r.status <> 'cancelled') AS registrations,
COUNT(*) FILTER (WHERE r.checked_in_at IS NOT NULL) AS attendees,
ROUND(
100.0 * COUNT(*) FILTER (WHERE r.checked_in_at IS NOT NULL)
/ NULLIF(COUNT(*) FILTER (WHERE r.status <> 'cancelled'), 0), 1
) AS attendance_pct,
ROUND(
100.0 * COUNT(*) FILTER (
WHERE r.status <> 'cancelled' AND r.checked_in_at IS NULL
)
/ NULLIF(COUNT(*) FILTER (WHERE r.status <> 'cancelled'), 0), 1
) AS no_show_pct,
ROUND(COALESCE(SUM(r.ticket_amount_usd), 0), 2) AS ticket_revenue
FROM community_events e
JOIN event_registrations r ON r.event_id = e.event_id
WHERE e.starts_at < CURRENT_TIMESTAMP
AND e.starts_at >= CURRENT_DATE - INTERVAL '12 months'
GROUP BY e.event_id, e.name, e.event_type, e.starts_at
ORDER BY event_date DESC;