What goes in a SOC dashboard in Metabase?
A SOC dashboard tracks the security operations center as an operation: alert volume by severity and source, triage speed (MTTA and MTTR), false-positive rate, escalations to incidents, and analyst workload. It's the management layer over the SIEM console — the console is where analysts triage; this is where the SOC lead sees whether triage is keeping up. Metabase builds it from SIEM, EDR, and case-management exports, alongside alert quality and incident response trends.
For: SOC leads, security managers, and detection engineers. Grain: one row per alert, with acknowledge/resolve timestamps. Refresh: hourly for the queue cards; the trends are weekly reads.
What does a SOC dashboard look like?
Here’s the layout this guide builds. The shift-handover row leads — volume, escalations, acknowledge time, false-positive rate, and the open queue — so an incoming shift reads one line; alert flow and triage follow, tracing alerts from source through the funnel to incidents; quality, workload, and coverage close the page, because those are the levers the SOC lead pulls week to week rather than shift to shift.

Which cards belong on a SOC dashboard?
The eight below cover throughput, speed, quality, and capacity — the four things that decide whether a SOC is coping or silently backing up.
- Alerts by severity per week — volume and mix over the last eight weeks (stacked bar)
- Alerts by source — EDR, email gateway, identity, cloud logs, WAF (row)
- From alert to incident — received, triaged, investigated, escalated (funnel)
- Time to acknowledge and resolve — median MTTA and MTTR per week (combo)
- False-positive rate per week — against the team’s target (line)
- Alerts closed per analyst — workload balance across the team (row)
- Detection coverage by ATT&CK tactic — % of techniques with an active rule (row)
- Escalated incidents — the last 7 days, with source, severity, and assignee (table)
What data does the dashboard need?
- An
alertstable —alert_id,source,severity,rule_id,created_at,acknowledged_at,resolved_at,disposition,assignee. - An
escalated_incident_idcolumn (or anincidentstable keyed to alerts) so escalations can be counted and joined. - A
detection_rulestable with rule status and mapped ATT&CK techniques, for the coverage card. - Analyst shift or roster data if you want workload normalized per shift rather than raw counts.
- Paging records (e.g., PagerDuty) if off-hours load and paging noise should appear alongside — see the alert quality dashboard for that cut.
How do you build it?
- Schedule exports from the SIEM/SOAR into your warehouse — hourly for the alerts table, daily for rules — keyed on
alert_idso re-syncs upsert cleanly. - Enforce dispositions at closure in the source tool; the false-positive card is only as good as the discipline behind that field.
- Model triage durations once (created → acknowledged → resolved, as minutes), using medians in every card so one weekend alert can’t skew a week.
- Build the funnel from alert states and the coverage card from the rule-to-technique mapping; both are ordinary grouped queries, not special tooling.
- Add filters for severity, alert source, and date range; pin the queue and handover cards to the top and subscribe the SOC channel to a start-of-shift snapshot.
Example card SQL
SELECT
date_trunc('week', a.created_at) AS week,
COUNT(*) AS alerts,
COUNT(*) FILTER (WHERE a.severity = 'critical') AS critical,
PERCENTILE_CONT(0.5) WITHIN GROUP (
ORDER BY EXTRACT(epoch FROM a.acknowledged_at - a.created_at) / 60
) AS mtta_minutes,
PERCENTILE_CONT(0.5) WITHIN GROUP (
ORDER BY EXTRACT(epoch FROM a.resolved_at - a.created_at) / 3600
) FILTER (WHERE a.resolved_at IS NOT NULL) AS mttr_hours,
ROUND(
100.0 * COUNT(*) FILTER (WHERE a.disposition = 'false_positive')
/ NULLIF(COUNT(*) FILTER (WHERE a.disposition IS NOT NULL), 0), 1
) AS false_positive_pct,
COUNT(*) FILTER (WHERE a.escalated_incident_id IS NOT NULL)
AS escalated_to_incident
FROM alerts a
WHERE a.created_at >= now() - interval '8 weeks'
GROUP BY 1
ORDER BY 1;