Sentry vs Raygun: Hands-On Error Tracking Comparison for 2026

Stanley Ulili
Updated on October 26, 2026

Sentry and Raygun both promise to help you find and fix application problems, but the amount of information they give you during an investigation can be very different. Sentry brings error tracking, distributed tracing, logs, and session replay together, while Raygun separates crash reporting, real user monitoring, and application performance monitoring into dedicated products.

I wanted to see how much that difference matters when something actually breaks, so I connected both platforms to the same Node.js bookstore. I introduced frontend and backend errors, tested source maps and error grouping, and shipped three releases, including one that made checkout dramatically slower and caused intermittent payment failures.

The results revealed a significant difference. Both tools detected the new payment errors, but only Sentry traced the checkout slowdown to the database query responsible. Raygun's release comparison actually reported that the faulty version was 34.8% faster, because it measured page loads rather than the slow checkout request.

Sentry also made it easier to follow errors from the browser to the backend, investigate session replays, and identify regressions. Raygun had advantages of its own, particularly its page-level performance reports, customer activity tracking, and options for managing resolved errors.

This hands-on comparison covers setup, error capture, debugging, grouping, real user monitoring, session replay, release tracking, performance, logs, AI-assisted debugging, and pricing, with screenshots and results from my October 2026 tests.

Sentry vs Raygun: Results at a glance

These verdicts reflect my Node.js and Express app and the way I configured it, so other stacks can land differently.

Area Better in my test Why
Setup Sentry One project for both sides; Raygun needed two applications and a loading workaround
Error capture Sentry Raygun missed the unhandled promise rejection
Debugging Sentry Backend source lines and a direct link from a browser error to its backend cause
Error grouping Sentry, narrowly Raygun split one bug by URL and another by amount; both made duplicates after a code change
Real user monitoring Raygun Per-page and per-request speed with no extra setup
Session replay Sentry Video replay with a network tab; Raygun offers a page timeline only
Release tracking Sentry Releases come from the SDK and regressions show in the list
Performance monitoring Sentry One trace showed the slow query; Raygun's tools missed it
Logs and events Sentry Logs linked to traces; Raygun has no log product
Uptime, status pages and alerts Not compared Not tested in either tool
AI-assisted debugging Not compared Only Seer was run, with the repository connected
Starting price Sentry Free plan and a cheaper first paid tier

How I tested Sentry and Raygun

My test app is monitoring-lab, a small bookstore built to fail in ways I can predict. The server is Express 5 on SQLite, the storefront is built with Vite, and two helpers misbehave on purpose: a price service that returns 503s and a sales report job that fails every minute.

Each tool got a thin adapter on both sides, so both SDKs saw identical failures from identical code.

The planted problems fell into five groups:

  • Backend crashes: a coupon code that doesn't exist, which causes a TypeError, and a book ID that doesn't exist.
  • Other backend failures: a handled out-of-stock error, an upstream 503, a promise nobody catches and the failing report job.
  • Browser errors: a crash on the wishlist button, plus storefront requests that fail with different status codes.
  • Slow paths: one slow book page, a CPU-heavy search endpoint, a slow price lookup and a cover image that never loads.
  • Release problems: a fixed bug that ships again, and a bad deploy with a new error and a slow query.

A traffic script simulated three shoppers named alice, bob and carol, three users over the API and two in headless Chromium.

The three releases

I shipped three versions through both tools.

Release What I tested
1.0.0 First install, capture from both sides, readable stack traces, breadcrumbs, user monitoring and speed
1.1.0 A coupon crash marked as fixed that ships again unchanged, to see which tool flags the comeback
1.2.0 A bad deploy: checkout waits on a slow database query, and every fifth card charge fails

The third release is the one that separated the tools.

It broke the shop in two ways at once. The payment failure throws a new exception, which any error tracker can catch. The slow query raises no exception at all, which means you need request timing to notice it.

Both tools reported the new error. Only one of them found the slowdown, and the evidence is under release tracking and performance below.

SDKs and test limitations

Platform SDKs
Sentry @sentry/node, @sentry/profiling-node and @sentry/browser 11.8.0, one project
Raygun Crash Reporting raygun 2.2.10 for the API and raygun4js 3.1.4 for the storefront, two applications
Raygun APM raygun-apm 2.3.0 plus the Raygun APM Agent in Docker, release 1.0.0 only

A few conditions shape the results:

  • Only Sentry had my GitHub repository connected. Its AI, Seer, read the code. I didn't test Raygun's AI.
  • Raygun ran on its 14-day trial. The trial blocks Personal Access Tokens, which forced manual source map uploads and manual deployments.
  • Raygun APM ran only during release 1.0.0. Installing it broke Crash Reporting, so I removed it before 1.1.0 and 1.2.0. It never saw the bad release.
  • Each tool got its own traffic runs. Event counts aren't comparable one to one.
  • Everything ran on Node.js. Raygun's APM support and both tools' grouping behave differently in other languages.
  • The storefront reported production and the API reported development. That's my lab's setup, and it affects per-environment views.

Setup and onboarding

Setup decides how many places you'll look when something breaks. Sentry gave me one, and Raygun gave me two.

Sentry: One project for the browser and the server

Creating the Sentry project detected my GitHub repository and offered Express and Browser JavaScript from it. The browser SDK then sent to the same project and the same DSN as the API, so one issue list held both sides from the first event.

The onboarding page put my DSN into the snippet and offered every product as a checkbox:

Sentry onboarding with errors, tracing, replay, logs and profiling selected

Errors, logs, metrics, tracing and profiling are all on by default, so the generated code already covers more than error capture.

Source maps went up through sentry-cli as part of the build script, and I didn't touch the Sentry UI again before traffic ran.

Raygun: One application per part of your app

Raygun organizes everything around applications. Each one has its own API key and its own error list, so I created monitoring-lab-api for the server and monitoring-lab-web for the storefront.

The first onboarding step explains the model before you create anything:

Raygun onboarding step 1, Create first application

The page says applications let you monitor each part separately, a frontend, a backend, an API or a mobile app, and the trial counter reads "Day 1/14".

The full application form also sets notification defaults:

Raygun Create application form for monitoring-lab-web

New-error emails, a daily summary and a weekly RUM update are switched on, while APM alerts start off.

Onboarding then takes one product at a time. Raygun's own wording is "We currently only support setting up one product at a time for your selected language", and step 3 won't let you leave until data arrives:

Raygun onboarding step 3, waiting for Real User Monitoring data

Crash Reporting has its green check, and Real User Monitoring still says it hasn't received anything. I sent a bad coupon to the API with curl to get past it.

Raygun's browser library needed a workaround

raygun4js reads its settings when the page's load event fires. My storefront imports its monitoring code after that event, so the library never started and sent nothing.

Raygun's npm instructions don't warn about this. The fix was to copy what Raygun's CDN snippet does: queue the calls first, then import the library after the page has loaded.

That load order is specific to my app, but any lazily loaded monitoring module will hit the same wall.

Setup comparison

Capability Sentry Raygun
Project structure One project for both sides One application per part
Keys One DSN One API key per application
Repository detection ✔: offered during project creation ✘: not observed
Onboarding All products in one snippet One product at a time, waits for data
Browser SDK Worked as installed Needed a load-order workaround in my app
Source maps on the trial ✔: CLI upload in the build ✘: manual upload only

Verdict: Sentry. One project and one snippet covered the whole app. Raygun needed two applications, a curl call to finish onboarding and a workaround before the browser sent anything.

Error capture

Both tools caught the browser crash and most backend failures. The difference came from one error that Node.js treats differently.

Sentry: Every seeded error arrived

Sentry's list after the first release held 11 issues, six from the server and five from the browser:

Sentry issues list after the first release, backend and browser together

The "Recommendation engine timed out" row is the unhandled promise rejection. Rows also carry a replay count, such as "▷ 7" on the wishlist crash, so you can see which errors have a recording.

Raygun: The unhandled rejection never arrived

Raygun's API application showed five error groups:

Raygun API error groups after the first release

The report job, the 503, the out-of-stock error and both TypeErrors are there, and "Recommendation engine timed out" is missing. I had reportUncaughtExceptions switched on.

This doesn't prove Raygun can't capture unhandled rejections in Node.js. It does mean the integration I followed didn't capture this one.

The Crash Reporting dashboard was the first screen I saw after traffic ran:

Raygun Crash Reporting dashboard for monitoring-lab-api

It defaults to a 7-day range, so the errors-by-hour chart is a flat line with one spike at the far right. You'll want to narrow the range before it tells you anything.

The broken image

The cover image that never loads didn't create an error in either tool. Sentry's replay was the only place it showed up, which you'll see in the replay section.

Error capture comparison

Test Sentry Raygun
Browser crash ✔: captured ✔: captured
Backend crashes ✔: captured ✔: captured
Handled errors ✔: captured ✔: captured
Unhandled promise rejection ✔: captured ✘: missed in my setup
Broken image as an error ✘: not an issue, visible in replay ✘: not captured
One list for both sides ✔: one project ✘: two applications

Verdict: Sentry. It caught one more failure, and both sides landed in one list. The event counts in each tool came from separate traffic runs, so the useful comparison is which errors arrived at all. Event totals per group can't be compared one to one.

Debugging an error

Capturing an error only starts the job. What matters next is how fast the error page gets you to the line and the request that caused it.

Sentry: Source maps from the build

Sentry's CLI uploaded the source maps during the build, and the wishlist crash arrived already readable:

Sentry browser error with the source-mapped stack trace

The frame reads ../../src/pages.js:122:13 with wishlist.items.push(book.id); highlighted and my deliberate-bug comment above it. A "Set up Code Mapping" link on the frame offers to connect it to the repository.

Backend frames showed source too. Each one also carried a GitHub icon that opens the file in the repository.

Raygun: Manual source maps on the trial

Uploading source maps through Raygun's API needs a Personal Access Token. On the trial, the token page said "Purchase a plan to use this feature".

Until the maps were in place, the wishlist crash pointed into minified code:

Raygun browser error with a minified stack trace

You can't locate the bug from a minified frame like index-tWfydWxy.js:2:2762.

The trial route is the JS Source Map Center, where you upload each file by hand. Every upload starts without a label:

Raygun JS Source Map Center after upload, with every file unlabelled

All four rows read "Please enter resource URL here", so you type the full URL the browser loads each file from.

Labelled, the center pairs every generated file with its URL:

Raygun JS Source Map Center with labelled files

Each label saved only when no other row already held that URL, and twice my labels ended up swapped between files. Built file names change on every build, so you repeat this after each rebuild.

Once the labels were right, "Re-process this error for Source Maps" worked straight away:

Raygun browser error with the source-mapped stack trace

The frame now reads pages.js:122, column 13, with lines 119 to 125 and the bug highlighted. The end result matches Sentry's, after a lot more manual work.

Backend frames stayed bare:

Raygun backend stack trace with no source lines

You get server.js:150 and "1 framework frame", with no code, so you open your editor to see what line 150 does.

Context and breadcrumbs

Sentry's browser error page puts the breadcrumbs next to the error:

Sentry browser error header with breadcrumbs

The trail runs from the fetch to /books/2, through the click with its CSS selector and the app's own "add to wishlist clicked", to the exception.

Raygun recorded the browser side automatically too:

Raygun browser breadcrumbs before an error

Clicks, hash changes, "Navigated back" and each request opening and finishing all appear, along with the app's messages.

On the server, Raygun's breadcrumbs stayed scoped to one request:

Raygun API breadcrumbs for one checkout request

POST /checkout, "checkout started" and "book found" appear with nothing from other shoppers mixed in.

Raygun's backend error page organizes the rest of the context under tabs:

Raygun API error page header

The header gives total instances, affected users linked to the Customers page, and first and last seen. The tabs below are Summary, Error details, HTTP, Environment, Custom, Breadcrumbs and Raw data. "Browser affected: curl 8.7.1" came from my onboarding curl call.

Sentry's backend error carried more in one place:

Sentry backend error with the request body and the browser replay attached

The request body {"bookId":6,"coupon":"FREEBOOKS","quantity":1} is kept, and alice's browser session replay sits inline on a server error. The browser passed its replay ID in the baggage header, so no setup on my part linked them.

From the browser to the backend

When the storefront's checkout fails, the browser records one error and the server records another, the real cause.

Sentry ties the two together. The failed browser checkout carried a Trace Preview reading "1 other issue appears in this trace":

Sentry browser error linked to the backend error in the same trace

The linked issue is the server's coupon TypeError, and the backend issue links back the same way.

Opening the trace shows each step between the click and the database:

Sentry trace from the storefront click to the database query

There are 12 spans in 64.90 ms, from the "place order" click through the HTTP request and the Express handler to the db.query span at the bottom.

The trace's Logs tab puts both sides' log lines in order:

Sentry trace Logs tab with browser and backend logs

The browser's "checkout partly failed" and the server's "POST /checkout failed" sit next to each other, each attached to its error.

Raygun can't make this connection. The browser error lives in monitoring-lab-web and the backend error in monitoring-lab-api, and Crash Reporting has no tracing to link them.

Debugging comparison

Capability Sentry Raygun
Browser source maps ✔: CLI upload in the build ✔: manual upload on the trial, API on paid plans
Backend source lines ✔: shown, with a GitHub link ✘: file and line only
Browser breadcrumbs ✔: automatic ✔: automatic
Request-scoped server breadcrumbs ✔: captured ✔: captured
Request body on the error ✔: kept Under the HTTP tab
Replay on a backend error ✔: attached through baggage ✘: not offered
Browser-to-backend link ✔: one trace ✘: separate applications

Verdict: Sentry, by a wide margin. Automatic source maps, backend source lines and the link from symptom to cause each save time on every error. Raygun matched it on breadcrumbs.

Raygun gave my shop two applications that never reference each other, and Sentry linked the two sides only by sending you from issue to trace. I also ran the same app through Better Stack, and one visit to the shop appeared as a single timeline: the recording at the top, 30 browser spans and 7 server spans underneath. The server needed no new library, since it kept the Sentry SDK and pointed it at a Better Stack DSN.

Better Stack timeline holding browser and server spans from one visit

The page, the clicks, the API calls and the server work all line up on one time axis. From any server error, the "View related" menu then takes you wherever you need to go next:

Better Stack View related menu on an exception

Logs, spans, the release, the session replays and an AI investigation are each one click from the error. One gap to know about: the browser tag didn't give me readable source maps in this test, so browser frames stayed minified.

Trace a request from the browser click to the database

Error grouping

Grouping decides whether one bug appears as one item or several. Too much splitting buries the list in duplicates, and too much merging hides separate problems under one title.

In this test, Raygun split more often, and both tools opened duplicates when the code changed.

Raygun: Split by URL and by amount

The storefront's failed book loads are one bug in one place in the code, triggered with different book IDs. Raygun's browser list gave each URL its own group:

Raygun browser error groups with the book load error split by URL

The ApiError rows for /books/0, /404, /99 and /1234 each stand alone. The orders tracking error also has a changing ID in its URL and stayed in one group, so the behavior wasn't consistent.

The new payment error in release 1.2.0 includes the failed amount in its message, and Raygun made a group per amount:

Raygun errors after the bad release, with the payment error split by amount

"Payment gateway rejected charge of 44 USD" has 8 events and "…of 35.5 USD" has 2. They share the class and the same two-frame stack, so the message text is what pulled them apart.

Sentry: One payment issue, one merge too many

Sentry kept the payment error as one issue across every amount, with 13 events from 3 users:

Sentry issues list after the bad release

PaymentGatewayError appears once. Look at the browser ApiError for "POST /checkout failed with 500" too: Sentry groups it by the browser stack, so the new payment failures joined the old coupon group, and its title switched to the payment message.

That merge is the opposite mistake from Raygun's. The browser error group no longer told you which server failure sat behind it, although the trace link still did.

Duplicates after the code changed

The 1.2.0 checkout code changed the stack traces of some old bugs, and both tools opened new groups for them.

Error in release 1.2.0 Sentry Raygun
New payment error One issue Two groups, one per amount
Coupon TypeError Original plus one duplicate Original plus one duplicate
Out-of-stock error Original plus one duplicate Original plus two duplicates
Browser checkout failure Merged into the old coupon group Not observed

What this shows is narrow. In my Node.js app, Raygun's grouping used parts of the message, so URLs and amounts produced new groups. Raygun lets you customize grouping, and other languages may behave differently.

If your error messages carry IDs, amounts or URLs, test this before you trust Raygun's counts. In our Sentry vs Rollbar test, the splitting came from changing framework frames instead, a reminder that every default breaks somewhere.

Error grouping comparison

Test Sentry Raygun
One book bug with changing IDs One issue Four groups
Payment error with changing amounts One issue Two groups
Old bugs after a stack change Two duplicates Three duplicates
Different failures merged Browser checkout group took the payment error Not observed
Main weakness Browser groups follow the browser stack Message text splits groups

Verdict: Sentry, narrowly. It kept each server bug in one issue more often and opened fewer duplicates. Its browser grouping hid one new failure inside an old group, so neither default is safe to accept untested.

Real user monitoring and session replay

Real user monitoring measures how fast your pages are for actual visitors. Session replay shows what a visitor did. Raygun is stronger on the first and Sentry on the second.

Raygun: Page and request speed without extra setup

Raygun's Real User Monitoring charts load time and the Core Web Vitals on its Performance tab:

Raygun RUM performance view with load time and Core Web Vitals

Load time, first paint, FCP, LCP, FID, CLS and INP each get a chart, with a Custom chart beside them.

Below the charts, Raygun ranks pages and requests:

Raygun most viewed virtual pages and requests with timings

Book pages averaged 1.58 s against 285 ms for the home page, and the requests table showed /search at 1.49 s and /prices at 2.63 s. Those are three of the slow paths I built in.

Raygun collapses /books/3 into /books/*, so you drill in to find which book is slow. It still pointed in the right direction from the first visit.

The Customers page ties sessions and errors to one person:

Raygun Customers page joining sessions and errors per user

alice shows 10 sessions and 5 errors, so you can see how often one customer runs into trouble.

Sentry: Web Vitals that needed route names

Sentry's Web Vitals dashboard scored the storefront at 90:

Sentry Web Vitals dashboard

P75 LCP is 92 ms, INP 8 ms and CLS 0.0007, while TTFB sits at 2.51 s, which hints at the slow server behind the pages.

The page breakdown was less useful for my app:

Sentry Web Vitals pages grouped as Pageload and Navigation

Everything is grouped as "Pageload" or "Navigation". My storefront uses hash routes such as #/books/2, so every transaction is named /, and the slow book page can't be picked out without custom transaction names.

Session replay: Sentry records, Raygun lists

Raygun's session page shows a visit as a list of pages and time on each:

Raygun RUM session timeline for one user

You can see where alice went and for how long, with an "Experience: Excellent" label, but you can't watch what she did.

Sentry records the session itself and writes a summary of it:

Sentry session replay with the AI summary

The summary lists four steps with time ranges, with the error steps in red, and they matched the session. All text is masked as asterisks by default, and the header counts dead clicks, rage clicks and errors.

The replay's Network tab lists every request the page made:

Sentry replay Network tab with the failed cover image request

The broken cover image shows here as an image request returning 404. It was the only place in either tool where that failure appeared.

Real user monitoring comparison

Capability Sentry Raygun
Core Web Vitals ✔: dashboard with a score ✔: charts per metric
Speed per page ✘: needs custom names for hash routes ✔: per virtual page
Speed per request Through traces ✔: requests table
Per-user view Through replays and issues ✔: Customers page
Video replay ✔: with an AI summary ✘: page timeline only
Replay network tab ✔: every request ✘: not offered
Broken image surfaced ✔: in the replay ✘: not seen

Verdict: Raygun for page speed, Sentry for replay. Raygun's tables named my slow pages and requests on day one. Sentry's replay showed what visitors did and caught a failure nothing else did.

Raygun had page speed without recordings, and Sentry had recordings while its Web Vitals lumped every hash route into /. I also ran the storefront through Better Stack, where each session came with a full replay and its event list side by side.

Better Stack session replay with its event list

Requests with their status codes, clicks, "added to cart" events with the book and quantity, and caught errors with full stacks run alongside the player. For page speed, I asked its RUM Insights box which route was slowest to load and why:

Better Stack AI SRE ranking routes by LCP

It ranked the hash routes by LCP without any custom naming, with /#/orders first at a p75 of 1948 ms, and traced the cause to a starved server behind them. It wasn't perfect: it missed the slow book page's waterfall, and the run cost $0.62.

Watch replays next to every request and error

Release tracking and regressions

Release tracking answers two questions: did this deploy introduce the problem, and has a fixed bug come back?

Sentry: Releases come from the SDK

Sentry reads the release name from the SDK's release value, monitoring-lab@1.1.0 in my case. Each version appeared as soon as it sent its first event, with no deploy step.

To set up the regression test, I resolved the coupon crash for the next release:

Sentry Resolve menu with release and commit options

Its choices are a single commit, another existing release, the current semver release or whichever release comes next. The banner then read "resolved starting with a release after 1.0.0".

Raygun: Deployments you register yourself

Raygun stamps each error with the SDK's version, but its deployment pages stay empty until something registers a deployment. The API needs the paid token, so I used the form:

Raygun Create deployment form

It asks for the version, deployment time, who deployed, an email address, a commit identifier and release notes.

The first save failed:

Raygun Create deployment returning a 500 error page

That attempt had a deployment time chosen through the date picker. The second save worked with only the version filled in.

The saved deployment then waited for traffic:

Raygun deployment page for 1.1.0 before traffic

It reads "1.1.0, Unknown", with New errors, Regressions, Still occurring and Commits tabs, all at zero.

Raygun's resolve menu has five choices:

Raygun resolve options

Resolve, Ignore, Permanently ignore, "Resolve in version…" and "Resolve in next version…" sit together.

The next-version dialog adds a checkbox Sentry doesn't have:

Raygun Resolve in next version dialog with the discard option

"Discard future occurrences until a newer version is released" is ticked by default, so late events from the old version stop counting once you resolve.

When the fixed bug came back

I shipped 1.1.0 with the coupon bug intact. In both tools, only the coupon crash reopened.

Sentry flags the comeback in the issue list:

Sentry list row for the coupon crash with the Regressed flag

"Regressed" sits under the trend graph, where the other rows show "New" or nothing, so you spot it while scanning.

The issue's activity feed has a small wording quirk:

Sentry activity feed recording the regression

It reads "Regressed in 1.1.0 compared with 1.1.0 based on SemVer", where you'd expect "compared with 1.0.0". The latest event came from an API user, so "A replay isn't available for this event" is expected.

The 1.1.0 release page collects regressions in their own tab:

Sentry release 1.1.0 with the Regressed tab

The tabs read All Issues 11, New 0, Unhandled 6, Regressed 1 and Resolved 0, and Regressed holds only the coupon crash.

Raygun's list row only went back to Active:

Raygun errors list after 1.1.0

The chart gained a deployments marker strip, while none of the rows carries a regressed label.

The reopen shows on the error itself:

Raygun coupon error with the version split and an Error reoccurred entry

The feed reads "Error reoccurred on Oct 23rd 6:24:38 am", and the version breakdown splits events 57% on 1.0.0 and 43% on 1.1.0.

Raygun's deployment page summarizes it per release:

Raygun deployment page with the coupon error under Regressions

The coupon error is marked "Resolved in 1.0.0" and active again. "Still occurring" listed 8 groups, which included leftovers from the APM side effect covered under performance.

The bad release

For 1.2.0, Raygun's deployment page listed five new errors:

Raygun deployment page for the bad release with five new errors

Only one bug is new. The five are the two payment groups plus three duplicates of old bugs. Sentry's count of three new groups for the same release had the same problem on a smaller scale.

Sentry linked a suspect commit to the payment error after I ran sentry-cli releases set-commits --auto:

Sentry payment error with the suspect commit and breadcrumbs

My repository has one commit, and the 1.2.0 behavior comes from a flag, so this suspect commit couldn't narrow anything down. The breadcrumbs did better, running from "slow query: SELECT book for checkout" through the gateway retry to the exception.

Release tracking comparison

Capability Sentry Raygun
Register a release ✔: automatic from the SDK Manual form on the trial, API on paid plans
Resolve for the next version ✔: plus named release or commit ✔: next version or named version
Discard old-version events ✘: not offered ✔: ticked by default
Regression label in the list ✔: Regressed ✘: row returns to Active
Regression in the error history ✔: activity feed ✔: "Error reoccurred"
Regressions per release ✔: Regressed tab ✔: Regressions tab
Suspect commits ✔: needs set-commits, useless with one commit ✘: not observed

Verdict: Sentry. Releases arrived without a manual step, and the regression showed in the list where you'd see it. Raygun's deployment pages are good once you feed them, and its discard option is useful, but feeding them on the trial was manual and fragile.

Raygun made me register every deployment through a form and still showed the returning coupon crash as plain Active, and both tools inflated the bad release's new-error count with duplicates. Better Stack, which I tested on the same releases, picked up each version from the SDK and marked the comeback with a red "Reoccurred" status on the row.

Better Stack error list showing the coupon crash as Reoccurred

The reopened bug stands out from everything else without opening it. On the bad release, the count stayed honest:

Better Stack releases with the 1.2.0 errors

The payment failure is one error with 10 exceptions across every amount, and the coupon crash stayed one error across all three releases. It has no separate Regressed tab like Sentry's, so the release page relies on that status label.

Spot returning bugs without registering deployments

Performance monitoring

A bad deploy doesn't always throw. Release 1.2.0 made checkout slow through a database query, and that slowdown is where the two tools split furthest apart.

Sentry: One trace found the query

Sentry's tracing measures each stage of a request, from the browser click to the database. One checkout trace from 1.2.0 was enough:

Sentry trace of a slow checkout after the bad release

Of the request's 2.26 s, the SELECT book for checkout query used 1.79 s. A "charge card" step that exists only in this version spent 459 ms before failing.

To rule out one unlucky request, I charted checkout time per release in Trace Explorer:

Sentry p95 checkout time by release

At the 95th percentile, checkout went from 3.63 ms on 1.1.0 to 5.93 s on 1.2.0, and the line jumps exactly at the deploy.

Sentry's profiling sent data too, but it wasn't the right tool here:

Sentry profiling with the slowest functions

The slowest functions, buildReport and withSpan, sit around 1 ms. The checkout slowdown comes from waiting, so a CPU profile wouldn't show it, and the profile link from a short checkout trace failed with "Failed to fetch profiles".

Raygun RUM: The bad release looked faster

Raygun has two places this slowdown could appear: RUM in the browser and APM on the server. RUM's release comparison gave the most surprising result of the test:

Raygun RUM Compare, 1.1.0 against 1.2.0

"1.2.0 is running 34.8% faster than 1.1.0 in median load time", with median page loads dropping from 28.9 ms to 18.85 ms. Full page loads didn't slow down, so the number is accurate for what it measures.

The slowdown was in the checkout request, which Compare doesn't cover. RUM's requests table did show /checkout averaging 438.95 ms over 143 requests, up from 199 ms after 1.0.0. That figure blends every version, and a link I tried for filtering by version didn't apply the filter.

Crash Reporting has no timing at all:

Raygun payment error page with a two-frame stack

The payment error shows its class, version 1.2.0, the user and server.js:173 called from server.js:163, with nothing about how long the request took.

Raygun APM: A second product with thin detail

I ran Raygun APM during release 1.0.0 only, for reasons covered below. It needs the raygun-apm profiler in your app plus the Raygun APM Agent beside it, which I ran in Docker.

On macOS, the profiler failed with EHOSTUNREACH 0.0.0.0:2799 until I set RAYGUN_AGENT_HOST=127.0.0.1. Raygun's Node.js setup page doesn't mention that setting.

Once it ran, the overview looked useful:

Raygun APM overview with Apdex and request speeds

It gave an Apdex of 0.94, a median request of 83 ms and a P99 of 4,754 ms, and ranked POST /checkout at 3,545 ms among the slowest. The Queries slice of the breakdown is 0 ms, because Raygun's Node.js APM doesn't support SQLite.

Not every request becomes a trace:

Raygun APM trace sampling settings

The default is "Sample 1 trace every 1 minute per URL", so my whole run produced a single checkout trace. You can raise the rate per URL.

The detail tables were mostly empty:

Raygun APM slowest tables with empty methods and queries

"Slowest methods" and "Slowest queries" have no rows. Raygun logged a single outbound call, its own error upload, and none of the app's requests to the price service.

A single trace was just as opaque:

Raygun APM flame chart for a slow price lookup

The 5,298 ms price request is mostly "(idle)" and "(garbage collector)" blocks, with no functions from my code. The profiler hooks Node's require, and my app uses ES modules, which likely explains it.

The call tree confirms it:

Raygun APM call tree with only Node internals

It lists parserOnHeadersComplete, 1,888 ms of garbage collection and 3,257 ms idle. The real cause, waiting on the slow price service, appears only as idle time.

Installing APM broke Crash Reporting

Once raygun-apm was installed, crashing errors started arriving in Crash Reporting as "Unknown error", with no message and no stack trace:

Raygun Crash Reporting showing Unknown error after installing raygun-apm

The coupon crash and the missing-book crash merged into this one empty group, and it kept happening with the profiler switched off.

Reading both packages' code explained it. When raygun-apm is installed, the Crash Reporting SDK loads a bridge from it that replaces JavaScript's built-in Error. Errors Node throws itself, such as TypeError, then fail the SDK's error check and get sent empty.

Uninstalling raygun-apm, or setting RAYGUN_APM_CRASH_REPORTING_INTEGRATION=false, fixed it. That's why APM was off for 1.1.0 and 1.2.0, and why it never saw the slow release. Even if it had, it couldn't read SQLite queries.

This happened with the versions I tested. It's worth checking before you install both packages in one Node.js app.

Performance comparison

Test Sentry Raygun
Slow checkout in one view ✔: trace showed the 1.79 s query ✘: not visible
Release comparison ✔: p95 by release RUM Compare called 1.2.0 34.8% faster
Request timing in the browser Through traces ✔: requests table, all versions blended
Server tracing setup Same SDK as errors Separate package and agent
Database queries ✔: SQLite spans ✘: SQLite not supported
App functions in traces ✔: handler and middleware spans ✘: Node internals only
Side effects None observed APM blanked native errors in Crash Reporting

Verdict: Sentry, decisively. Its tracing found the slow query in one view, from the same SDK that reports errors. Raygun's release comparison called the bad release faster, its APM couldn't see my database or my code, and installing it broke error reporting.

Tracing with Raygun meant a second package, an agent container and a host setting the docs left out, and Sentry's trace still sat one click away from the error. I also ran the bad release through Better Stack with the server's existing Sentry SDK. From the payment crash, "View spans" opened the failing checkout: 2.19 s overall, 1.53 s in the book query and 660 ms in the payment call.

Better Stack span list for one failing checkout, led by the slow query

The slow query and the new payment step both sit on the request that failed, so there's no hunting for a matching trace. "View logs" then narrowed Live tail to that same request:

Better Stack Live tail filtered to the failing request

The app's slow-query warning sits right above POST /checkout failed, so the timing and the app's own explanation arrive together. The Service column stayed empty, because the Sentry SDK doesn't set a service name.

See the spans and logs behind every error

Logs and events

Logs fill the gap between an error and a trace: what your app said while things went wrong.

Sentry: Logs from the same SDK

Sentry's logs arrived from the SDK I already had, 129 in the first hour:

Sentry logs explorer with a per-minute chart

The chart runs per minute, severity shows as a colored dot, and the report job's "sales report built" or "sales report failed" line appears once a minute.

The more useful part is where logs show up. Each trace has a Logs tab, as you saw under debugging, and each issue page has inline Logs and Application Metrics sections, such as browser.web_vital.lcp at 33.8 ms.

Raygun: No log product

Raygun has no general log store. Context comes from breadcrumbs, the Custom tab and RUM, so the slow-query warnings my app writes had nowhere to go. You'd need a separate logging tool to read them.

Logs comparison

Capability Sentry Raygun
Log storage ✔: logs explorer ✘: not offered
Logs on a trace ✔: Logs tab ✘: not offered
Logs on an issue ✔: inline section Breadcrumbs only
Metrics on an issue ✔: Application Metrics ✘: not observed

Verdict: Sentry. Its logs came with no extra setup and attached themselves to traces and issues. Raygun leaves logs to another vendor.

Uptime, status pages and alerts

This section has no result, since my tests covered neither tool's uptime checks, status pages or alert delivery.

The one alert setting I saw was Raygun's application form, which switches on new-error emails, a daily summary and a weekly RUM update by default. Sentry offers uptime monitoring, while Raygun showed me no product for uptime or status pages.

Capability Sentry Raygun
Uptime monitoring Not tested Not tested
Status pages Not tested Not tested
Default alerts Not tested New error, daily summary, weekly RUM
Alert delivery Not tested Not tested

Verdict: Not compared. Test both on your own endpoints before you count on either for availability.

AI-assisted debugging

This section isn't a head-to-head. Seer ran with my GitHub repository connected, and I didn't run either of Raygun's AI options, so everything about Raygun comes from its documentation.

Sentry Seer: Strong on code, weaker on performance data

Setting up Seer meant connecting the repository and accepting the AI terms:

Sentry Seer settings with one repository connected

One repository is connected, the agent is "Seer", and automation is set to "Stop after PR drafted".

On the coupon crash, Seer returned a root cause in about 15 seconds:

Seer root cause for the coupon crash

"The checkout handler accesses .discount on an unvalidated coupon lookup" is correct. It names line 150, notes that COUPONS only holds SAVE10 and HALFOFF, and cites the lines it read from the repository. It also assigned the issue to me.

Its plan matched what I'd do:

Seer plan for the coupon crash

It proposes a 400 response for unknown coupons, optional chaining on line 150 and removing the bug comment. I didn't click "Yes, write a code fix", because it can draft a pull request on the repository.

On the payment crash, it took about 20 seconds:

Seer root cause for the new payment error

It found the module-level paymentAttempts counter and the version gate that enables the failure on every fifth charge. It explains the error only and says nothing about the slow queries.

Then I asked Seer Agent, the chat assistant Sentry labels beta, what the bad release changed and why checkout dragged:

Seer Agent answer about the bad release

After 51.1 seconds, its numbers were right: p50 checkout up from 1.7 ms to 3.77 s, and p95 from 3.6 ms to 5.93 s. No cost was shown.

The explanation further down was wrong:

Seer Agent blaming the payment timeout for the slowdown

It says the slowdown "is driven by the upstream timeout on failed payment attempts". Sentry's own trace contradicts that, with the query at 1.79 s and the payment step at 459 ms.

I asked which spans got slower:

Seer Agent span table for checkout

The table is accurate, with the book query going from 0.1 ms to 2,640 ms. It still blamed payment retries for slowing the queries, which run before any payment code.

Raygun: Two options, neither tested

Raygun's docs describe AI Error Resolution, which sends a Crash Reporting error's stack trace and data to a model. You bring your own OpenAI or Azure OpenAI key, so the model bill is yours. Raygun's pricing page lists it on every Crash Reporting plan, but I didn't open it during my test.

Raygun also runs a remote MCP server at https://api.raygun.com/v3/mcp with OAuth sign-in. Outside assistants such as Claude Code, Cursor or Codex can use it to query errors, deployments, sessions and APM data. I skipped it.

AI comparison

Capability Sentry Raygun
Root cause on an error ✔: Seer, tested with the repository AI Error Resolution, not tested
Model credentials Sentry's Your OpenAI or Azure OpenAI key
Chat about releases ✔: Seer Agent, beta, tested ✘: not observed
MCP server Exists, not tested Exists, not tested
Accuracy on crashes Correct on both Not tested
Accuracy on the slowdown Right numbers, wrong cause Not tested

Verdict: Not compared. Seer was accurate on both crashes and misread the performance data, all with the code in hand. I can't rank it against an AI I didn't run.

Seer had my source code and still pinned the slowdown on the payment step, and Raygun's AI only runs once you plug in your own model key. I put the same question to Better Stack's AI SRE, which comes with the product and never saw my repository.

Better Stack AI SRE comparing 1.2.0 with 1.1.0

It found the book query's median jumping from 0.13 ms to 2.6 s while every other statement stayed near 0.1 ms, which ruled out the database server. It then separated the second cause:

Better Stack AI SRE explaining both causes of the broken version

The new "charge card" step failed on 10 of 48 calls, all on 1.2.0, and it tied each of those failures back to the new crash. It was slower than Seer at about four minutes and showed a $0.49 cost, but it was the only AI in my tests that got both causes right.

Let Better Stack AI SRE investigate your next bad deploy

Pricing

Sentry sells one product with usage-based add-ons, and Raygun sells Crash Reporting, RUM and APM as separate subscriptions.

These figures come from each vendor's pricing page on October 23, 2026. Prices change, so check them before you buy.

Free plans and trials

Feature Sentry Raygun
Free plan ✔: Developer, 1 user ✘: none
Free errors 5,000 Not applicable
Free replays 50 Not applicable
Free spans 5M Not applicable
Free logs 5 GB Not applicable
Trial 14-day Business trial 14 days on any plan
API tokens on the trial ✔: available ✘: Personal Access Tokens need a paid plan

Entry-level paid plans

Raygun prices each product separately, so the fair comparison is Sentry's Team plan against the Raygun products you'd need.

Feature Sentry Team Raygun Crash Reporting Basic Raygun RUM Basic Raygun APM Basic
Billed monthly $29 a month $60 a month $120 a month $120 a month
Billed annually $26 a month $40 a month $80 a month $80 a month
Included errors 50,000 100,000 Not applicable Not applicable
Included sessions or replays 50 replays 5,000 RUM sessions 100,000 sessions Not applicable
Included traces or spans 5M spans 5,000 APM traces Not applicable 100,000 traces
Included logs 5 GB ✘: not offered ✘: not offered ✘: not offered
Users Unlimited Unlimited Unlimited Unlimited
Error retention Not published 180 days Not published Not published

One step up, Sentry Business costs $89 a month, or $80 a month billed annually. Each Raygun Team plan doubles both the Basic price and its included volume.

What costs extra

Need Sentry Raygun
More errors Pay-as-you-go budget $0.001 per error
More replays or sessions Pay-as-you-go for replays $0.002 per RUM session
More tracing Pay-as-you-go for spans $0.002 per APM trace, plus an agent to run
More logs $0.50 per GB ✘: not offered
Video replay Pay-as-you-go ✘: not offered
Profiling From $0.25 per UI profiling hour Part of APM
AI Seer sold separately, price not listed Your own OpenAI or Azure OpenAI bill

Comparing the actual cost

For a small team, Sentry is much cheaper to start. It's free for one user, and $29 a month covers errors, tracing, replay and logs together.

Covering the same ground with Raygun's three Basic products costs $300 a month on monthly billing, or $200 a month billed annually. That still leaves you without logs or video replay, so you'd add a logging tool on top.

The gap narrows at high error volumes. Raygun's Crash Reporting Basic includes 100,000 errors, double Sentry Team's 50,000, with a flat $0.001 for each one over. If Crash Reporting is all you need, price your real monthly volume in both.

If you'd rather buy errors, logs, uptime checks and on-call from one vendor, our comparison for Sentry against an all-in-one platform and our matching one for Raygun cover that route.

Verdict: Sentry for most teams. Its free plan and $29 tier cover more than three Raygun products together. Raygun's included error volume makes more sense at scale, if Crash Reporting alone is enough.

Full feature comparison

This table combines everything I observed across the three releases.

Feature Sentry Raygun
Backend and browser in one place ✔: one project ✘: one application per part
Onboarding ✔: all products in one snippet One product at a time
Unhandled promise rejection in Node.js ✔: captured ✘: missed in my setup
Browser source maps ✔: CLI upload ✔: manual on the trial, API on paid plans
Backend source lines ✔: shown ✘: file and line only
Breadcrumbs ✔: browser and request-scoped backend ✔: browser and request-scoped backend
Browser-to-backend link ✔: one trace ✘: separate applications
Grouping in my test One issue per server bug, one browser merge, two duplicates Split by URL and amount, three duplicates
Page speed ✔: Web Vitals, hash routes need names ✔: per page and per request
Per-user view Through replays ✔: Customers page
Session replay ✔: video, AI summary, network tab ✘: page timeline only
Releases ✔: automatic from the SDK Manual deployments on the trial
Regression label in the list ✔: Regressed ✘: row returns to Active
Regressions per release ✔: Regressed tab ✔: Regressions tab
Discard old-version events ✘: not offered ✔: checkbox on resolve
Server tracing ✔: same SDK Separate APM package and agent
SQLite queries in traces ✔: shown ✘: not supported
Release performance comparison ✔: p95 by release RUM Compare, page loads only
Logs ✔: linked to traces and issues ✘: not offered
Uptime and status pages Not tested Not tested
AI root cause ✔: Seer, tested with the repository AI Error Resolution, not tested
MCP server Exists, not tested Exists, not tested
Free plan ✔: 1 user ✘: 14-day trial only

Which should you choose?

The choice depends on whether your problems cross the line between browser and server, or stay inside one of them.

Choose Sentry if your bugs cross from browser to server

Sentry fits when a broken button in the browser usually means a broken handler on the server. In my test, it was the only tool that linked a browser error to its backend cause, and the only one that found the query behind the slow release.

It did both from one SDK in one project, with logs and replays attached to the same issues. Releases registered themselves, and the regression showed in the list.

The trade-offs are smaller but real. Its Web Vitals pages needed custom names for my hash routes, its browser grouping merged a new failure into an old group, and replay volume costs more as you grow. Seer is strong on code and was wrong about the slowdown.

Our Sentry vs Honeybadger comparison shows how it fares against a tracker that bundles logs and uptime checks.

Choose Raygun if page speed is the main question

Raygun fits when you mostly want to know how fast your pages are for real visitors. Its RUM tables named my slow pages and requests on the first day, and the Customers page shows how often one person hits errors.

Its resolve dialog is also well thought out. Discarding old-version events after you resolve keeps late traffic from reopening a bug you've already fixed.

The trade-offs are larger. You'll run separate applications for each part of your app, the trial makes source maps and deployments manual, and grouping split bugs by URL and amount. On Node.js, test Raygun APM carefully: it couldn't read SQLite, showed none of my code, and blanked my error reports until I removed it.

Our Rollbar vs Raygun comparison puts it against another tracker that keeps errors and replay together.

Final thoughts

The real decision is how many tools you'll open to explain one bad deploy. Raygun gave me three products that each saw a slice: Crash Reporting saw the payment error, RUM saw faster pages, and APM couldn't run beside Crash Reporting at all. Sentry put the error, the trace and the replay on pages that link to each other.

Raygun's page-speed tables are worth having if front-end speed is your main worry. Just don't let its release comparison be the only thing that signs off a deploy.

My worst release shipped with a query that took 1.79 seconds on every checkout, and Raygun called it 34.8% faster.