Skip to main content

Events vs Issues

Understanding the difference between events and issues is fundamental to using Proliferate effectively.

Events

An event is a single occurrence of an error in your application. Every time an exception is thrown and captured, a new event is created. Events contain:
  • Timestamp of when the error occurred
  • Stack trace showing where the error happened
  • User and account context at the time of the error
  • Environment and release information
  • Breadcrumbs (user actions, network requests, console logs)
  • Session replay (for browser errors)
  • Logs leading up to the error
Think of an event as a single instance: “Alice from Acme Corp hit a TypeError at 2:45 PM on production.”

Issues

An issue is a group of similar events that share the same root cause. Proliferate automatically groups events into issues using fingerprinting. Issues show you:
  • Total count of events
  • First and last occurrence timestamps
  • Unique users and accounts affected
  • Frequency trends over time
  • Individual event details
Think of an issue as the pattern: “The checkout page throws TypeError: Cannot read property 'id' in production, affecting 47 users across 12 accounts.”
Example:
Issue #123: TypeError: Cannot read property 'id' of undefined
├── Event 1: occurred at 2:45 PM, user_123, acct_456
├── Event 2: occurred at 2:47 PM, user_789, acct_456
├── Event 3: occurred at 3:02 PM, user_234, acct_999
└── Event 4: occurred at 3:15 PM, user_567, acct_999
All 4 events are grouped into a single issue because they have the same fingerprint.

Fingerprinting

Fingerprinting is how Proliferate determines which events should be grouped together into the same issue. This is crucial for noise reduction and understanding the scope of problems.

The Algorithm

Proliferate uses a smart fingerprinting algorithm that focuses on the structural characteristics of errors:
1

Extract exception type

Get the error type (e.g., TypeError, ReferenceError, ValueError)
2

Parse stack trace

Extract function names and file names from the first 3 stack frames
3

Create fingerprint string

Combine into a string: TypeError|[email protected]|[email protected]|[email protected]Important: Line numbers and column numbers are ignored
4

Hash and truncate

Compute SHA256 hash and take the first 16 characters: a3f5c7e9b1d4f6a8

Example

Given this JavaScript error:
TypeError: Cannot read property 'id' of undefined
    at checkout (app.js:42:15)
    at onClick (button.js:10:5)
    at callHandler (react-dom.js:500:20)
    at dispatch (react-dom.js:425:10)
The fingerprint is generated from:
  • Exception type: TypeError
  • Frame 1: checkout in app.js
  • Frame 2: onClick in button.js
  • Frame 3: callHandler in react-dom.js
Result: SHA256("TypeError|[email protected]|[email protected]|[email protected]")[:16]

Why Line Numbers Are Ignored

Line numbers are intentionally ignored in fingerprinting. This ensures that:
  • Code changes don’t split issues: If you add a line at the top of a file, the error still groups with previous occurrences
  • Different builds group together: Production and staging builds with different line numbers still group correctly
  • Long-term tracking: Track the same error across deployments and releases
If you refactor code and change function or file names, events before and after the refactor will create separate issues. This is intentional and usually desired.

Language Support

The fingerprinting algorithm works for both JavaScript/TypeScript and Python:
Stack trace format:
at functionName (file.js:10:5)
at file.js:10:5
Parsed as: [email protected] or <anonymous>@file.js

Projects

A project is a logical container for your application’s errors, typically representing one codebase or service.

When to Create Projects

Create separate projects for:
  • Different applications: Web app, mobile API, admin dashboard
  • Different services: Each microservice in your architecture
  • Different repositories: Monorepo apps might share one project, multi-repo systems have multiple
Best practice: If it has its own deployment, it should probably be its own project.

Project Settings

Each project has:
  • API Key: Used by the SDK to send events (pk_...)
  • Name and description
  • Linked repository: For source code context (GitHub integration)
  • Team members: Who can view and manage errors

Releases

A release represents a specific version of your code, typically identified by a git commit SHA.

Why Releases Matter

Releases are essential for:
  1. Source maps: Matching minified code to original source
  2. Regression detection: Identifying when an issue first appeared
  3. Deployment tracking: Seeing which errors are in which version
  4. Rollback decisions: Understanding if rolling back will fix issues

Release Detection

Proliferate automatically detects releases from:
Build plugins (recommended):
  • Next.js plugin injects release at build time
  • Webpack/Vite plugins do the same
Environment variables:
  • PROLIFERATE_RELEASE
  • GITHUB_SHA
  • VERCEL_GIT_COMMIT_SHA
  • CF_PAGES_COMMIT_SHA
  • And many more…
Manual:
Proliferate.init({
  endpoint: '...',
  apiKey: '...',
  release: '1.2.3', // Explicitly set
});

Release Workflow

1

Create release

Build plugins automatically create releases. Or use the API:
curl -X POST https://api.proliferate.com/api/v1/releases \
  -H "Authorization: Bearer $API_KEY" \
  -d '{"version": "abc123", "project_id": 1}'
2

Upload source maps

For JavaScript projects, upload source maps to get readable stack traces:
npx @proliferate/cli upload-sourcemaps \
  --release abc123 \
  --dir ./dist
3

Finalize release

Mark the release as complete (optional):
curl -X POST https://api.proliferate.com/api/v1/releases/abc123/finalize \
  -H "Authorization: Bearer $API_KEY"

Environments

An environment represents where your code is running: production, staging, development, etc.

Environment Detection

Auto-detected from:
  • process.env.NODE_ENV (most common)
  • process.env.ENVIRONMENT
  • process.env.ENV
Manual:
Proliferate.init({
  endpoint: '...',
  apiKey: '...',
  environment: 'production',
});

Using Environments

Filter issues by environment to:
  • Focus on production errors vs. staging noise
  • Compare error rates across environments
  • Set up different alerting rules per environment
Use descriptive environment names like production, staging, development, preview, or local. Avoid using commit SHAs or version numbers as environments.

Session Context

Sessions help you understand user behavior leading up to errors.

Session ID

A session ID is generated when the SDK initializes and persists across page navigations (for browser apps). Use cases:
  • Correlate multiple errors from the same user session
  • See the full sequence of actions a user took
  • Link errors to backend logs using the same session ID
Access the session ID:
const sessionId = Proliferate.getSessionId();
// Send to backend for log correlation

Window ID

For multi-tab scenarios, each browser tab gets a unique window ID while sharing the same session ID. Use cases:
  • Differentiate between errors from different tabs
  • Replay shows what happened in a specific tab

Trace ID

A trace ID is generated per page load (for SPAs) or request (for servers) and is used to correlate logs with errors. How it works:
  1. SDK generates a trace ID when initialized
  2. All logs get tagged with the trace ID
  3. Errors include the trace ID
  4. Dashboard shows logs ±5 minutes around the error with matching trace ID
Access the trace ID:
const traceId = Proliferate.getTraceId();

Summary

Events

Individual error occurrences with full context

Issues

Grouped events with the same fingerprint

Fingerprints

SHA256 hash of type + top 3 frames (no line numbers)

Projects

Containers for one app/service

Releases

Code versions (git SHAs) for source maps and tracking

Environments

Where code runs (production, staging, etc.)

Next Steps

Now that you understand the core concepts, dive deeper into specific features: