Set Up Metrics

Metrics allow you to send, view and query counters, gauges and measurements from your Sentry-configured apps to track application health and drill down into related traces, logs, and errors.

Sentry Agent Skills

Install Sentry's agent skills to teach your AI coding assistant how to set up metrics in your application.

Copied
npx @sentry/dotagents add getsentry/sentry-agent-skills --name sentry-setup-metrics

See the full list of available skills and installation docs for more details.

With Sentry Metrics, you can send counters, gauges, and distributions from your applications to Sentry. Once in Sentry, these metrics can be viewed alongside relevant errors, and searched using their individual attributes.

Metrics are supported in all Sentry JavaScript SDKs version 10.25.0 and above.

Make sure you have the SDK set up before proceeding.

TypeUse For
countEvents (orders, clicks, API calls)
gaugeCurrent values (queue depth, connections)
distributionValue ranges (response times, payload sizes)

No setup required beyond SDK initialization.

Copied
import * as Sentry from "@sentry/browser";

// Count occurrences
Sentry.metrics.count("orders_created", 1);

// Track current values
Sentry.metrics.gauge("active_connections", 42);

// Track distributions
Sentry.metrics.distribution("api_latency", 187, {
  unit: "millisecond",
});

Attributes let you filter and group metrics in Sentry. Use them for:

  • Environment segmentation
  • Feature flag tracking
  • User tier analysis

Each metric has a 2KB size limit. If you exceed this, the metric will be dropped.

Copied
Sentry.metrics.count("api_calls", 1, {
  attributes: {
    endpoint: "/api/orders",
    user_tier: "pro",
    region: "us-west",
    user_id: user.id,
    order_id: order.id,
  },
});

With version 10.33.0+, use scope APIs to set attributes that apply to all metrics while the scope is active.

Supported types: string, number, boolean

Copied
Sentry.getGlobalScope().setAttributes({
  is_admin: true,
  auth_provider: "google",
});

Sentry.withScope((scope) => {
  scope.setAttribute("step", "authentication");

  // All scope attributes are added
  Sentry.metrics.count("clicks", 1);
  Sentry.metrics.gauge("time_since_refresh", 4, { unit: "hour" });
});

For gauge and distribution metrics, specify a unit to help Sentry display values in a human-readable format.

Common units: millisecond, second, byte, kilobyte, megabyte. See supported units for the full list.

Copied
Sentry.metrics.distribution("response_time", 187.5, {
  unit: "millisecond",
});

Sentry.metrics.gauge("memory_usage", 1024, {
  unit: "byte",
});

Track request timing and business events in your route handlers.

app/api/orders/route.ts
Copied
import * as Sentry from "@sentry/nextjs";

export async function POST(request: Request) {
  const start = Date.now();

  try {
    const order = await createOrder(request);

    Sentry.metrics.count("orders_created", 1, {
      attributes: { status: "success" },
    });

    return Response.json(order);
  } catch (error) {
    Sentry.metrics.count("orders_created", 1, {
      attributes: { status: "failed" },
    });
    throw error;
  } finally {
    Sentry.metrics.distribution("order_latency", Date.now() - start, {
      unit: "millisecond",
    });
  }
}

Track form submissions and mutations.

app/actions.ts
Copied
"use server";

import * as Sentry from "@sentry/nextjs";

export async function submitCheckout(formData: FormData) {
  Sentry.metrics.count("checkout_attempts", 1);

  try {
    const result = await processCheckout(formData);
    Sentry.metrics.count("checkout_success", 1);
    return result;
  } catch (error) {
    Sentry.metrics.count("checkout_failures", 1);
    throw error;
  }
}

Track request patterns at the edge.

Next.js 16+ uses proxy.ts, while earlier versions use middleware.ts. The pattern is the same.

proxy.ts
Copied
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
import * as Sentry from "@sentry/nextjs";

export function proxy(request: NextRequest) {
  Sentry.metrics.count("requests", 1, {
    attributes: {
      path: request.nextUrl.pathname,
      method: request.method,
    },
  });

  return NextResponse.next();
}

Filter or modify metrics before sending. Return null to drop a metric.

Copied
Sentry.init({
  dsn: "___PUBLIC_DSN___",
  beforeSendMetric: (metric) => {
    // Drop specific metrics
    if (metric.name === "debug_metric") {
      return null;
    }

    // Add attributes
    metric.attributes = {
      ...metric.attributes,
      processed: true,
    };

    return metric;
  },
});

Set enableMetrics: false to disable metrics collection entirely.

Metrics are buffered and sent periodically. Use this snippet to flush immediately:

Copied
// Disable metrics
Sentry.init({
  dsn: "___PUBLIC_DSN___",
  enableMetrics: false,
});

// Flush all pending metrics
await Sentry.flush();

Sentry automatically attaches these attributes to every metric:

AttributeDescriptionContext
sentry.environmentEnvironment from SDK configAlways
sentry.releaseRelease version from SDK configAlways
sentry.sdk.nameSDK nameAlways
sentry.sdk.versionSDK versionAlways
user.id, user.name, user.emailUser identifiersIf user set
browser.name, browser.versionBrowser infoClient-side
sentry.replay_idSession replay IDClient-side
server.addressServer hostnameServer-side
  • Tracing — Drill down from metrics into related traces to understand performance patterns.
  • Logs — Combine metrics with logs for full observability into your application's behavior.

  • Error Monitoring — Use metrics alongside error tracking to understand the impact of issues.
Was this helpful?
Help improve this content
Our documentation is open source and available on GitHub. Your contributions are welcome, whether fixing a typo (drat!) or suggesting an update ("yeah, this would be better").