Skip to content

Release health: what got worse after each deploy, and did the fix hold

Record releases and deploy markers from CI with sentry-cli or REST, see new, regressed and increased errors in each release's first 24 hours, resolve in a release and check the fix per environment.

Markdown
On this page

Every deploy raises two questions: which errors got worse with this release? and did the fix really end the error? Release health answers both from data on your node — in the app (Project → Releases, and the issue page), through the REST API and through MCP release_health.

What you need#

  1. A release name on every event. Set release in the SDK's init, for example the commit SHA or web@1.4.2. The same name goes into your source map upload and your deploy marker.

  2. A deploy marker for every deploy. It tells Belvador when a release started running in an environment. Without markers a release's window starts at its first event and a fix can never be verified.

  3. A node on agent 0.1.38 or newer. Nodes update themselves; the Releases tab says so while yours is older.

Record releases and deploys from CI#

Use the same upload token as for source maps (Project settings → Upload tokens). Tokens created since release health shipped can upload source maps and record releases and deploys; an older token answers 403 naming the missing releases:write scope — create a new one.

Terminal
export SENTRY_URL=https://edge.belvador.devexport SENTRY_AUTH_TOKEN="$BELVADOR_UPLOAD_TOKEN"export SENTRY_ORG=belvador SENTRY_PROJECT=<project-slug>npx @sentry/cli releases new "$RELEASE"npx @sentry/cli releases set-commits "$RELEASE" --localnpx @sentry/cli releases finalize "$RELEASE"npx @sentry/cli deploys new --release "$RELEASE" -e production
  • set-commits --local sends only the commit SHA and repository name of each commit. Author names, e-mail addresses, messages and changed files are dropped at the edge and never reach your node.

  • --auto needs a repository integration Belvador does not offer; it falls back to --local.

  • Run deploys new once per environment you deploy to, after the deploy succeeded.

Without sentry-cli#

Any CI can post a deploy marker to the REST API with a token that has the releases:write scope (Settings → API tokens):

Terminal
curl -fsS -X POST "https://api.belvador.dev/v1/projects/<project-id>/deployments" \  -H "Authorization: Bearer $BELVADOR_TOKEN" -H "Content-Type: application/json" \  -d "{\"version\":\"$RELEASE\",\"environment\":\"production\",\"deploy_id\":\"$CI_PIPELINE_ID\"}"

deploy_id is optional: sending the same marker again (a retried job) changes nothing.

Release health#

Project → Releases lists the releases of one environment, newest deploy first; releases without a marker are ordered by semantic version. Each row shows events per hour against the previous release and three counts for the release's first 24 hours (from its first deploy, or from its first event when there is no marker):

ListAn issue is in it when
Newits first event in this environment carries this release
Regressedit was resolved and came back with this release
Increasedits events per hour are at least 2× the previous release's, with at least 10 events (new issues are not repeated here)

Open a release to see the three lists (up to 50 issues each, with hourly sparklines), its deploy markers and commits. Compare with picks another release instead of the previous one.

Resolve in a release#

On an issue, Resolve → Resolve in release… marks it fixed from release R on:

  • an event from R or a later release reopens the issue as regressed;

  • an event from an older release that is still running does not — the old version is expected to keep failing until it is replaced.

"Later" follows deploy order in the environment, then semantic versions. When neither orders two releases, the issue reopens only for events that arrive after the resolve, as before. Resolve and Resolve in next release keep working as they always did.

Fix status#

A resolved issue shows Fix status for every environment it occurred in during the last 30 days:

StatusMeaning
Fixedthe release with the fix has a deploy marker, sent 24 hours of traffic, and the error did not happen in it or any later release
Not verified yetthe release is not deployed, has no marker, has no traffic yet, or has run for less than 24 hours
Not fixedthe error happened again in a release that has the fix, or the issue regressed
Unknownthe releases cannot be put in order (no deploy markers, not semantic versions)

The issue's overall status is its worst environment. "Traffic" means any event, span or log carrying the release (service.version for OpenTelemetry), so an app that sends traces counts even when it has no errors. For Resolve in next release and plain Resolve, the fix is checked against the first deploy after the resolve.

API and MCP#

RequestScope
GET /v1/projects/{project}/releases?environment=releases:read
GET /v1/projects/{project}/releases/{version}/health?environment=&compare=releases:read
GET /v1/issues/{issue_id}/fix-statusreleases:read
POST /v1/projects/{project}/deploymentsreleases:write
PATCH /v1/issues/{issue_id} with {"action":"resolve","in_release":"web@1.4.2"}issues:write

MCP release_health(project, version?, environment?, compare?) returns the same three lists; get_issue adds fix_status for resolved issues. See the API reference and MCP.

Limits#

LimitValue
Release name200 characters, no spaces, slashes or control characters
Commits kept per release1,000 (SHA + repository only)
sentry-cli release and deploy requests per token600 per hour
Issues per health list50
Releases listed per environment50

Releases and deploy markers are stored only on your node and removed with the project.

When something looks wrong#

  • Every issue is "New" — there is no earlier release in that environment yet.

  • Fix status stays "Not verified yet" — check that CI runs deploys new (or the REST call) for that environment and that events carry the release name.

  • 403 with releases:write — the upload token predates release health; create a new one.

  • The tab asks for a node update — the node is older than agent 0.1.38; it updates itself on its channel.

Spotted something wrong or missing? Tell us: hello@belvador.dev