Breadcrumbs

Structured trail of events that live on scopes and are applied to error events to show what happened before an issue.

Statusstable
Version1.1.0(changelog)

Breadcrumbs create a trail of events that happened prior to an issue. They live on scopes and are applied to error events at capture time, giving users context about what led to a problem.

Unlike traditional logs, breadcrumbs are structured — they carry a type, category, severity level, and arbitrary data. They are stored in a ring buffer with a configurable maximum size, keeping only the most recent entries.

Related specs:


Stablespecified since 1.0.0

A breadcrumb is a structured record with the following fields:

FieldTypeRequiredDescription
timestampstring or numberRecommendedRFC 3339 string or Unix epoch (float/integer). Breadcrumbs are most useful when timestamped.
typestringNoControls rendering. Defaults to "default". See Breadcrumb Types.
categorystringNoDotted string identifying the origin, e.g., ui.click, http, flask. Influences rendering color and icon.
messagestringNoHuman-readable text. Whitespace is preserved.
dataobjectNoArbitrary key-value pairs. Contents depend on type. Extra keys rendered as a key/value table.
levelstringNoSeverity: fatal, error, warning, info (default), debug.
originstringNoSource identifier. Used by hybrid SDKs to distinguish native vs JS vs Flutter breadcrumbs.

Breadcrumbs MUST NOT be sorted by timestamp. They MUST preserve insertion order.

Stablespecified since 1.0.0

On the event, breadcrumbs appear as either a wrapped or flat array. SDKs SHOULD use the wrapped format:

Copied
{
  "breadcrumbs": {
    "values": [
      {
        "timestamp": "2016-04-20T20:55:53.845Z",
        "message": "Started",
        "category": "log"
      },
      {
        "timestamp": "2016-04-20T20:55:53.847Z",
        "type": "navigation",
        "data": { "from": "/login", "to": "/dashboard" }
      }
    ]
  }
}

Entries are ordered oldest to newest. The last entry is the last event before the captured error occurred.

Stablespecified since 1.0.0
TypeDescriptionSpecial data fields
defaultGeneric breadcrumb or log message.None defined. Rendered as key/value table.
debugLog message. Internally, default + category console renders as debug.None defined.
errorAn error that occurred before the captured exception.None defined.
navigationURL change (web) or UI transition (mobile/desktop). Internally, default + category navigation renders as navigation.from (required): original location. to (required): new location.
httpOutgoing HTTP request (AJAX, server-to-server, etc.).url, method, status_code (integer), reason.
infoInformation identifying root cause or affected user.None defined.
queryA query made in the application.None defined.
transactionA tracing event. Wire format: default + category sentry.transaction or sentry.event.None defined.
uiUser interaction. Wire format: default + category ui.* (e.g., ui.click).None defined.
userUser interaction (distinct from ui — uses type: "user" directly).None defined.

Stablespecified since 1.0.0

Breadcrumbs MUST be stored in a ring buffer on the scope. When a breadcrumb is added and the total count exceeds the max_breadcrumbs limit, the SDK MUST remove the oldest breadcrumb.

The max_breadcrumbs limit is a Client option. SDKs SHOULD default to 100.

If the SDK is disabled (no active client), breadcrumbs SHOULD NOT be recorded.

Stablespecified since 1.1.0

Breadcrumbs live on scopes and follow the same scope data application rules as other scope data. When an event is captured, breadcrumbs from the global, isolation, and current scopes are merged.

The top-level Sentry.addBreadcrumb() MUST write to the isolation scope. This ensures breadcrumbs are shared across all events within the same request/tab/session.

When merging breadcrumbs from multiple scopes at capture time, the SDK SHOULD sort them by insertion order and then reapply the max_breadcrumbs limit.

When a scope is forked (via withScope() or starting a new span), the forked scope receives a copy of the parent's breadcrumbs. Breadcrumbs added to the forked scope do not propagate back to the parent — this follows copy-on-write semantics.

Stablespecified since 1.0.0

SDKs SHOULD support a before_breadcrumb Client option — a callback invoked with the breadcrumb (and on some platforms a hint) before it is added to the scope.

The callback MAY:

  • Return the breadcrumb (possibly modified) to record it
  • Return null to discard it
Copied
Sentry.init({
  beforeBreadcrumb(breadcrumb, hint) {
    if (breadcrumb.category === "console") {
      return null; // discard console breadcrumbs
    }
    return breadcrumb;
  },
});
Stablespecified since 1.0.0

SDKs SHOULD automatically record breadcrumbs for common events via default integrations:

  • HTTP requests: type: "http", category: "http". Added after the request finishes. Level: info (2xx-3xx), warning (4xx), error (5xx). Data SHOULD include url, http.request.method, http.response.status_code. HTTP requests matching the configured DSN MUST be excluded.
  • UI events: type: "default", category: "ui.click" (or similar ui.*). Button clicks, touch events, etc.
  • System events: Low battery, low storage, airplane mode, memory warnings, device orientation changes.
  • Console/log messages: type: "default", category: "console".
  • Navigation: type: "navigation", with data.from and data.to.

MethodDescription
scope.addBreadcrumb(breadcrumb)Add a breadcrumb to the scope. Enforces the ring buffer limit.
scope.clearBreadcrumbs()Remove all breadcrumbs from the scope.
scope.clear()Remove all data from the scope, including breadcrumbs.

FunctionTarget ScopeDescription
Sentry.addBreadcrumb(breadcrumb)Isolation scopeConvenience function. The breadcrumb passes through the before_breadcrumb hook before being added.

OptionTypeDefaultDescription
max_breadcrumbsint100Maximum number of breadcrumbs per scope.
before_breadcrumbcallbackHook to modify or discard breadcrumbs before recording.

Copied
// Manual breadcrumb
Sentry.addBreadcrumb({
  category: "auth",
  message: "User logged in",
  level: "info",
});

// Navigation breadcrumb
Sentry.addBreadcrumb({
  type: "navigation",
  data: {
    from: "/login",
    to: "/dashboard",
  },
});

// HTTP breadcrumb (typically added automatically by integrations)
Sentry.addBreadcrumb({
  type: "http",
  category: "xhr",
  data: {
    url: "https://api.example.com/users",
    method: "GET",
    status_code: 200,
    reason: "OK",
  },
});

Copied
import sentry_sdk

# Manual breadcrumb
sentry_sdk.add_breadcrumb(
    category="auth",
    message="User logged in",
    level="info",
)

# Breadcrumb on a specific scope
with sentry_sdk.new_scope() as scope:
    scope.add_breadcrumb(
        category="db",
        message="SELECT * FROM users",
        level="info",
    )
    sentry_sdk.capture_exception(error)

VersionDateSummary
1.1.02024-02-14Breadcrumbs written via top-level API now go to isolation scope (three-scope model)
1.0.02020-05-04Initial spec — breadcrumb structure, types, ring buffer, before_breadcrumb hook
Was this helpful?
Help improve this content
Our documentation is open source and available on GitHub. Your contributions are welcome, whether fixing a typo (drat!) or suggesting an update ("yeah, this would be better").