Skip to main content

Process Analytics

Analytics reports how a deployed process behaved across many instances: where time goes, which branches instances took, where they failed, and how those figures differ between groups of instances.

Open Analytics from the BPMN navigation. The section is present when the deployment configures a read rate, see Configuration.

The Analytics section listing analysis runs across the projectThe Analytics section listing analysis runs across the project
Every run in the project, newest first. Each row is a link that reopens it.

Two sources of figures

SourceCoversAvailability
OverviewInstance counts, throughput, incidentsOn first paint, complete
Deep analysisNode durations, branches, routes, instance durations, rotationsNeeds an analysis run, converges as the run reads

Overview reads the instance and incident tables. Deep analysis reads each instance's execution history from Temporal.

Overview

The overview panel sits at the top of every run page. It opens on a 30 day window and offers 24h, 7d, 30d and 90d, independent of the run's own window.

CardContents
InstancesTotal in the window, with completed, failed and running beside it
Instances startedOne bar per bucket. The bucket width follows the window, and empty buckets are drawn
Incidents by nodeMost incidents first, each with the number still open
Incidents by error typeCounted across the window

FAILED, TERMINATED and TIMED_OUT count as failed.

Overview panel with instance counts, a throughput chart and incidents by nodeOverview panel with instance counts, a throughput chart and incidents by node
Read from the indexes, so it is complete the moment the page opens.

The incident cards count incidents. An incident that was retried and failed again is two incidents and two failed executions, so these figures and the Nodes table's Failed column answer different questions.

The overview is unfiltered. A segment predicate reads an instance's variables, and variables arrive with the history fetch that an analysis run performs.

Analysis runs

An analysis run is a durable object with an id and a URL. Creating one returns immediately and the read continues in the background. The run page polls it, so figures appear while the read is still going, and closing the tab, losing the connection or restarting the replica costs at most one checkpoint interval.

Starting a run

New analysis opens the drawer.

FieldDetail
Process, VersionOne deployed version. Node ids are defined by the version that declares them, so a run covers exactly one version
Time window24h, 7d, 30d, 90d, or a custom from and to
SegmentsOne to five named groups, see Segments
New analysis drawer with a process, version, time window, cost estimate and two segmentsNew analysis drawer with a process, version, time window, cost estimate and two segments
The estimate updates as the scope changes, before anything is committed.

Before the run starts, the drawer reports the number of instances in the window, the configured read rate, and the estimated time from dividing one by the other.

The window is frozen when the run is created, so a resumed run enumerates exactly what it started with.

Submitting a window and segment list that already has a RUNNING or PAUSED run on the same definition opens that run.

Run status

StatusMeaning
RUNNINGReading
PAUSEDStopped by an operator. Folded figures are kept and a resume continues from the checkpoint
COMPLETEThe read reached the end of the window
FAILEDThe read stopped on an error, shown in a banner on the run page
CANCELEDStopped by an operator. Folded figures are kept

A RUNNING run that no replica has picked up is marked queued and is waiting for a slot under the concurrency cap.

Controls

ActionEffect
PauseStops the read at the current checkpoint
ResumeContinues from the checkpoint
Cancel runStops a RUNNING or PAUSED run
Re-analyzeOpens the drawer carrying the same segments and a window of the same length ending now
ExportCSV or JSON, see below

CSV is one row per node per segment, with the coverage counters repeated on every row. JSON carries the coverage, every segment and the model element names. Both files are named <process>-v<version>-<date>, with -partial appended when the run had not finished.

Coverage

The progress card carries:

  • Analyzed N of M with a percentage. M is counted once when the run starts.
  • How far back the read has reached. A run reads newest first, so a partial result describes recent behaviour.
  • The window.
  • Skipped, instances whose row is in the database and whose history is no longer readable.
  • The read rate, the elapsed time, and the estimated time remaining.
Progress card of a running analysis showing coverage, skipped instances, read rate and time remainingProgress card of a running analysis showing coverage, skipped instances, read rate and time remaining
A run in flight. The skipped count is discovered while reading, never predicted.

Retention and skipped instances

A run reads each instance's history by explicit run id, taken from the run chain recorded in the database. Archived history is readable on that path: once Temporal deletes the live history it serves the archived copy for the same run id, so archival keeps instances analysable past Temporal's retention.

An instance is skipped when its history is readable from neither live persistence nor archival. Skips are found while reading, one instance at a time, and the run walks on.

Once the app level retention pass deletes the instance row, the instance is no longer enumerated at all. See History retention and archival.

Read cost

A run reads one history per Temporal run in an instance's chain. An instance that rotated through Continue-as-New three times costs three reads, and the Rotations per instance card reports that distribution.

Reads are rate limited to the configured instances per second, and a run holds that rate for its whole read. See Configuration.

Segments

A segment is a name and a FEEL boolean over the variables an instance ended with. A run carries one to five of them. The first segment is always unfiltered and is the baseline that comparison works against.

PredicateResult
EmptyEvery instance in the window matches
Evaluates to trueThe instance joins the segment
Evaluates to falseThe instance stays out of the segment
Cannot be evaluatedCounted under "could not be evaluated" and left out of the segment

A predicate that names a variable an instance does not carry cannot be evaluated against it. A variable written on one branch only produces this for every instance that took a different branch. The run page reports the count per segment, and flags a segment where no instance could be evaluated at all.

Every segment is folded during the same pass, so a run with five segments reads each instance once.

amount > 50000
customer.vip
amount > 50000 and customer.region = "EU"

Predicates read root scope variables. See Variables.

Reading the results

Counts, failures, cancellations, minimum and maximum are exact. p50, p95 and p99 come from a bucketed histogram and are within about 2%.

While a run is RUNNING, every figure covers the instances read so far.

Where the time goes

A heatmap over the deployed diagram.

MetricColours each node by
p50, p95, MaxThe selected duration, with a log scale toggle
FrequencyNumber of executions
Error rateFailed executions over total executions
Process diagram coloured by p95 duration on a log scaleProcess diagram coloured by p95 duration on a log scale
p95 on a log scale. The scale below the diagram maps colour to duration.

Gateways and events finish the instant they are reached and carry no duration.

In delta mode the colour is the difference against the baseline, and a node the segment never took is struck through.

When the analysed version is no longer available the diagram is not drawn. Every figure below it is unaffected.

Nodes

Sorted by p95. Elements that finish instantly sit behind Show N instant elements.

ColumnContents
NodeElement name and id
ExecutionsTimes the node was entered across the segment
Min, p50, p95, MaxDuration
FailedExecutions that threw
RepeatsExecutions per instance, bucketed as 1, 2, 3, 4+
Share of timeThis node's duration sum over the segment's instance duration sum
Nodes table sorted by p95 with executions, durations, failures, repeats and share of timeNodes table sorted by p95 with executions, durations, failures, repeats and share of time
A repeat count above 1x marks a node the average instance entered more than once.

Instance duration

A histogram over the segment's completed instances. A running instance has no end time and is not in it.

Rotations per instance

Temporal runs per instance, bucketed as 1, 2, 3, 4+. An instance appears above 1 when it outgrew a single Temporal run and rotated through Continue-as-New.

Branches

Per gateway, the instances that reached it, the number of visits, and the share per outgoing flow.

  • Reached counts instances. Takings counts visits. A gateway inside a loop is visited more than once per instance.
  • Parallel gateways choose nothing and do not appear.
  • A visit is counted as ambiguous when two of the gateway's outgoing flows lead to the same node.
  • A default flow is labelled default. A flow drawn without a name is labelled with its condition.
Branches panel showing the share of each outgoing flow for two gatewaysBranches panel showing the share of each outgoing flow for two gateways
One block per gateway, one bar per outgoing flow.

Routes

The combination of branches an instance took, with repeats collapsed into 1, 2, 3, 4+. Most travelled first, 50 at most, with the instances on further routes counted below the list.

Selecting a route strokes the flows it took on the diagram and fades the rest. Selecting it again clears it.

Routes list with each route shown as its branch legs, instance count, share and p50Routes list with each route shown as its branch legs, instance count, share and p50
A route carries no name of its own, so it is rendered as the legs it is made of.

Comparing segments

With more than one segment the run offers three modes.

ModeShows
One segmentThe selected segment on its own
Side by sideEvery segment together
Delta vs baselineThe selected segment as its difference from the first segment

Two comparisons are drawn across segments:

  • Node p95 by segment, where the baseline column carries the figure and every other column carries its difference.
  • Branch mix, one gateway at a time, one bar per segment, each bar adding to 100% of that segment.
Node p95 compared across three segments, with differences from the baselineNode p95 compared across three segments, with differences from the baseline
A node a segment never took is struck through rather than shown as zero.

Configuration

VariableDefaultDescription
ANALYTICS_READ_RATE100Instances per second a run is allowed to read. 0 turns the feature off
ANALYTICS_CONCURRENCY16Instances fetched in parallel within one run
ANALYTICS_MAX_CONCURRENT_RUNS3Runs executing at once per replica. Each holds its own read rate
ANALYTICS_RETENTION_DAYS30Days a finished run is kept before the retention pass drops it

A run's rate is read capacity that the live engine does not get, so the rate belongs below what the Temporal cluster can serve alongside process execution.

With ANALYTICS_READ_RATE=0 the Analytics section is absent from the navigation and the API refuses to create a run.

Permissions

ActionRole
Open a run, the overview, the estimate and the runs listViewer
Create, pause, resume and cancel a runEditor

API

All analytics endpoints are under /projects/{projectID}/bpmn.

EndpointPurpose
POST /definitions/{definitionID}/analytics/runsStart a run
GET /definitions/{definitionID}/analytics/runsRuns for one definition
GET /analytics/runsRuns across the project, paginated
GET /analytics/runs/{runID}Progress and folded figures
DELETE /analytics/runs/{runID}Cancel
POST /analytics/runs/{runID}/pausePause
POST /analytics/runs/{runID}/resumeResume
GET /definitions/{definitionID}/analytics/instantOverview figures for a window
GET /definitions/{definitionID}/analytics/estimateInstances and time a run over a window would cost

To find individual instances by what their variables hold, see Finding instances by variable.