| title | What to Track |
|---|---|
| sidebar_order | 15 |
| description | Practical guidance on what metrics to track, how to explore them, and when to set alerts. |
You've set up Sentry Metrics. Now what?
This guide covers the high-value metric patterns that give you visibility into application health and how to drill into traces when something looks off.
Sentry supports three metric types:
| Type | Method | Use For |
|---|---|---|
| Counter | Sentry.metrics.count() |
Events that happen (orders, clicks, errors) |
| Gauge | Sentry.metrics.gauge() |
Current state (queue depth, connections) |
| Distribution | Sentry.metrics.distribution() |
Values that vary (latency, sizes, amounts) |
Every metric is trace-connected. When a metric spikes, click into samples to see the exact trace that produced it.
Sentry.metrics.count("checkout.failed", 1, {
attributes: {
user_tier: "premium",
failure_reason: "payment_declined",
},
});import sentry_sdk
sentry_sdk.metrics.count("checkout.failed", 1, attributes={
"user_tier": "premium",
"failure_reason": "payment_declined"
})\Sentry\traceMetrics()->count('checkout.failed', 1, [
'user_tier' => 'premium',
'failure_reason' => 'payment_declined',
]);SentrySdk.Metrics.Counter("checkout.failed")
.Tag("user_tier", "premium")
.Tag("failure_reason", "payment_declined")
.Increment();Sentry.metrics.count('checkout.failed', 1,
tags: { user_tier: 'premium', failure_reason: 'payment_declined' }
)Sentry.metrics.count('checkout.failed', 1, attributes: {
'user_tier': 'premium',
'failure_reason': 'payment_declined',
});import Sentry
SentrySDK.metrics.count(key: "checkout.failed", value: 1, attributes: [
"user_tier": "premium",
"failure_reason": "payment_declined"
])import io.sentry.Sentry
Sentry.metrics().count("checkout.failed", 1.0)Start with these five metrics and you'll spot issues before they become problems.
Track discrete events that matter to the business. These become your KPIs.
Sentry.metrics.count("checkout.completed", 1, {
attributes: { user_tier: "premium", payment_method: "card" },
});
Sentry.metrics.count("checkout.failed", 1, {
attributes: { user_tier: "premium", failure_reason: "payment_declined" },
});import sentry_sdk
sentry_sdk.metrics.count("checkout.completed", 1, attributes={
"user_tier": "premium", "payment_method": "card"
})
sentry_sdk.metrics.count("checkout.failed", 1, attributes={
"user_tier": "premium", "failure_reason": "payment_declined"
})\Sentry\traceMetrics()->count('checkout.completed', 1, [
'user_tier' => 'premium', 'payment_method' => 'card'
]);
\Sentry\traceMetrics()->count('checkout.failed', 1, [
'user_tier' => 'premium', 'failure_reason' => 'payment_declined'
]);SentrySdk.Metrics.Counter("checkout.completed")
.Tag("user_tier", "premium")
.Tag("payment_method", "card")
.Increment();
SentrySdk.Metrics.Counter("checkout.failed")
.Tag("user_tier", "premium")
.Tag("failure_reason", "payment_declined")
.Increment();Sentry.metrics.count('checkout.completed', 1,
tags: { user_tier: 'premium', payment_method: 'card' }
)
Sentry.metrics.count('checkout.failed', 1,
tags: { user_tier: 'premium', failure_reason: 'payment_declined' }
)Sentry.metrics.count('checkout.completed', 1, attributes: {
'user_tier': 'premium',
'payment_method': 'card',
});
Sentry.metrics.count('checkout.failed', 1, attributes: {
'user_tier': 'premium',
'failure_reason': 'payment_declined',
});import Sentry
SentrySDK.metrics.count(key: "checkout.completed", value: 1, attributes: [
"user_tier": "premium", "payment_method": "card"
])
SentrySDK.metrics.count(key: "checkout.failed", value: 1, attributes: [
"user_tier": "premium", "failure_reason": "payment_declined"
])import io.sentry.Sentry
Sentry.metrics().count("checkout.completed", 1.0)
Sentry.metrics().count("checkout.failed", 1.0)Explore in Sentry:
- Go to Explore > Metrics
- Select
checkout.failed, set Aggregate tosum - Group by
failure_reason - Click Samples to see individual events and their traces
Track success and failure of critical operations.
Sentry.metrics.count("email.sent", 1, {
attributes: { email_type: "welcome", provider: "sendgrid" },
});
Sentry.metrics.count("email.failed", 1, {
attributes: { email_type: "welcome", error: "rate_limited" },
});
Sentry.metrics.count("job.processed", 1, {
attributes: { job_type: "invoice-generation", queue: "billing" },
});import sentry_sdk
sentry_sdk.metrics.count("email.sent", 1, attributes={
"email_type": "welcome", "provider": "sendgrid"
})
sentry_sdk.metrics.count("email.failed", 1, attributes={
"email_type": "welcome", "error": "rate_limited"
})
sentry_sdk.metrics.count("job.processed", 1, attributes={
"job_type": "invoice-generation", "queue": "billing"
})\Sentry\traceMetrics()->count('email.sent', 1, [
'email_type' => 'welcome', 'provider' => 'sendgrid'
]);
\Sentry\traceMetrics()->count('email.failed', 1, [
'email_type' => 'welcome', 'error' => 'rate_limited'
]);
\Sentry\traceMetrics()->count('job.processed', 1, [
'job_type' => 'invoice-generation', 'queue' => 'billing'
]);SentrySdk.Metrics.Counter("email.sent")
.Tag("email_type", "welcome")
.Tag("provider", "sendgrid")
.Increment();
SentrySdk.Metrics.Counter("email.failed")
.Tag("email_type", "welcome")
.Tag("error", "rate_limited")
.Increment();
SentrySdk.Metrics.Counter("job.processed")
.Tag("job_type", "invoice-generation")
.Tag("queue", "billing")
.Increment();Sentry.metrics.count('email.sent', 1,
tags: { email_type: 'welcome', provider: 'sendgrid' }
)
Sentry.metrics.count('email.failed', 1,
tags: { email_type: 'welcome', error: 'rate_limited' }
)
Sentry.metrics.count('job.processed', 1,
tags: { job_type: 'invoice-generation', queue: 'billing' }
)Sentry.metrics.count('email.sent', 1, attributes: {
'email_type': 'welcome',
'provider': 'sendgrid',
});
Sentry.metrics.count('email.failed', 1, attributes: {
'email_type': 'welcome',
'error': 'rate_limited',
});
Sentry.metrics.count('job.processed', 1, attributes: {
'job_type': 'invoice-generation',
'queue': 'billing',
});import Sentry
SentrySDK.metrics.count(key: "email.sent", value: 1, attributes: [
"email_type": "welcome", "provider": "sendgrid"
])
SentrySDK.metrics.count(key: "email.failed", value: 1, attributes: [
"email_type": "welcome", "error": "rate_limited"
])
SentrySDK.metrics.count(key: "job.processed", value: 1, attributes: [
"job_type": "invoice-generation", "queue": "billing"
])import io.sentry.Sentry
Sentry.metrics().count("email.sent", 1.0)
Sentry.metrics().count("email.failed", 1.0)
Sentry.metrics().count("job.processed", 1.0)Query in Explore > Metrics: Add both email.sent and email.failed, group by email_type, compare the ratio.
Track the current state of pools, queues, and connections. Call these periodically (e.g., every 30 seconds).
Sentry.metrics.gauge("queue.depth", await queue.size(), {
attributes: { queue_name: "notifications" },
});
Sentry.metrics.gauge("pool.connections_active", pool.activeConnections, {
attributes: { pool_name: "postgres-primary" },
});import sentry_sdk
sentry_sdk.metrics.gauge("queue.depth", queue.size(), attributes={
"queue_name": "notifications"
})
sentry_sdk.metrics.gauge("pool.connections_active", pool.active_connections, attributes={
"pool_name": "postgres-primary"
})use \Sentry\Metrics\Unit;
\Sentry\traceMetrics()->gauge('queue.depth', $queue->size(), [
'queue_name' => 'notifications'
]);
\Sentry\traceMetrics()->gauge('pool.connections_active', $pool->activeConnections, [
'pool_name' => 'postgres-primary'
]);SentrySdk.Metrics.Gauge("queue.depth")
.Tag("queue_name", "notifications")
.Set(queue.Size);
SentrySdk.Metrics.Gauge("pool.connections_active")
.Tag("pool_name", "postgres-primary")
.Set(pool.ActiveConnections);Sentry.metrics.gauge('queue.depth', queue.size,
tags: { queue_name: 'notifications' }
)
Sentry.metrics.gauge('pool.connections_active', pool.active_connections,
tags: { pool_name: 'postgres-primary' }
)Sentry.metrics.gauge('queue.depth', queue.size.toDouble(), attributes: {
'queue_name': 'notifications',
});
Sentry.metrics.gauge('pool.connections_active', pool.activeConnections.toDouble(), attributes: {
'pool_name': 'postgres-primary',
});import Sentry
SentrySDK.metrics.gauge(key: "queue.depth", value: Double(queue.size), attributes: [
"queue_name": "notifications"
])
SentrySDK.metrics.gauge(key: "pool.connections_active", value: Double(pool.activeConnections), attributes: [
"pool_name": "postgres-primary"
])import io.sentry.Sentry
Sentry.metrics().gauge("queue.depth", queue.size.toDouble())
Sentry.metrics().gauge("pool.connections_active", pool.activeConnections.toDouble())Query in Explore > Metrics: View max(queue.depth) over time to spot backlogs.
Track values that vary and need percentile analysis. Tip: averages can hide outliers, use p90/p95/p99 instead.
Sentry.metrics.distribution("api.latency", responseTimeMs, {
unit: "millisecond",
attributes: { endpoint: "/api/orders", method: "POST" },
});
Sentry.metrics.distribution("db.query_time", queryDurationMs, {
unit: "millisecond",
attributes: { table: "orders", operation: "select" },
});import sentry_sdk
sentry_sdk.metrics.distribution("api.latency", response_time_ms,
unit="millisecond",
attributes={"endpoint": "/api/orders", "method": "POST"}
)
sentry_sdk.metrics.distribution("db.query_time", query_duration_ms,
unit="millisecond",
attributes={"table": "orders", "operation": "select"}
)use \Sentry\Metrics\Unit;
\Sentry\traceMetrics()->distribution('api.latency', $responseTimeMs,
['endpoint' => '/api/orders', 'method' => 'POST'],
Unit::millisecond()
);
\Sentry\traceMetrics()->distribution('db.query_time', $queryDurationMs,
['table' => 'orders', 'operation' => 'select'],
Unit::millisecond()
);SentrySdk.Metrics.Distribution("api.latency", responseTimeMs,
unit: MeasurementUnit.Duration.Millisecond)
.Tag("endpoint", "/api/orders")
.Tag("method", "POST");
SentrySdk.Metrics.Distribution("db.query_time", queryDurationMs,
unit: MeasurementUnit.Duration.Millisecond)
.Tag("table", "orders")
.Tag("operation", "select");Sentry.metrics.distribution('api.latency', response_time_ms,
unit: 'millisecond',
tags: { endpoint: '/api/orders', method: 'POST' }
)
Sentry.metrics.distribution('db.query_time', query_duration_ms,
unit: 'millisecond',
tags: { table: 'orders', operation: 'select' }
)Sentry.metrics.distribution('api.latency', responseTimeMs,
unit: SentryMeasurementUnit.duration(SentryDurationUnit.milliSecond),
attributes: {'endpoint': '/api/orders', 'method': 'POST'},
);
Sentry.metrics.distribution('db.query_time', queryDurationMs,
unit: SentryMeasurementUnit.duration(SentryDurationUnit.milliSecond),
attributes: {'table': 'orders', 'operation': 'select'},
);import Sentry
SentrySDK.metrics.distribution(key: "api.latency", value: responseTimeMs,
unit: .millisecond,
attributes: ["endpoint": "/api/orders", "method": "POST"]
)
SentrySDK.metrics.distribution(key: "db.query_time", value: queryDurationMs,
unit: .millisecond,
attributes: ["table": "orders", "operation": "select"]
)import io.sentry.Sentry
import io.sentry.metrics.MetricsUnit
Sentry.metrics().distribution("api.latency", responseTimeMs,
MetricsUnit.Duration.MILLISECOND)
Sentry.metrics().distribution("db.query_time", queryDurationMs,
MetricsUnit.Duration.MILLISECOND)Query in Explore > Metrics: View p95(api.latency) grouped by endpoint to find slow routes.
Track amounts, sizes, and quantities for analysis.
Sentry.metrics.distribution("order.amount", order.totalUsd, {
unit: "usd",
attributes: { user_tier: "premium", region: "us-west" },
});
Sentry.metrics.distribution("upload.size", fileSizeBytes, {
unit: "byte",
attributes: { file_type: "image", source: "profile-update" },
});import sentry_sdk
sentry_sdk.metrics.distribution("order.amount", order.total_usd,
unit="usd",
attributes={"user_tier": "premium", "region": "us-west"}
)
sentry_sdk.metrics.distribution("upload.size", file_size_bytes,
unit="byte",
attributes={"file_type": "image", "source": "profile-update"}
)use \Sentry\Metrics\Unit;
\Sentry\traceMetrics()->distribution('order.amount', $order->totalUsd,
['user_tier' => 'premium', 'region' => 'us-west'],
Unit::custom('usd')
);
\Sentry\traceMetrics()->distribution('upload.size', $fileSizeBytes,
['file_type' => 'image', 'source' => 'profile-update'],
Unit::byte()
);SentrySdk.Metrics.Distribution("order.amount", order.TotalUsd,
unit: MeasurementUnit.Custom("usd"))
.Tag("user_tier", "premium")
.Tag("region", "us-west");
SentrySdk.Metrics.Distribution("upload.size", fileSizeBytes,
unit: MeasurementUnit.Information.Byte)
.Tag("file_type", "image")
.Tag("source", "profile-update");Sentry.metrics.distribution('order.amount', order.total_usd,
unit: 'usd',
tags: { user_tier: 'premium', region: 'us-west' }
)
Sentry.metrics.distribution('upload.size', file_size_bytes,
unit: 'byte',
tags: { file_type: 'image', source: 'profile-update' }
)Sentry.metrics.distribution('order.amount', order.totalUsd,
unit: SentryMeasurementUnit.custom('usd'),
attributes: {'user_tier': 'premium', 'region': 'us-west'},
);
Sentry.metrics.distribution('upload.size', fileSizeBytes.toDouble(),
unit: SentryMeasurementUnit.information(SentryInformationUnit.byte),
attributes: {'file_type': 'image', 'source': 'profile-update'},
);import Sentry
SentrySDK.metrics.distribution(key: "order.amount", value: order.totalUsd,
unit: .generic("usd"),
attributes: ["user_tier": "premium", "region": "us-west"]
)
SentrySDK.metrics.distribution(key: "upload.size", value: Double(fileSizeBytes),
unit: .byte,
attributes: ["file_type": "image", "source": "profile-update"]
)import io.sentry.Sentry
import io.sentry.metrics.MetricsUnit
Sentry.metrics().distribution("order.amount", order.totalUsd)
Sentry.metrics().distribution("upload.size", fileSizeBytes.toDouble(),
MetricsUnit.Information.BYTE)Query in Explore > Metrics: View avg(order.amount) grouped by region to compare regional performance.
You'll soon be able to:
- Create alert rules based on metric queries
- Add metric visualizations to dashboards
- Set up notifications when metrics cross thresholds
- Save common queries for quick access
| Category | Type | Method | Example Attributes |
|---|---|---|---|
| Business events | Counter | count() |
user_tier, payment_method, failure_reason |
| Application health | Counter | count() |
email_type, provider, job_type, queue |
| Resource utilization | Gauge | gauge() |
queue_name, pool_name |
| Latency/performance | Distribution | distribution() |
endpoint, method, table, operation |
| Business values | Distribution | distribution() |
user_tier, region, file_type |
| Signal | Best For | Example Question |
|---|---|---|
| Metrics | Aggregated counts, rates, percentiles | "How many checkouts failed this hour?" |
| Traces | Request flow, latency breakdown | "Why was this specific request slow?" |
| Logs | Detailed context, debugging | "What happened right before this error?" |
All three are trace-connected. Start wherever makes sense and navigate to the others.
Explore the Metrics product walkthrough guides to learn more about the Sentry interface and discover additional tips.