All lessons
DevOps & cloudBeginner9 min readWorth knowing

Sentry

Find out about errors before users report them, with the stack trace, release and context attached.

  • Error tracking
  • Releases
  • Source maps
  • Performance
Step 1/6
Checkout takes 8 seconds and users are fuming. Time to call the detectives: metrics, traces and logs.

In 30 seconds

Sentry is an application monitoring service focused on errors. An SDK in your app catches exceptions, adds context (browser, user, request, breadcrumbs of what happened before) and sends them to Sentry, which groups identical errors into issues and alerts you. With releases and source maps you see the exact line of your original code, which commit introduced the bug and how many users it affects. It also offers tracing, session replay, logs, cron and uptime monitoring.

Not in my daily stack — I know the concepts and would learn the details when a project needs it.

Why it matters

  • Users rarely report bugs; they leave. Error tracking turns silent failures into alerts with enough detail to fix them quickly.
  • Minified JavaScript stack traces are unreadable; with uploaded source maps Sentry shows the original file, line and surrounding code.
  • Release tracking connects errors to deploys and commits, so a team can see in minutes that "this started with version 1.4.2" and roll back.
  • It is cheap to start (a free tier and a wizard that configures popular frameworks), which is why it is often the first monitoring tool a team adds.

How it works

01How it works: events, issues and the DSN

When an error happens, the Sentry SDK in your app captures it as an event: the exception type and message, the stack trace, and context such as browser and OS, URL, release, environment, user ID if you allow it, and breadcrumbs, a short timeline of recent actions (clicks, navigation, network requests, console messages). The SDK sends it to Sentry using a DSN, a project-specific URL that tells the SDK where to send data. The DSN is not a secret in the usual sense, because it can only send events, which is why it can live in browser code. Sentry then fingerprints the event, mostly by stack trace, and groups similar events into an issue. You work with issues, not with millions of events: one issue says "TypeError in CheckoutForm, 312 events, 87 users, first seen in 1.4.2". Unhandled errors are captured automatically; handled ones you report with captureException.

02Setting it up in a Next.js app

Sentry's wizard configures most frameworks in a few minutes: it installs the SDK, creates config files and wires up source map uploads in the build. For Next.js it creates instrumentation-client.ts for the browser, sentry.server.config.ts and sentry.edge.config.ts for the server runtimes, an instrumentation.ts that loads them and exports onRequestError, and wraps next.config with withSentryConfig. Other platforms are similar: @sentry/react, @sentry/node, sentry/sentry-laravel, @sentry/react-native. After setup, set the environment and release, lower the trace sample rate for production, and decide what user data you send. Then throw a test error to confirm it arrives with a readable stack trace.

ts
// instrumentation-client.ts (created by: npx @sentry/wizard@latest -i nextjs)
import * as Sentry from "@sentry/nextjs";
 
Sentry.init({
  dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
  environment: process.env.NEXT_PUBLIC_APP_ENV ?? "development",
  integrations: [Sentry.replayIntegration()],
  tracesSampleRate: 0.1,          // 10% of transactions in production
  replaysSessionSampleRate: 0.0,  // no replays for normal sessions
  replaysOnErrorSampleRate: 1.0,  // replay every session that hits an error
});
 
export const onRouterTransitionStart = Sentry.captureRouterTransitionStart;

03Releases and source maps

A release is a version label attached to every event, usually the Git commit SHA or a semantic version. With releases, Sentry knows when an issue first appeared, can mark an issue "resolved in next release" and reopen it if it comes back (a regression), and with commit integration it suggests which commit and author likely caused it. Source maps translate minified production code back to your original source. Upload them during the build with the bundler plugin or sentry-cli, then do not serve them publicly; the plugins can delete them after upload. Sentry matches uploaded files to errors using Debug IDs injected into the bundle, which is far more reliable than the old URL matching. Mobile apps need the same idea: dSYMs for iOS, ProGuard/R8 mapping files for Android, and source maps for React Native's JavaScript bundle.

bash
# CI step after the build (if not using a bundler plugin)
export SENTRY_AUTH_TOKEN=***            # from CI secrets, never committed
export SENTRY_ORG=your_org SENTRY_PROJECT=web
VERSION=$(git rev-parse --short HEAD)
 
npx @sentry/cli releases new "$VERSION"
npx @sentry/cli releases set-commits "$VERSION" --auto
npx @sentry/cli sourcemaps inject ./dist
npx @sentry/cli sourcemaps upload --release "$VERSION" ./dist
npx @sentry/cli releases finalize "$VERSION"
npx @sentry/cli deploys new --release "$VERSION" -e production
find ./dist -name "*.map" -delete

04Adding context: users, tags and breadcrumbs

An error without context is a puzzle. Add an anonymised user ID with Sentry.setUser so you can count affected users and find all errors for one customer who contacts support. Add tags for things you want to filter and search by: tenant plan, feature flag, payment provider, app locale. Tags are indexed and should have a limited set of values. Use contexts or extra data for larger structured information that you only read on the event page. Breadcrumbs are recorded automatically for navigation, clicks, console and network calls; add your own for important business steps. Be deliberate about privacy: do not send emails, names or tokens unless you have a reason and a legal basis, and use beforeSend to remove sensitive fields. Server-side data scrubbing in project settings is a second layer of protection.

ts
import * as Sentry from "@sentry/nextjs";
 
Sentry.setUser({ id: account.id });               // id only, no email
Sentry.setTag("plan", account.plan);               // "free" | "pro" | "enterprise"
 
try {
  await chargeCard(order);
} catch (err) {
  Sentry.captureException(err, {
    tags: { payment_provider: "stripe" },
    contexts: { order: { id: order.id, total: order.total } },
  });
  throw err;
}

05Alerts, noise and quotas

Sentry is only useful if people trust its alerts. Start with three kinds: a new issue in production, a regression (a resolved issue that came back), and a spike in frequency or affected users. Route them to the owning team's Slack channel with ownership rules based on file paths or URLs, and page someone only for high-impact metric alerts, such as a drop in crash-free sessions or error rate above a threshold. Keep noise down: ignore known browser-extension errors with ignoreErrors and denyUrls, use inbound filters for legacy browsers and web crawlers, and archive issues you will not fix. Plans include a monthly quota of errors, spans, replays and logs; a single bug in a loop can burn through it in an hour. Use spike protection and per-key rate limits, sample transactions, and set a spending cap on paid plans.

Use it when

  • Any production web or mobile app where you want to learn about errors before users complain.
  • Frontend apps with minified code, where readable stack traces need source maps.
  • Teams that deploy often and want to connect errors to releases, commits and rollbacks.
  • Mobile apps that need crash reports, crash-free session rates and release health.

Skip it when

  • As your only monitoring: Sentry does not replace uptime checks, server metrics, backups or log retention.
  • Strict data residency or privacy rules that the hosted regions do not meet, unless you self-host.
  • When you need deep infrastructure metrics and distributed tracing across many services as the main goal; OpenTelemetry with a tracing backend fits better.

Alternatives

  • Self-hosted Sentry

    Same product on your own servers via Docker Compose; free licence, but it is a heavy stack to run and upgrade.

  • GlitchTip

    Lightweight open-source error tracker compatible with Sentry SDKs; fewer features, much easier to self-host.

  • Datadog / New Relic

    Full observability platforms with error tracking included; broader, more expensive.

  • Firebase Crashlytics / Bugsnag

    Strong mobile crash reporting; Crashlytics is free and common in mobile-only teams.

Best practices

  1. Set environment and release on every event; use the Git SHA as the release.
  2. Upload source maps (and dSYMs or mapping files) in CI, and do not publish them.
  3. Send an anonymised user ID, not personal data, and scrub sensitive fields with beforeSend.
  4. Sample performance traces in production (often 5–20%) and keep error sampling at 100%.
  5. Assign ownership rules so every issue lands with a team, and review new issues weekly.
  6. Filter known noise (browser extensions, bots, aborted requests) so real errors stand out.
  7. Enable spike protection and rate limits to protect your quota from runaway loops.

Common mistakes

  • Shipping without source maps and getting stack traces that point at line 1 of a minified bundle.
  • Leaving tracesSampleRate at 1.0 in production and using up the quota in days.
  • Catching errors and swallowing them without captureException, so Sentry never sees them.
  • Sending emails, tokens or full request bodies with events, creating a privacy problem.
  • Alerting on every event to a shared channel until everyone mutes it.

Deep dive

06Sampling, quotas and cost control

Sentry bills by volume per data category: errors, spans, replays, attachments, logs and monitors, each with a monthly quota and optional pay-as-you-go budget. Control happens at three layers. In the SDK: tracesSampler (a function) lets you sample by route, for example 100% for checkout, 1% for health checks, 0 for bots; replaysOnErrorSampleRate keeps replays only where they help; beforeSend and beforeSendTransaction drop events you know are noise. At the project level: inbound filters, rate limits per DSN key and spike protection, which temporarily drops events when volume jumps far above normal. At the organisation level: spending caps and alerts. Sampling decisions propagate with the trace in the sentry-trace and baggage headers, so frontend and backend keep or drop the same trace together.

ts
Sentry.init({
  dsn: process.env.SENTRY_DSN,
  tracesSampler: ({ name, inheritOrSampleWith }) => {
    if (name.includes("/healthz")) return 0;        // never trace health checks
    if (name.includes("/checkout")) return 1.0;     // always trace checkout
    return inheritOrSampleWith(0.05);               // follow parent, else 5%
  },
  beforeSend(event) {
    if (event.request?.headers) delete event.request.headers["authorization"];
    return event;
  },
});

07Distributed tracing between frontend and backend

When a browser page calls your API, Sentry's browser SDK adds sentry-trace and baggage headers to outgoing requests that match tracePropagationTargets. The backend SDK reads them and continues the same trace, so one trace shows the page load, the fetch, the API handler and the SQL queries. Set tracePropagationTargets to your own API origins only; sending these headers to third-party domains can break their CORS preflight. Your API must also allow these headers in CORS. For server-rendered pages, the server injects trace meta tags so the browser continues the server's trace. Because the JavaScript SDK is built on OpenTelemetry, it also understands W3C traceparent, and you can send OTel data from other services to Sentry through its OTLP endpoint, which makes Sentry part of a wider OTel setup rather than a separate island.

08Self-hosting versus SaaS

Sentry's code is available under the Functional Source License, and the self-hosted distribution runs with Docker Compose. It is not small: Kafka, ClickHouse, PostgreSQL, Redis, Snuba, Relay, Symbolicator and many workers, with a recommended minimum of around 4 CPU cores, 16 GB of RAM plus swap and fast disks. You must upgrade through specific versions in order, back up Postgres and ClickHouse, and monitor the stack itself. Some newer features such as the AI debugging agent are SaaS-only. Self-hosting makes sense for strict data residency or air-gapped environments, or at a volume where licence savings outweigh an engineer's time. For most teams the SaaS, with its EU or US data region and server-side scrubbing, is cheaper in total. A lighter middle ground is GlitchTip, which accepts Sentry SDK data with far fewer components.

Real-world scenarios

01

Errors arrive with minified stack traces

Problem

Sentry is installed in a Vite React app, but every stack trace shows index-3f9a.js line 1 and minified names.

How to solve it

Source maps are not being uploaded or matched. Enable build.sourcemap in Vite (hidden source maps are fine), add @sentry/vite-plugin with org, project and SENTRY_AUTH_TOKEN from CI secrets, and let it inject Debug IDs and upload, then delete the .map files from the output. Make sure the release in Sentry.init matches the release the plugin creates. Deploy, trigger a test error, and check the event's processing errors section, which explains missing or mismatched maps. Use npx @sentry/cli sourcemaps explain with the event ID if it still fails. Add the step to CI so every build uploads maps automatically.

02

A bug in a loop burns the monthly quota

Problem

A new release threw the same error thousands of times per user per minute. By the next morning the error quota for the month was used up and other errors were dropped.

How to solve it

Roll back or hotfix the bug first. In Sentry, make sure spike protection is on and set a rate limit on the DSN key for the affected project, for example a few thousand events per minute. In the SDK, fix the code path that re-throws in a loop and consider deduplicating errors client-side; the Dedupe integration drops identical consecutive events. Set a pay-as-you-go budget with a cap so a future spike is absorbed without unlimited cost. Add a metric alert on event volume per project, so an abnormal spike notifies the team within minutes instead of being discovered at month end.

03

Linking a mobile crash to a backend problem

Problem

A React Native app shows crashes on the order screen, but the backend team says their API is fine.

How to solve it

Enable tracing in both the React Native SDK and the backend SDK, and set tracePropagationTargets to the API domain so requests carry sentry-trace and baggage headers. Upload JavaScript source maps and native debug files (dSYMs, ProGuard mappings) in the mobile build pipeline so crashes are readable. Now open a crash and follow its trace: you may see the API returning a 200 with an unexpected null field that the app does not handle. Add a tag for app version and API version. The fix is often in both places: defensive parsing in the app and a contract test on the API.

Cheat sheet

Set up a framework with the wizard
npx @sentry/wizard@latest -i nextjs
Report a handled error
Sentry.captureException(err)
Send a message event
Sentry.captureMessage("Payment webhook retried", "warning")
Attach an anonymised user
Sentry.setUser({ id: account.id })
Add a searchable tag
Sentry.setTag("plan", "pro")
Upload source maps from CI
npx @sentry/cli sourcemaps inject ./dist && npx @sentry/cli sourcemaps upload --release "$VERSION" ./dist
Debug why a source map failed
npx @sentry/cli sourcemaps explain <event-id>
Ignore browser extension noise
denyUrls: [/extensions\//i, /^chrome:\/\//i]
Laravel install
composer require sentry/sentry-laravel && php artisan sentry:publish --dsn=<your-dsn>

Questions & answers

Q1What is a DSN and is it safe to expose in the browser?

The DSN (Data Source Name) is a URL that contains the project's public key and ID and tells the SDK where to send events. It only allows sending events to that project, not reading data or changing settings, so it is designed to be embedded in browser and mobile apps. The real secret is the auth token used by sentry-cli and build plugins to create releases and upload source maps; that one must stay in CI secrets. The risk of an exposed DSN is spam: someone could send fake events and consume quota. Mitigate it with allowed domains, rate limits per key and inbound filters.

Q2Why are source maps important, and how do you keep them private?

Production JavaScript is minified and bundled, so a raw stack trace points to something like main.4f2a.js line 1, column 48211, which is useless. Source maps map those positions back to the original file, line and function. Sentry uses them on its servers to show readable stack traces with surrounding code. To keep your source private, upload the maps to Sentry during the build and do not deploy them to the public server: the bundler plugins can delete them after upload, or you can exclude .map files from the deploy. Debug IDs injected into each file let Sentry match maps reliably without relying on public URLs.

Q3How does Sentry group errors into issues?

Each event gets a fingerprint. By default it is based on the stack trace, mostly the in-app frames, which is your code rather than libraries; if there is no stack trace it falls back to the exception type and message. Events with the same fingerprint belong to the same issue. Sometimes the default is wrong: one generic error from different causes merges into one issue, or a dynamic message creates thousands of issues. You fix that with fingerprint rules and stack trace rules in project settings, or by setting a custom fingerprint in the SDK, for example grouping all timeouts from one API client by endpoint.

Q4What is the difference between Sentry's error tracking and tracing?

Error tracking captures exceptions and crashes with stack traces and context, groups them and alerts. Tracing (performance monitoring) records spans for page loads, navigations, API requests and database queries, so you see how long things take and where the time goes, even when nothing fails. Sentry connects them: an error carries the trace ID, so you can open the request that failed and see the slow query before it. Errors are usually kept at 100%, while traces are sampled because their volume is much higher. Since version 8, Sentry's JavaScript SDK uses OpenTelemetry internally, so it can work alongside other OTel instrumentation.

Q5A client asks: why pay for Sentry if we have server logs?

Logs tell you what the server did; Sentry tells you which problems users actually hit and how often. Most frontend and mobile errors never reach server logs at all: a crash in the browser or app happens on the user's device. Sentry captures those, groups thousands of events into a short list of issues, shows the exact line of original code, the release and commit that introduced it, how many users are affected, and a replay of what the user did. It alerts the team when a new problem appears after a deploy. That usually turns a bug from days of guessing into an hour of fixing, which pays for the plan quickly.

Senior-level questions

S1How do you make Sentry useful for a large organisation instead of a noisy inbox?

Structure and ownership come first. Create projects per deployable app, use environments (production, staging) and releases consistently, and add ownership rules or code owners integration so each issue is auto-assigned to a team. Alert on what matters: new issues in production, regressions, and metric alerts on error rate or crash-free sessions tied to SLOs, routed to the owning team's channel and paging only for user-impacting thresholds. Reduce noise with inbound filters, ignore rules and fingerprint rules for known groups. Run a weekly triage per team with a simple rule: resolve, assign, or archive with a reason. Track crash-free rate per release as a release gate. The trade-off is upfront configuration work, which pays back as trust in alerts.

S2Sentry or an OpenTelemetry-based stack: are they competitors?

They overlap but are focused differently. OpenTelemetry is an instrumentation standard and pipeline; it gives you portable traces, metrics and logs, but no backend, no issue grouping and no workflow. Sentry is a product built around developer workflows: grouping, regressions, release health, suspect commits, replays and source map handling, plus tracing. Since its JavaScript SDK runs on OpenTelemetry internally and Sentry accepts OTLP, they combine well: OTel instrumentation for backend services with a Collector exporting traces to your tracing backend, and Sentry for frontend and mobile errors, crashes and replays, sharing trace context. Choose by questions: "which code is broken for users?" fits Sentry; "where does latency go across 30 services?" fits an OTel tracing backend.

S3How do you handle privacy and GDPR with Sentry and Session Replay?

Collect the minimum. Use an internal user ID instead of email or name, keep default PII collection off, and strip headers, cookies, query strings and request bodies that may contain personal data in beforeSend. Enable server-side data scrubbing and advanced scrubbing rules as a safety net. For Session Replay, keep the defaults that mask all text and block media, and unmask only specific safe elements; never record payment or medical forms. Choose the EU data region if your users are in Europe, sign the data processing agreement, and set retention as short as is useful. Document Sentry as a processor in your privacy policy. Finally, honour consent: initialise replay only after the user accepts, if your legal basis requires it.

Glossary

DSN
The project URL and public key that tells an SDK where to send events; safe to embed in clients.
Event
One captured error, message or transaction, with stack trace, context and breadcrumbs.
Issue
A group of similar events sharing one fingerprint, which the team triages and resolves.
Fingerprint
The value Sentry uses to decide which events belong to the same issue; customisable.
Breadcrumbs
A timeline of actions before an error: clicks, navigation, network calls and console messages.
Release
A version identifier attached to events, linking errors to deploys and commits.
Debug ID
A unique ID injected into bundles and source maps so Sentry can match them reliably.
Session Replay
A privacy-masked, video-like reconstruction of what the user did before an error.
Spike protection
A Sentry feature that drops events temporarily when volume suddenly rises far above normal.

Have a product in mind?Let's build it.

Tell me about your idea, your product or your team. I usually reply within one working day.