TL;DR:

  • Sentry catches and aggregates unhandled exceptions, providing stack traces, user context, and release tracking — it tells you what broke, who was affected, and what changed
  • The most common mistake is treating it as a logging tool and never acting on it; the value comes from triaging issues, not just collecting them
  • Release tracking and performance monitoring are underused features that turn Sentry from a crash collector into a genuine debugging workflow

If you’re shipping code without error tracking, you’re discovering your production bugs through user complaints rather than before them. Sentry is the standard solution for most teams — it’s quick to set up, covers most languages and frameworks, and has a generous free tier that works for many small projects.

The harder part isn’t installation. It’s using it in a way that actually improves how you respond to bugs.

Basic Setup

Installation varies by platform, but the pattern is consistent: install the SDK, initialise it with your DSN (a project-specific URL from the Sentry dashboard), and it starts capturing uncaught exceptions automatically.

For JavaScript (browser or Node.js):

npm install @sentry/browser  # or @sentry/node
import * as Sentry from "@sentry/browser";

Sentry.init({
  dsn: "https://your-project-dsn@sentry.io/project-id",
  environment: process.env.NODE_ENV,
  release: process.env.COMMIT_SHA,  // More on this below
  tracesSampleRate: 0.1,  // 10% of transactions for performance
});

For Python (Django/Flask):

pip install sentry-sdk
import sentry_sdk

sentry_sdk.init(
    dsn="https://your-project-dsn@sentry.io/project-id",
    environment="production",
    release=os.environ.get("COMMIT_SHA"),
    traces_sample_rate=0.1,
)

The default configuration captures unhandled exceptions. That’s enough to get started, but there are several things you should configure early to avoid problems later.

Setting Up Release Tracking

Release tracking is the feature that turns Sentry from a passive bug collector into a useful debugging tool. When you tell Sentry which version of your code is running, it can:

  • Show you which release introduced an issue
  • Track whether an issue was resolved in a specific release
  • Alert you when a new release causes a regression

To use it effectively, set the release parameter to your commit SHA or version tag, and create a Sentry release during your deployment pipeline:

# In your CI/CD pipeline
export SENTRY_AUTH_TOKEN=your_auth_token
export SENTRY_ORG=your-org
export SENTRY_PROJECT=your-project

npx sentry-cli releases new $COMMIT_SHA
npx sentry-cli releases set-commits $COMMIT_SHA --auto
npx sentry-cli releases finalize $COMMIT_SHA
npx sentry-cli releases deploys $COMMIT_SHA new -e production

With this in place, every issue in Sentry shows which commit introduced it. If you push a release and a new category of errors appears within minutes, you know exactly where to look.

Sourcemaps for Minified JavaScript

If you’re shipping minified or bundled JavaScript without sourcemaps, your Sentry stack traces are nearly useless — you’ll see minified variable names and no line numbers that correspond to your source.

Upload sourcemaps during your build:

npx sentry-cli sourcemaps upload --release $COMMIT_SHA ./dist

Or use the Sentry webpack/vite plugin which does this automatically as part of your build:

// vite.config.js
import { sentryVitePlugin } from "@sentry/vite-plugin";

export default {
  plugins: [
    sentryVitePlugin({
      authToken: process.env.SENTRY_AUTH_TOKEN,
      org: "your-org",
      project: "your-project",
    }),
  ],
  build: {
    sourcemap: true,
  },
};

This is a five-minute setup that dramatically improves the quality of every stack trace you’ll ever see.

Adding Context

The default exception capture gives you a stack trace and some environment data. Adding context turns a generic exception into a debuggable issue.

User context: Attach the current user when they’re authenticated:

Sentry.setUser({
  id: user.id,
  email: user.email,
  username: user.username,
});

This lets you see how many unique users an issue affects, filter issues by user, and — for enterprise plans — contact affected users.

Breadcrumbs: Sentry automatically captures some breadcrumbs (console logs, HTTP requests, navigation events in browser SDKs). You can add custom ones:

Sentry.addBreadcrumb({
  category: "payment",
  message: "User initiated checkout",
  level: "info",
  data: { cart_total: 49.99 },
});

These appear in the breadcrumb trail for any exception that occurs after them, giving you the sequence of events that led to the crash.

Tags and extra data:

Sentry.setTag("subscription_tier", "pro");
Sentry.setExtra("cart_items_count", 7);

Tags are indexed and filterable; extra data is context for debugging but not searchable.

Avoiding Alert Fatigue

The most common Sentry antipattern: an organisation sets it up, gets overwhelmed by alerts, turns off notifications, and ends up with a dashboard full of ignored issues. The alerts stop being useful, the errors keep happening, and users keep noticing bugs before the team does.

A few practices that help:

Triage issues when they’re new. When a new issue appears in Sentry, someone should look at it within a reasonable time window — not necessarily fix it immediately, but decide: is this critical, worth fixing soon, expected behaviour, or something to ignore? Sentry’s issue states (Unresolved, Resolved, Ignored, Archived) exist for this.

Use alert routing. Set up alert rules that route critical issues to your incident response channel immediately, and non-critical issues to a daily digest. Not every exception should page your on-call engineer.

Set volume thresholds. An issue that fires once an hour is different from one that fires a thousand times. Alert on frequency, not just presence. Sentry’s alert conditions support thresholds like “more than 10 occurrences in 5 minutes.”

Mark issues as resolved on release. When you fix a bug and deploy, mark the corresponding Sentry issues as resolved. If they resurface, Sentry will alert you to the regression. This closes the feedback loop.

Performance Monitoring

Sentry’s performance monitoring (now called Tracing) captures distributed traces and measures transaction performance. The tracesSampleRate you saw in the initialisation code above controls what percentage of requests generate a trace.

For most applications, 10% sampling is a reasonable start for production. You can increase it in staging or for specific transactions you’re trying to debug.

Performance monitoring is particularly useful for identifying slow database queries, external API calls that are adding latency, and N+1 query patterns. The Sentry dashboard shows p50/p90/p99 latency distributions by transaction, so you can find the worst outliers rather than average performance.

The combination of error tracking and performance monitoring in the same tool means you can see “this endpoint has 200ms p99 latency and also throws exceptions for 0.3% of requests” — which is more useful than seeing either in isolation.