← Back to Cookbook

Build a dashboard and alert from custom metrics in a Next.js app

Turn a single custom metric into something your team actually watches: a dashboard widget and an alert that fires the moment things drift.

Features
SDKs
Category Monitoring
Time
20-25 minutes
Difficulty
Intermediate
Steps
6 steps

Before you start

SDKs & packages
  • A Next.js app (v13+ with App Router recommended)
  • @sentry/nextjs version 10.25.0 or later (metrics are on by default from this version)
Accounts & access
  • Sentry account with a Next.js project created
  • A Trial, Business, or Enterprise plan if you want to use anomaly-detection alerts (open beta)
Knowledge
  • Basic familiarity with Next.js Route Handlers or Server Actions
  • A rough sense of when to reach for a counter, a gauge, or a distribution

1
Install the Sentry Next.js SDK

Add the Sentry SDK to your project with the wizard, which wires up the instrumentation files automatically. Run this in your project root. Metrics are on by default in @sentry/nextjs 10.25.0 and later, so there's nothing extra to enable. If you ever need to turn them off, set enableMetrics: false in your Sentry.init config.

Next.js SDK setup guide
Bash
npx @sentry/wizard@latest -i nextjs

2
Emit a custom metric from your app

Pick a signal that maps to something your team cares about, then emit it from the exact code path where it happens. Use Sentry.metrics.count() for events you tally and Sentry.metrics.distribution() for values you'll want percentiles on later.

The example below is from a Next.js conference-scheduler app: every time a user adds or removes a talk, it counts a schedule.event and attaches action and result attributes so you can slice by outcome. Both logs and metrics are high-cardinality wide events, so adding more attributes costs nothing and gives you more ways to query, group, and alert later. For values where you want a p95, emit a distribution instead, for example Sentry.metrics.distribution("ai.tokens.total", totalTokens).

Next.js metrics setup
TypeScript
import * as Sentry from '@sentry/nextjs';

export async function addTalkToSchedule(userId: string, talkId: string) {
  const existing = await getScheduleEntry(userId, talkId);

  if (existing.length > 0) {
    Sentry.metrics.count('schedule.event', 1, {
      attributes: { action: 'add', result: 'duplicate' },
    });
    return;
  }

  await db.insert(userSchedules).values({ userId, talkId });
  revalidatePath('/');

  Sentry.metrics.count('schedule.event', 1, {
    attributes: { action: 'add', result: 'success' },
  });
}

3
Explore your metric in the Metrics explorer

Trigger the code path a few times, then open the Metrics explorer. Select schedule.event, choose an aggregation like sum or per_minute, and group by the result attribute to see successes, duplicates, and failures split out.

Open the Samples tab to see individual metric events, each with a direct link to its trace, so a suspicious number is one click away from the request behind it.

Application Metrics documentation
Sentry Metrics explorer showing the schedule.event counter with sum aggregation grouped by action, bar chart with remove success, add success, and add duplicate segments, and an Aggregates table breaking down each combination

4
Build a dashboard around your metric

Once the query in the explorer shows what you want, open the Save As menu and pin it as a dashboard widget. Head to Dashboards to add it to a new or existing dashboard, then drop in a second widget for another signal (like ai.tokens.total at p95, or page.view throughput) so related metrics sit side by side.

A good starter layout: schedule events over time grouped by result, plus a throughput or latency widget next to it.

Dashboards documentation
Sentry Product Dashboard with six widgets: All Log Messages table, Server Action Performance with count and p95 duration, Pageload Duration by Route chart, DB Query Performance table, Cache Misses Over Time chart, and AI Chat Usage chart with release markers

5
Add a threshold alert

From the metric query, use the Save As menu to turn it into a Monitor (or head to Alerts and create one). Pick Threshold as the detection method and set a number you understand: for a free AI assistant, that might be ai.tokens.total summed above a cost ceiling per hour; for the scheduler, schedule.event where result is not success above N per hour. Route the notification to Slack, PagerDuty, or email so the right people hear about it.

Static thresholds are the right call when you already know the number that means trouble, like a spend cap or an SLO you've committed to.

Alerts documentation
Sentry Metric Monitor detail page showing a count tags message_count number query with static threshold, a chart with High above 10 and Medium above 5 severity lines, an ongoing resolved issue assigned to a team member, and a connected Slack alert

6
Switch to anomaly detection when you don't have a baseline

When you don't yet know what "normal" looks like, a static threshold either fires all night or sleeps through daytime spikes. Create a second alert and pick Anomaly as the detection method instead. Sentry learns your metric's seasonality and daily or weekly patterns, then flags deviations with no threshold to tune, just a sensitivity slider. Throughput metrics like page.view are a perfect fit, since traffic naturally rises and falls through the day.

Reach for anomaly detection on new metrics or anything with a strong daily rhythm, and keep static thresholds for hard limits you've explicitly agreed to.

Alerts documentation
Sentry alert Issue Detection section with Dynamic detection selected for auto-detecting anomalies, responsiveness set to Medium, direction set to Above and Below, and Issue Ownership assigning a team member

That's it.

Your telemetry finally tells you something.

One custom metric becomes a dashboard you watch and an alert that pages you, all trace-connected so you can jump straight from a spike to the request that caused it.

  • Emitted a custom counter metric from a Next.js Server Action with business-context attributes
  • Explored metric values, aggregations, and trace-connected samples in the Metrics explorer
  • Built a dashboard widget from a saved metric query
  • Created a static threshold alert routed to your team's channels
  • Compared static thresholds with anomaly detection so you know which to reach for

Pro tips

  • 💡 Name metrics with a consistent, dotted convention like schedule.event and ai.tokens.total so they're easy to find, group, and reason about across the team.
  • 💡 Push business context into attributes (action, result, plan tier) rather than baking it into the metric name. Attributes are free on high-cardinality events and give you more ways to slice, group, and alert.
  • 💡 Use a distribution, not a gauge, whenever you care about p95 or p99. Gauges only keep the latest snapshot, so percentiles need distributions.
  • 💡 Start with a static threshold you understand, then add an anomaly alert once you have a couple of weeks of baseline data for Sentry to learn from.

Common pitfalls

  • ⚠️ Baking dimensions into the metric name (schedule.event.success, schedule.event.duplicate) instead of using one metric with a result attribute. This explodes cardinality and makes grouping impossible.
  • ⚠️ Expecting percentiles from a counter or gauge. Only distributions compute p50, p95, and p99; counters aggregate by sum or rate, and gauges keep the last value.
  • ⚠️ Putting a static threshold on a metric with strong daily or weekly seasonality like page views. It will page you every night or miss real daytime spikes. Use anomaly detection there instead.
  • ⚠️ Running an SDK older than 10.25.0. Earlier versions silently ignore Sentry.metrics calls, so your metric never shows up.

Frequently asked questions

No. Metrics are on by default in @sentry/nextjs version 10.25.0 and later. If you want to turn them off, set enableMetrics: false in your Sentry.init config.

Use a counter for things you tally, like schedule events or requests. Use a gauge for a point-in-time value that goes up and down, like queue depth. Use a distribution for values you want percentiles on, like token usage or request latency.

Use a static threshold when you already know the number that means trouble, like a spend cap or an SLO. Use anomaly detection when you don't have a baseline yet or the metric has strong daily or weekly seasonality. Sentry learns the pattern and flags deviations without a fixed threshold.

Metrics are billed by volume, and Sentry's free tier includes enough to get started. Anomaly-detection alerts are in open beta for Trial, Business, and Enterprise plans.

Yes. Both threshold and anomaly alerts can route notifications to Slack, PagerDuty, or email, so they reach your team through the channels you already use.

Fix it, don't observe it.

Get started with the only application monitoring platform that empowers developers to fix application problems without compromising on velocity.