Portal Community

What Is Measured

Response time in EdgeInteract is defined as the duration from the displayed pipeline state to the responded pipeline state — i.e., the time from the moment the UI rendered the interaction to the moment the user submitted their response.

published
delivered
displayed
⟵ response_time_ms measured here ⟶
acked

The clock starts when the client emits the displayed acknowledgement, and stops when the response is received server-side.

The Metric: interaction_response_time_ms

AttributeValue
Metric nameinteraction_response_time_ms
TypeHistogram
Unitmilliseconds
Labelstype (approval, confirmation, form, picker, notification), outcome (approved, rejected, confirmed, cancelled, submitted, selected, acknowledged)
Buckets500ms, 1s, 2s, 5s, 10s, 30s, 60s, 120s, 300s, 600s, 1800s, 3600s
Emitted byMetricsInteractionHook (must be registered)
Histogram Buckets The buckets span from 500ms to 1 hour, reflecting the wide range of expected response times — notifications may be acknowledged in under a second, while multi-day approvals may be pending for hours.

Accessing Response Time in Code

Use the useInteractionMetrics() hook from edge-interact-observability to access response time data in React admin views:

import { useInteractionMetrics } from 'edge-interact-observability';

function ResponseTimePanel() {
  const { responseTime } = useInteractionMetrics({
    type: 'approval',    // optional filter
    window: '24h'        // time window
  });

  // responseTime contains P50, P95, P99, mean, count
  return (
    <div>
      <h3>Approval Response Times (last 24h)</h3>
      <p>P50: {responseTime.p50}ms</p>
      <p>P95: {responseTime.p95}ms</p>
      <p>P99: {responseTime.p99}ms</p>
      <p>Sample count: {responseTime.count}</p>
    </div>
  );
}

Server-Side: Accessing Response Time

On the server, you can query response time statistics from the audit store:

// In a diagnostics service or admin controller
public class ResponseTimeService(IInteractionAuditStore auditStore)
{
    public async Task<ResponseTimeStats> GetResponseTimeStatsAsync(
        string? type = null,
        TimeSpan? window = null,
        CancellationToken ct = default)
    {
        var since = window.HasValue
            ? DateTime.UtcNow - window.Value
            : DateTime.UtcNow.AddDays(-1);

        var entries = await auditStore.QueryAsync(new AuditQuery
        {
            Type          = type,
            RespondedAfter = since,
            Statuses       = [InteractionStatus.Responded]
        }, ct);

        var times = entries
            .Where(e => e.DisplayedAt.HasValue && e.RespondedAt.HasValue)
            .Select(e => (e.RespondedAt!.Value - e.DisplayedAt!.Value).TotalMilliseconds)
            .OrderBy(ms => ms)
            .ToList();

        if (times.Count == 0)
            return ResponseTimeStats.Empty;

        return new ResponseTimeStats
        {
            Count = times.Count,
            P50   = times[(int)(times.Count * 0.50)],
            P95   = times[(int)(times.Count * 0.95)],
            P99   = times[(int)(times.Count * 0.99)],
            Mean  = times.Average(),
            Min   = times.First(),
            Max   = times.Last()
        };
    }
}

Typical Percentile Targets

Notification P95
< 30s
Users typically acknowledge notifications quickly
Confirmation P95
< 2m
Blocking confirmations should resolve fast
Approval P95
< 4h
Approvals may involve review; daily alerting is typical

Grafana Query

To visualize response time percentiles in a BizFirst Observe dashboard panel:

// PromQL — P95 response time for approval interactions (5-minute rate)
histogram_quantile(0.95,
  sum(rate(interaction_response_time_ms_bucket{type="approval"}[5m]))
  by (le)
)

// PromQL — P50 response time across all types
histogram_quantile(0.50,
  sum(rate(interaction_response_time_ms_bucket[5m]))
  by (le, type)
)
Timed-Out Interactions Are Excluded interaction_response_time_ms only records entries for interactions that received a response. Timed-out interactions are counted separately in interaction_timeout_total. This means response time P95 reflects users who did respond — not the full population.

Factors That Skew Response Times