# Bugsnag vs Raygun: A Hands-On Error Tracking Comparison for 2026

Ask BugSnag and Raygun whether your last release made things worse, and you get two very different kinds of answer. BugSnag gives the version a stability score built from the sessions it counted. Raygun gives the deployment its own page, with tabs for new errors and regressions, and it can also time your pages and your server through products you buy separately.

**BugSnag is an error and stability monitor** from SmartBear. It counts sessions for every app version, turns crashes into a crash-free percentage, and leaves performance tracing to OpenTelemetry.

**Raygun is a suite of three monitoring products** that you set up and pay for one by one: Crash Reporting for errors, Real User Monitoring for the browser, and APM for the server.

[ad-logs]

That difference decides which teams each tool suits. In my test, BugSnag had the richer error pages and caught every server failure, including a promise rejection that Raygun never reported. Raygun reached further, into page speed, browser sessions and server timing, and its deployment page named the bug I'd shipped again. It also had more setup friction than any tool in this series, including a performance package that quietly wiped the messages off my errors.

The coverage isn't equal, and you should know that before reading the verdicts. BugSnag ran on the server through two releases. Raygun ran on the server and in the browser through three. Where only one tool was tested, the section says so, and the verdict sticks to what both tools did.

Below, you'll find how they compare on setup, error capture, debugging, grouping, releases and regressions, browser monitoring, performance, logs and alerts, AI and pricing.

## BugSnag vs Raygun: Results at a glance

The verdicts reflect my Node.js test app as I configured it in October 2026. With another stack or other SDK versions, a few verdicts might flip.

| Area | Better in my test | Why |
|---|---|---|
| Setup | **BugSnag** | One wizard and one project; Raygun needs an application per part of the app and one product at a time |
| Server error capture | **BugSnag** | Caught all six server bugs; Raygun missed an unhandled promise rejection |
| Debugging an error | **BugSnag** | User, metadata and correlated events in separate tabs; neither showed server source lines |
| Error grouping | Tie | Both kept six server bugs apart at release 1.0.0 |
| Releases and regressions | **Raygun** | A Regressions tab on each deployment; BugSnag reopened the bug but didn't list it as a regression |
| Release health | **BugSnag** | A crash-free score per version straight from the SDK |
| Browser errors and RUM | Raygun only | BugSnag's browser SDK wasn't part of my test |
| Server performance | Neither | BugSnag needs OpenTelemetry; Raygun's APM saw no app code and broke error reports |
| Logs and alerts | Not compared | Neither has logs, and I didn't test alert delivery |
| AI-assisted debugging | Not compared | Neither tool's AI was run in my test |
| Price | Mixed | BugSnag has a free plan; Raygun publishes every price |

## How I tested BugSnag and Raygun

My test app, `monitoring-lab`, is a small online bookstore. An Express API keeps its data in SQLite, calls a price service that fails on purpose, and runs a sales report job in the background. A Vite storefront talks to the API. Each monitoring tool connects through its own adapter file, so the app's code stays the same for every tool.

The app produces these failures:

- **Server crashes:** a `TypeError` for an unknown coupon code, called the coupon bug below, and another for a missing book.
- **Handled server errors:** out-of-stock checkouts and 503s from the price service, reported by the app itself.
- **An unhandled promise rejection:** a recommendation call that rejects with no `catch`.
- **Job failures:** the sales report fails on some runs.
- **Browser failures:** a wishlist `TypeError` and failed API calls, on the storefront only.

### The releases I shipped

| Release | What I tested |
|---|---|
| 1.0.0 | Setup, capture, error detail and grouping |
| 1.1.0 | The coupon bug marked fixed in each tool, then shipped again |
| 1.2.0 | Raygun only: checkout slows down and a payment error appears |

Release 1.1.0 is the test most teams care about: does the tool notice when a fix doesn't hold? Release 1.2.0 asks whether a tool can tell a slow deploy from a broken one.

### SDKs and test limitations

| Tool | Packages in the app |
|---|---|
| BugSnag | Server only: `@bugsnag/plugin-express` on top of `@bugsnag/js` |
| Raygun | Server: `raygun` 2.2.10. Browser: `raygun4js` 3.1.4. Performance: `raygun-apm` 2.3.0 and the APM agent |

These conditions shape the results:

- **BugSnag ran on the server through 1.0.0 and 1.1.0,** on October 21, with an earlier build of the app that had no storefront. Its browser SDK, OpenTelemetry-based performance and AI workflow stayed outside the test.
- **Raygun ran on both sides through all three releases,** on October 23, with Crash Reporting, Real User Monitoring and APM on a 14-day trial.
- **Event counts come from separate runs,** so compare behavior and leave the totals aside.
- **Results that only one tool produced don't count against the other.** I label those sections and rows.
- I didn't test alert delivery or the AI features in either tool.

## Setting up both tools

Setup decides how much of your app you can watch on day one. On the server, both tools took a few lines. Past that, their designs pulled apart.

### BugSnag: Pick a platform, add two middlewares

The onboarding has four steps, ending in Integrate BugSnag. It opens by asking where your application runs, from mobile and browser to server, desktop, TV and console, then narrows to a platform. I picked Express.

The integration step shows the npm install and `Bugsnag.start` with the API key. Its request handler goes in front of your routes and its error handler behind them. Sessions arrived without any code from me, since the Express plugin records a session for each request. That's where the release scores you'll see later come from.

BugSnag's overview opened on those numbers:

![BugSnag overview with session stability for release 1.0.0](https://imagedelivery.net/xZXo0QFi-1_4Zimer-T0XQ/ba5d0dbb-dcb4-4570-3667-04043b1a7800/md2x =1126x737)

Release 1.0.0 shows a session stability of 83.103% across 290 sessions, labelled "Critical stability". Two performance monitors show as Alerting by default, even though the app sent no performance data at all.

### Raygun: One application per part of your app

Raygun asks you to create an application first:

![Raygun onboarding step to create the first application](https://imagedelivery.net/xZXo0QFi-1_4Zimer-T0XQ/bc2ac788-e5d6-4c0d-f087-e6fe875fd400/orig =3024x2044)

Each application monitors one part of the app, such as the frontend, the backend or a mobile app, with its own API key and error list. I needed two: `monitoring-lab-api` for Node.js and `monitoring-lab-web` for the browser. The wizard also handles a single product per language in each pass, and its last step waits for a first event before letting you leave:

![Raygun onboarding waiting for Real User Monitoring data](https://imagedelivery.net/xZXo0QFi-1_4Zimer-T0XQ/01c590dd-4711-4492-cc05-f47bfbd18b00/orig =2244x1388)

Errors had arrived, so Crash Reporting is ticked, but the RUM side hasn't seen a page view yet. Three more things slowed me down:

- **The npm build of `raygun4js` didn't start in a lazily loaded module.** It reads its config at the page's load event, so a module imported later never sent anything. Queuing calls the way the CDN snippet does fixed it.
- **Source map and deployment uploads by API need a Personal Access Token,** which is paid-only. On the trial, I uploaded maps by hand after every build.
- **APM needs a separate agent** running next to your app, covered in the performance section.

### Setup comparison

| Step | BugSnag | Raygun |
|---|---|---|
| Server install | ✔: npm package and two middlewares | ✔: npm package |
| Browser install | Not tested | ✔: npm or CDN snippet, with a load-timing catch |
| Projects needed | One per app | One application per part of the app |
| Sessions or releases from the SDK | ✔: sessions per request, version from `appVersion` | ✔: version from `setVersion` |
| API automation on the trial | Not tested | ✘: needs a paid token |

**Verdict: BugSnag.** Its server setup was as short as Raygun's and gave me release health for free. Raygun's split into applications and products makes sense for large apps, but it turns a small app into several setups.

## Catching server errors

Capture is the baseline: an error tracker that misses a crash can't help you fix it. Both tools received the same six server failures.

### BugSnag: Six bugs, six errors, with crashes marked

After release 1.0.0, BugSnag's inbox held six errors:

![BugSnag inbox with six errors after release 1.0.0](https://imagedelivery.net/xZXo0QFi-1_4Zimer-T0XQ/41cb6591-5e64-46cd-5750-81874b813100/orig =1126x737)

Every bug got its own row, including the two TypeErrors that fail in almost the same way. Each row carries a handled or unhandled badge, so crashes stand apart from errors the app reported itself. The sidebar sorts the inbox into views such as Introduced Today, For review and Snoozed.

The unhandled promise rejection arrived too:

![BugSnag unhandled promise rejection with one stack frame](https://imagedelivery.net/xZXo0QFi-1_4Zimer-T0XQ/d30fd5b8-6f32-4a4b-eeef-025fea087200/lg2x =1126x737)

It's marked unhandled with a single frame, `loadRecommendations`, which is all the context Node.js gives a rejection with no `catch`.

### Raygun: Five of six on the server

Raygun's API application showed five error groups:

![Raygun error groups for the API application](https://imagedelivery.net/xZXo0QFi-1_4Zimer-T0XQ/177ba59c-5e8d-4c7c-f78e-3b8598bedf00/lg1x =1512x744)

The coupon and book TypeErrors, the out-of-stock error, the 503 and the sales report each have a group. "Recommendation engine timed out", the unhandled rejection, never appeared, although `reportUncaughtExceptions` was on. That doesn't prove Raygun can't catch rejections in Node.js, only that this integration didn't.

Browser errors went to the separate web application, which you'll see in the browser section.

### Server capture comparison

| Test | BugSnag | Raygun |
|---|---|---|
| Coupon and book TypeErrors | ✔: separate errors | ✔: separate groups |
| Handled errors | ✔: caught, marked handled | ✔: caught |
| Unhandled promise rejection | ✔: caught | ✘: missed in my setup |
| Job failure | ✔: caught | ✔: caught |
| Handled and unhandled marked on rows | ✔: badge per row | ✘: no badge seen |
| Server and browser in one list | Not tested | ✘: separate applications |

**Verdict: BugSnag.** It caught every server failure and labelled crashes on each row. Raygun's missed rejection is a reason to test that path before you rely on it.

[summary]
<iframe width="100%" class="aspect-video h-auto" src="https://www.youtube.com/embed/-26mmryojE4" title="Error tracking | Better Stack" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

BugSnag and Raygun both caught the server crashes, and neither showed a single line of the code around them, as you'll see in the next section. I ran the same server bugs through Better Stack, and its stack trace opened on the source itself:

![Better Stack coupon error with the source line highlighted](https://imagedelivery.net/xZXo0QFi-1_4Zimer-T0XQ/7ca5550a-dddc-4a42-e1ff-3e3a0d688c00/lg2x =1126x737)

The failing line sits highlighted among its neighbors, so you can read the bug without opening your editor. Better Stack also kept the six bugs in six groups, so you get BugSnag's clean capture and the code view together.

**[Read the failing line on the error page](https://betterstack.com/error-tracking)**
[/summary]

## Debugging an error

Once an error is caught, what matters is how quickly its page tells you who hit it, what they did and where it broke.

### BugSnag: The whole visit around one error

Each BugSnag event is split into tabs, from the stack trace and breadcrumbs to the device, request and user, with Correlated events and your own metadata alongside. The stack trace itself was thin:

![BugSnag stack trace with frames and no source lines](https://imagedelivery.net/xZXo0QFi-1_4Zimer-T0XQ/51d3864a-f024-4746-a122-8797d3e65100/lg1x =1126x737)

You get the file and line, `server.js:38:45`, then the router frames, with no code shown. The breadcrumbs had more to offer:

![BugSnag breadcrumbs timeline for the coupon error](https://imagedelivery.net/xZXo0QFi-1_4Zimer-T0XQ/13456096-d09f-4176-0a2b-02af9c17f900/md1x =1126x737)

The timeline has a type filter and search, and it shows the app's own "book found" breadcrumb with the book's ID, title and stock. The tab I'd miss most in other tools is Correlated events:

![BugSnag Correlated events tab for one shopper](https://imagedelivery.net/xZXo0QFi-1_4Zimer-T0XQ/ca3c6329-5b8f-476b-6f1d-66f45743e700/orig =1126x737)

Here, carol's coupon crash sits beside the out-of-stock errors she hit in that same session, so you can see the rest of a bad visit from one page. Handled errors kept the metadata my app attached, such as the book ID and quantity, in a Details tab.

### Raygun: Request breadcrumbs and an error page per group

Raygun's error page leads with totals, affected users, first and last seen, and an occurrence chart:

![Raygun API error page with instances and affected users](https://imagedelivery.net/xZXo0QFi-1_4Zimer-T0XQ/35514061-ff55-48e0-8f4a-cfc1e0ff3a00/lg1x =1512x744)

Tabs cover the summary, error details, HTTP, environment, custom data, breadcrumbs and the raw payload, and the affected-users count links to Raygun's Customers page. The server breadcrumbs stayed scoped to the request:

![Raygun breadcrumbs for one checkout request](https://imagedelivery.net/xZXo0QFi-1_4Zimer-T0XQ/e0321b8b-1aba-4083-a4c0-2f62f7065400/md2x =1512x744)

You see the POST /checkout request, "checkout started" and "book found", with no events from other shoppers mixed in. Like BugSnag's, the server stack trace showed a file and line, `server.js:150`, with "1 framework frame" and no source lines.

### Debugging comparison

| Capability | BugSnag | Raygun |
|---|---|---|
| Server source lines | ✘: frames only | ✘: frames only |
| Breadcrumbs | ✔: with filter and search | ✔: scoped to the request |
| User on the event | ✔: own tab | ✔: linked to Customers |
| Other events from the same session | ✔: Correlated events | ✘: not offered |
| Custom metadata | ✔: Details tab | ✔: Custom tab |
| Raw payload | ✔: Raw view on the stack trace | ✔: Raw data tab |

**Verdict: BugSnag.** Both pages were well organized, and both left out the server's code. BugSnag's Correlated events tab adds context Raygun's page doesn't have.

## Error grouping

Grouping decides whether your error count means anything. Too loose and two bugs share a row, too strict and one bug fills the list.

### Both kept six server bugs apart

At release 1.0.0, BugSnag and Raygun each gave the six server bugs their own rows, including the two TypeErrors from almost the same line. BugSnag labels each error with its grouping rule, "Default grouping", and its project settings also offer grouping by error class or by error context:

![BugSnag project settings with grouping and integration options](https://imagedelivery.net/xZXo0QFi-1_4Zimer-T0XQ/8d275c28-b762-4073-fb80-f5d822cfdb00/lg2x =1126x737)

The same page lists the integrations, and "Mark errors as fixed after each release" sits there switched off by default.

### Raygun: Where messages and URLs split a bug

Raygun's Node.js grouping takes the message text into account, and that showed on two later tests that BugSnag didn't run. In the browser, failed book loads split by URL:

![Raygun browser error groups split by URL](https://imagedelivery.net/xZXo0QFi-1_4Zimer-T0XQ/56902b55-07c6-47d2-01f1-e7b3399f2a00/public =1512x744)

The same ApiError appears as separate groups for `/books/0`, `/404`, `/99` and `/1234`, while the order-tracking 404 stayed in one group despite changing IDs. On release 1.2.0, the new payment error split by the charge amount in its message into two groups that share one class and one stack. The code changes in 1.2.0 also opened second groups for two old server bugs.

### Grouping comparison

| Test | BugSnag | Raygun |
|---|---|---|
| Six server bugs at 1.0.0 | ✔: six errors | ✔: five groups, the rejection missed |
| Grouping options | ✔: default, by class or by context | Not tested |
| Same error, different URLs | Not tested | ✘: split by URL in the browser |
| Same error, different amounts | Not tested | ✘: split by message |
| Old bugs after a code change | Not tested | ✘: duplicate groups |

**Verdict: Tie.** Both grouped correctly on the release they shared. Raygun's splits come from tests BugSnag didn't run, so read them as a reason to check Raygun's grouping on errors with variable messages.

## Releases and regressions

After you ship a fix, you want to know whether it held. BugSnag and Raygun both tie a fix to a version, which not every error tracker does. Before 1.1.0, I marked the coupon bug fixed in each tool and shipped it unchanged.

### BugSnag: Fixed until a new version, and a score for every release

BugSnag's Mark as fixed holds until the error shows up in a newer version. When 1.1.0 traffic arrived, the coupon error reopened and its activity said why:

![BugSnag activity showing the error reopened in 1.1.0](https://imagedelivery.net/xZXo0QFi-1_4Zimer-T0XQ/5f0672ec-21d4-4845-a942-338f1cb6f000/lg2x =1126x737)

The newest entry says BugSnag reopened it because it occurred in 1.1.0, and below it sits my fix with its condition: valid until the error appears in a newer version. Nothing else changed status. The inbox told a quieter story:

![BugSnag inbox after release 1.1.0](https://imagedelivery.net/xZXo0QFi-1_4Zimer-T0XQ/19001b1f-a263-4d2f-e34c-37d2f7c9f400/orig =1126x737)

The reopened coupon row looks like every other open error, with no regressed badge, so you'd only spot it by opening the error. Where BugSnag shines is the releases page:

![BugSnag releases page with stability for 1.0.0 and 1.1.0](https://imagedelivery.net/xZXo0QFi-1_4Zimer-T0XQ/7950f4f0-2e49-480d-d43e-9b33d86c6500/lg2x =1126x737)

Each version gets a session stability score, 83.103% for 1.0.0 and 83.893% for 1.1.0, from the SDK's `appVersion` alone, with no deploy call. The 1.1.0 release page splits errors into "Errors seen" and "Errors introduced", and "Errors introduced" was correctly empty. It doesn't single out the bug that came back.

### Raygun: A deployment page that names the regression

Raygun offers "Resolve in next version", with a checkbox BugSnag doesn't have:

![Raygun Resolve in next version dialog](https://imagedelivery.net/xZXo0QFi-1_4Zimer-T0XQ/c8fb7442-3eef-442a-e848-b8ee10252900/lg1x =1512x800)

The dialog's discard checkbox is ticked by default. It drops repeats from 1.0.0 until a newer version ships, so they stop counting against your quota. After 1.1.0, the coupon group was Active again, and its activity read "Error reoccurred". The list row just said Active, the same quiet treatment as BugSnag's inbox.

The deployment page made up for it:

![Raygun deployment 1.1.0 with one regression](https://imagedelivery.net/xZXo0QFi-1_4Zimer-T0XQ/1eec3e22-6d7f-4c1e-546f-ecf853d63600/lg2x =1512x744)

The Regressions tab holds exactly one group, the coupon TypeError, marked resolved in 1.0.0 and now Active. That's the answer to "did my fix hold?" in one click.

Deployments take more work than BugSnag's releases. Without the paid token, I created each one by hand, and the first save failed with a Raygun 500 page until I left every field except Version empty.

### Releases comparison

| Capability | BugSnag | Raygun |
|---|---|---|
| Version from the SDK | ✔: `appVersion` | ✔: `setVersion` |
| Fix tied to a version | ✔: until a new version | ✔: next version, or a chosen version |
| Returning bug reopens | ✔: with the reason logged | ✔: "Error reoccurred" in activity |
| Regression label in the list | ✘: none | ✘: none |
| Regressions listed per release | ✘: not listed | ✔: Regressions tab |
| Release health score | ✔: session stability | ✘: not offered in Crash Reporting |
| Deployments | ✔: not needed | Manual or API with a paid token |

**Verdict: Raygun for regressions, BugSnag for release health.** Raygun's Regressions tab names a broken fix outright. BugSnag gives you a stability score per version without any deploy step, which is the better signal for a release with many small problems.

[summary]
<iframe width="100%" class="aspect-video h-auto" src="https://www.youtube.com/embed/E8JQPRVR20E" title="On-call Overview | Better Stack" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

Both tools reopened the coupon bug and then showed it in their lists as one more open row. In Better Stack, the same comeback changed the row's status:

![Better Stack errors list with the coupon bug marked Reoccurred](https://imagedelivery.net/xZXo0QFi-1_4Zimer-T0XQ/a4c8af6b-7733-40f5-93ac-a059feb27800/md1x =1512x744)

Only the returning error swapped its "Unresolved" status for a red "Reoccurred", so you spot a failed fix while scanning the list. You don't need a deployment page or an activity feed to find it, and you don't need to create deployments by hand.

**[See failed fixes in your error list](https://betterstack.com/error-tracking)**
[/summary]

## Browser errors and real user monitoring

Browser monitoring shows what your users run into: script crashes, failed requests and slow pages. Raygun covers it with Crash Reporting in the browser plus its Real User Monitoring product. I didn't run BugSnag's browser SDK, so this section is Raygun only.

### Raygun: Source maps that work, after a manual upload

The storefront's wishlist crash arrived minified until I uploaded source maps. On the trial, that meant the JS Source Map Center, where uploads by API point to a paid token:

![Raygun JS Source Map Center with the paid-token note for API uploads](https://imagedelivery.net/xZXo0QFi-1_4Zimer-T0XQ/99190265-e574-41f6-598a-bb7f74c39b00/md2x =1512x800)

Each uploaded file needs an absolute URL label typed in by hand, and the file names change on every build. Once labelled, "Re-process this error for Source Maps" worked immediately:

![Raygun browser error mapped to pages.js line 122](https://imagedelivery.net/xZXo0QFi-1_4Zimer-T0XQ/133efeeb-7f19-4d49-a11d-bdda02fd0e00/lg1x =1512x744)

The frame reads `../../src/pages.js:122`, with the surrounding lines and my deliberate-bug comment. Browser breadcrumbs were automatic, with clicks, hash changes and every request opening and finishing.

### Raygun: Page speed with no extra code

Real User Monitoring started measuring as soon as the browser script loaded:

![Raygun RUM performance charts](https://imagedelivery.net/xZXo0QFi-1_4Zimer-T0XQ/b5ebd5de-809c-40fd-3bb8-774d60f0ee00/lg2x =1512x744)

Load time sits next to the Core Web Vitals, including LCP, CLS and INP, plus first paint, FCP and FID. The virtual pages table broke that down by route, such as `/books/*` at 1.58 s and `/checkout` at 1.76 s, and a requests table timed the API calls. The Customers page joins sessions and errors per user:

![Raygun Customers page with sessions and errors per user](https://imagedelivery.net/xZXo0QFi-1_4Zimer-T0XQ/e0763b19-bfcc-437e-8529-559f49e93900/md1x =1512x744)

alice had 10 sessions and 5 errors, and a session opens as a timeline of her page views and time on each page. It's a timeline, with no video replay.

What Raygun couldn't do was connect a browser error to the server error behind it. The two live in separate applications, with no tracing between them.

### BugSnag: Not tested

BugSnag has a browser SDK, and its performance page lists Page Loads, which come through OpenTelemetry. BugSnag doesn't list session replay among its features. I didn't test any of that, so I can't compare it with Raygun's RUM.

### Browser monitoring comparison

| Capability | BugSnag | Raygun |
|---|---|---|
| Browser errors | Not tested | ✔: separate application |
| Source maps | Not tested | ✔: manual upload on the trial |
| Automatic breadcrumbs | Not tested | ✔: clicks, navigation, requests |
| Web Vitals | Needs OpenTelemetry, not tested | ✔: out of the box |
| Speed by route | Not tested | ✔: virtual pages |
| Per-user view | Not tested | ✔: Customers |
| Session replay | ✘: not listed | ✘: timeline only |
| Browser error linked to server error | Not tested | ✘: separate applications |

**Verdict: Raygun, on what I could test.** Its RUM worked with no extra code and covered more than error tracking alone. BugSnag's browser side needs its own test.

[summary]
<iframe width="100%" class="aspect-video h-auto" src="https://www.youtube.com/embed/7tQ7haFmSXI" title="Explore Traces | Better Stack" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

Raygun timed the storefront well, but its browser and server errors sat in separate applications with nothing joining them. Better Stack kept both halves of a visit on one timeline:

![Better Stack session timeline with browser and server spans](https://imagedelivery.net/xZXo0QFi-1_4Zimer-T0XQ/719b53e1-6b61-4f23-7134-6ae81a884200/md1x =1512x744)

The visit has 30 browser spans followed by the 7 server spans they triggered, so a slow click and the API work behind it read together. One SDK setup covered it, with no second application or product to buy.

**[Follow a click into your API](https://betterstack.com/tracing)**
[/summary]

## Server performance

Release 1.2.0 made checkout slow, and the slow part threw nothing. Only a tool that measures server requests would notice.

### BugSnag: Performance through OpenTelemetry

BugSnag's performance product reads OpenTelemetry data, and its SDK doesn't send any by itself:

![BugSnag performance page asking for the OpenTelemetry SDK](https://imagedelivery.net/xZXo0QFi-1_4Zimer-T0XQ/309143e2-6849-4eea-07dd-5e65c1586600/lg2x =935x737)

Page Loads, Inbound Requests, Outbound Requests and Custom Spans stay empty until you install OpenTelemetry. If your services already run OpenTelemetry, that's a plus. If they don't, it's a second rollout.

### Raygun: A separate agent, and a side effect

Raygun's APM for Node.js needs the `raygun-apm` package and the Raygun APM agent, which ran here as a Docker container. On my Mac, the profiler couldn't reach the agent, because it sends to `0.0.0.0` by default. Pointing `RAYGUN_AGENT_HOST` at `127.0.0.1` fixed it, and Raygun's Node.js setup page doesn't mention that variable.

The overview did fill in:

![Raygun APM overview with Apdex and request speeds](https://imagedelivery.net/xZXo0QFi-1_4Zimer-T0XQ/cb6735fc-87bd-4789-afe8-3e237f58c200/md2x =1512x800)

It reported an Apdex of 0.94, a median of 83 ms and a 99th percentile of 4,754 ms. Queries per minute stays at 0, because the profiler doesn't support SQLite. The traces didn't explain much:

![Raygun APM flame chart for a slow price request](https://imagedelivery.net/xZXo0QFi-1_4Zimer-T0XQ/95169f4a-b221-4c97-d9f3-92f221144900/orig =1512x800)

The 5.3-second request breaks down into garbage collection and idle time, and none of my functions appear. The wait on the price service shows as idle, and the app's calls to it weren't recorded as external calls. By default, Raygun also keeps only one trace per URL per minute.

The bigger problem was what the package did to error reports:

![Raygun errors arriving as Unknown error after installing APM](https://imagedelivery.net/xZXo0QFi-1_4Zimer-T0XQ/44ed786c-b5a5-41dd-c08d-e753fc28f500/lg1x =1512x800)

**With `raygun-apm` installed, every native JavaScript error arrived as "Unknown error"** with an empty message and stack, even with the profiler off. The Crash Reporting SDK loads a bridge from the APM package that replaces `global.Error`, so a native `TypeError` no longer passes `instanceof Error`. To fix it, remove the package or turn the bridge off with `RAYGUN_APM_CRASH_REPORTING_INTEGRATION=false`. Because of this, the 1.2.0 run had no APM data.

For 1.2.0, Raygun's RUM comparison called the release 34.8% faster than 1.1.0 by median load time. It compares full page loads, and the slowdown was in the checkout request, which that view doesn't cover.

### Performance comparison

| Capability | BugSnag | Raygun |
|---|---|---|
| Server timing out of the box | ✘: needs OpenTelemetry | ✘: needs the APM agent |
| App functions in traces | Not tested | ✘: none seen with ES modules |
| Database queries | Not tested | ✘: SQLite not supported |
| Effect on error reports | None | ✘: emptied native errors until disabled |
| Slow 1.2.0 checkout found | Not tested | ✘: missed |

**Verdict: Neither.** BugSnag hands performance to OpenTelemetry, and Raygun's APM saw none of my code and damaged its own error reports. Plan on extra work with either one.

[summary]
<iframe width="100%" class="aspect-video h-auto" src="https://www.youtube.com/embed/XJv7ON314k4" title="Live Tail Overview | Better Stack" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

BugSnag needed OpenTelemetry before it would time anything, and Raygun's agent missed the slow checkout entirely. Better Stack traced the same 1.2.0 release from its SDK alone, and the failing payment opened into its spans:

![Better Stack spans for a failing checkout on release 1.2.0](https://imagedelivery.net/xZXo0QFi-1_4Zimer-T0XQ/6e59bd17-1ba1-432a-9a2e-6686c91c5700/lg2x =1512x744)

The book query took 1.53 s of the 2.19-second request, and the failed charge took 660 ms, so the slowdown and the new error separate at a glance. From there, the request's logs showed the app's own slow-query warning just before the failure. There was no agent to run, and my error reports stayed intact.

**[Trace a slow release down to the query](https://betterstack.com/tracing)**
[/summary]

## Logs and alerts

Neither BugSnag nor Raygun stores application logs, so you'd pair either one with a log tool. Alerting is where they differ.

### BugSnag: Integrations and conditional snoozing

BugSnag sends email and connects to Slack, Datadog, Jira, Trello, PagerDuty, webhooks and Splunk from the settings page you saw earlier. Its snooze menu goes further than most:

![BugSnag snooze options](https://imagedelivery.net/xZXo0QFi-1_4Zimer-T0XQ/6c865473-2d86-419a-2527-a99c34dc7000/public =1126x737)

You can snooze until an error "occurs again", occurs again after a while, reaches a count, or "impacts an additional" number of users. That last one lets you park a noisy error until it starts to spread.

### Raygun: Notification defaults on every application

Each new Raygun application comes with its own notification settings:

![Raygun Create application form with notification defaults](https://imagedelivery.net/xZXo0QFi-1_4Zimer-T0XQ/7730796e-3b56-4056-25b4-65cdc95d2f00/public =2238x1566)

By default, you get an email for each new error, a daily digest and a weekly RUM report, while APM alerts start switched off. Raygun's triage options are Resolve, Ignore, Permanently ignore and the two version-based resolves.

| Capability | BugSnag | Raygun |
|---|---|---|
| Application logs | ✘: not offered | ✘: not offered |
| Email notifications | ✔: yes | ✔: on by default |
| Chat and incident tools | ✔: Slack, PagerDuty and more | Not tested |
| Conditional snooze | ✔: by recurrence, count or users | ✘: ignore or permanently ignore |
| Alert delivery tested | ✘: no | ✘: no |

**Verdict: Not compared.** I didn't fire alerts in either tool. BugSnag's snooze conditions are the stronger triage feature I saw.

## AI-assisted debugging

BugSnag sends AI work to an outside assistant, and Raygun offers AI suggestions on the error page plus an MCP server. I didn't run either one, so treat this as a feature list.

- **BugSnag:** "Fix with MCP" on each error sends you to install the SmartBear MCP Server, which lets an outside coding assistant read your errors. I cancelled at that step.
- **Raygun:** its pricing page lists AI Error Resolution in Crash Reporting on all tiers, for root-cause and fix suggestions. It also runs a remote MCP server that coding assistants can connect to for errors, deployments, sessions and APM data.

Here's the step where BugSnag hands you off:

![BugSnag Fix with MCP prompt to install the MCP server](https://imagedelivery.net/xZXo0QFi-1_4Zimer-T0XQ/6b9f4b38-5469-4df9-884c-569311142e00/lg2x =1126x737)

The prompt notes that you haven't used the MCP server on this project yet, so the AI work happens in your editor, with your own assistant.

| Capability | BugSnag | Raygun |
|---|---|---|
| In-app AI analysis | ✘: not offered | AI Error Resolution, not tested |
| MCP server | ✔: SmartBear MCP Server, not tested | ✔: remote MCP server, not tested |

**Verdict: Not compared.** Both lean on outside assistants, and I tested neither.

[summary]
<iframe width="100%" class="aspect-video h-auto" src="https://www.youtube.com/embed/n6TtDk8ITgc" title="AI SRE Demo | Better Stack" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

BugSnag and Raygun both send you to an outside assistant through MCP. Better Stack's AI SRE runs inside the product, and I asked it what went wrong in release 1.2.0 with no access to my repository:

![Better Stack AI SRE comparing release 1.2.0 with 1.1.0](https://imagedelivery.net/xZXo0QFi-1_4Zimer-T0XQ/156c28b3-08a9-4423-a025-fac33aa2c700/public =1512x744)

Its first finding was that the book lookup was the one statement that got slower, which ruled out the database as a whole. It then tied all 10 failed card charges, out of 48, to the new payment error on 1.2.0. Both causes were right, after roughly four minutes and $0.49 of usage.

**[Ask AI SRE what changed in a release](https://betterstack.com/ai-sre)**
[/summary]

## Pricing

BugSnag prices error events and spans on a volume slider. Raygun bills each of its three products as its own subscription. I read both pricing pages on October 30, 2026, and prices move, so check them again before buying.

### Free plans and trials

| Feature | BugSnag | Raygun |
|---|---|---|
| Permanent free plan | ✔: Free | ✘: none listed |
| Free-plan users | 1 | No free plan |
| Free-plan errors a month | 7,500 events | No free plan |
| Free-plan spans | 1M, needs OpenTelemetry | No free plan |
| Free-plan retention | 7 days | No free plan |
| Trial | 14 days, no card | 14 days, no card |

BugSnag's trial ran its error and performance plans side by side:

![BugSnag plans page during the trial](https://imagedelivery.net/xZXo0QFi-1_4Zimer-T0XQ/0ba55dd6-6979-45e2-234c-1b12c6094e00/md2x =1126x737)

The two are billed as separate plans, which matters once the trial ends.

### Entry-level paid plans

The last three columns are Raygun's Basic tier for each product.

| Feature | BugSnag Select | Crash Reporting Basic | RUM Basic | APM Basic |
|---|---|---|---|---|
| Price, annual billing | Price not listed | $40 a month | $80 a month | $80 a month |
| Price, monthly billing | Price not listed | $60 a month | $120 a month | $120 a month |
| Included volume | 50,000 to 3M events, 1M to 150M spans | 100,000 errors | 100,000 sessions | 100,000 traces |
| Retention | 60 days | 180 days | Not listed | Not listed |
| Users | Unlimited | Unlimited | Unlimited | Unlimited |

BugSnag's Select and Preferred plans both read "Starting at $0" next to the slider, with no fixed figure, so you'll need to set your volume or talk to sales.

### What costs extra

| Need | BugSnag | Raygun |
|---|---|---|
| More errors | A higher volume tier | $0.001 per error |
| Page speed | Spans on the slider, plus OpenTelemetry | RUM subscription, $0.002 per extra session |
| Server performance | Spans on the slider, plus OpenTelemetry | APM subscription, $0.002 per extra trace |
| Logs | ✘: buy a separate log tool | ✘: buy a separate log tool |
| AI | Your own assistant through MCP | AI Error Resolution included; MCP with your own assistant |

### Comparing the actual cost

For error tracking alone, BugSnag lets you start for nothing, but its free plan holds one user and seven days of data. Raygun has no free plan, and Crash Reporting starts at $40 a month with 180 days of retention and unlimited users.

The bill grows faster with Raygun once you want its other products. Crash Reporting, RUM and APM at the Basic tier come to $200 a month on annual billing. Raygun's Crash Reporting plan does include 5,000 RUM sessions and 5,000 APM traces, which covers a small trial. BugSnag folds spans into the same slider, though you still pay for the OpenTelemetry work.

Neither covers logs or uptime checks. If you'd rather pay for errors, logs and uptime in one product, this [comparison of Raygun with an all-in-one platform](https://betterstack.com/community/comparisons/better-stack-vs-raygun/) runs those numbers.

**Verdict: Mixed.** BugSnag is cheaper to try. Raygun is easier to budget, since every price is on its page.

## Full feature comparison

| Feature | BugSnag | Raygun |
|---|---|---|
| Main focus | Errors and release stability | Errors, RUM and APM as separate products |
| Setup | One project per app | One application per part of the app |
| Server errors caught | ✔: all six | Five of six |
| Handled and unhandled badges | ✔: on every row | ✘: no badge seen |
| Server source lines | ✘: not shown | ✘: not shown |
| Correlated events | ✔: same user and session | ✘: not offered |
| Fix tied to a version | ✔: yes | ✔: yes, with a discard option |
| Regressions listed per release | ✘: no | ✔: Regressions tab |
| Release stability score | ✔: session stability | ✘: not offered |
| Browser errors and source maps | Not tested | ✔: manual upload on the trial |
| Real user monitoring | Not tested | ✔: Web Vitals, routes, Customers |
| Server performance | Needs OpenTelemetry | APM agent, limited in my test |
| Logs | ✘: not offered | ✘: not offered |
| Conditional snooze | ✔: yes | ✘: no |
| AI | MCP server | AI Error Resolution and MCP server |
| Free plan | ✔: 7,500 events, 1 user | ✘: none |
| Published prices | ✘: slider, no figure | ✔: every product |

## Which should you choose?

It depends on how much of your stack you want one vendor to watch.

### Choose BugSnag if you want clean error data and release health

BugSnag fits teams that care most about the errors themselves. It caught every server failure I planted, marked crashes on every row, and showed the rest of a bad session through Correlated events. Its fixes are tied to versions, and every release gets a stability score with no deploy step. The snooze conditions keep noisy errors quiet until they spread.

Plan around two gaps: there's no performance data until you adopt OpenTelemetry, and prices aren't published. If you're weighing it against a broader platform, our [Sentry vs BugSnag test](https://betterstack.com/community/comparisons/sentry-vs-bugsnag/) shows what you give up and gain.

### Choose Raygun if you want errors, page speed and server timing from one vendor

Raygun fits teams who want to watch the browser as closely as the server. Its RUM gave me Web Vitals, speed by route and a per-user view with no extra code, and each deployment page lists its new errors and regressions. Every price is published, and Crash Reporting keeps errors for 180 days.

Expect more setup. Each part of your app is its own application, API automation needs a paid token, and the Node.js APM package broke my error reports until I disabled its crash-reporting bridge. For a closer look at how Raygun's browser side holds up against a tool with replay and tracing, see our [Sentry vs Raygun comparison](https://betterstack.com/community/comparisons/sentry-vs-raygun/).

## FAQ

### Does BugSnag have real user monitoring?

BugSnag's performance product lists Page Loads, and it collects them through OpenTelemetry. I didn't test it. BugSnag doesn't list session replay, and its error SDK alone sends no performance data.

### Is Raygun APM safe to add to an app that already uses Raygun Crash Reporting?

Test it first. In my Node.js app, installing `raygun-apm` 2.3.0 next to `raygun` 2.2.10 turned every native JavaScript error into an empty "Unknown error", even with the profiler off. Setting `RAYGUN_APM_CRASH_REPORTING_INTEGRATION=false` or removing the package brought the messages back.

### Which tool is better at catching a bug that comes back?

Both reopen a bug that returns in a newer version, and both log why. Raygun's deployment page also lists that bug under Regressions, which makes it easier to find. Neither marks it in the main error list.

### Do I need a paid plan to automate Raygun?

For uploads and deployments by API, yes. Raygun's Personal Access Token is paid-only, so on the trial you upload source maps and create deployments by hand.

## Final thoughts

BugSnag and Raygun both treat a fix as something tied to a version, and both did that well. Past that point, **BugSnag stays focused on error quality, while Raygun spreads out into page speed and server timing**.

That spread is Raygun's strength and its cost. Its RUM was the most useful thing either tool gave me outside error tracking. Its APM, in my Node.js app, cost me two wasted test runs and the messages on my errors. BugSnag asks you to bring OpenTelemetry for anything beyond errors, which is more work up front and less risk later.

If the browser is where your users feel problems, Raygun's RUM is worth the extra applications and subscriptions. **If your errors are the job, BugSnag does that job with fewer surprises.**