Part
6
  |  
Field Manual
  |  
Chapter
23

Monitoring and Alerting on Your Workflow Stack

Monitoring a workflow stack is a different problem from monitoring a service. The unit of work is a workflow execution, not a request. The failure modes are different.
Reading Time
11
mins
BACK TO n8n Workflow ENgineer

Here is the trap I see teams fall into: they instrument their n8n instance like it's a web application. They point Datadog at the container, watch CPU and memory graphs, and set an alert if the host goes down. Then they wonder why an order-processing workflow has been silently dropping webhook events for six hours while the server CPU sits at a comfortable twelve percent.

The infrastructure is healthy. The business logic is on fire.

You cannot solve this with container metrics. A workflow execution is a long-running, stateful transaction that may span thirty seconds, touch five external APIs, and process two hundred items in a loop. You need to trace the execution, not the server.

Execution-Centric Monitoring

Key takeaway

Stop asking "Is n8n up?" and start asking "Did the execution finish correctly?" The server can be up while your most critical workflow fails continuously.

The first shift is mental. In my experience, the majority of production incidents I get called in for look like this: the workflow is active, the trigger is firing, and the execution log is a wall of red that nobody noticed because there was no error workflow attached.

Every production workflow needs an error workflow configured in its settings. No exceptions. It takes thirty seconds and prevents silent failures from rotting for days. The error workflow receives the execution ID, the workflow name, the failing node, and the error message. That payload is the starting point for every triage.

I treat each execution like a distributed trace. I want to know when it started, how long each node took, whether it hit any retries, and what the final state was. The n8n execution detail view shows per-node timing, and I use it constantly. When a workflow is slow, I do not guess. I open a completed execution and look at the timing panel. The bottleneck is almost always a single node: an unbatched HTTP Request inside a loop making two hundred serial calls, a database query missing an index, or a Code node processing thousands of items without batching.

Prune aggressively, keep failures

An execution table can swell to millions of records and tens of gigabytes in under three months on a busy instance. Prune successful execution data after 72 hours; keep failures for a week. Failures are the signal. Successes are noise after you verify they're routine.

The Three-Questions Check

When an alert fires, I run the same three questions every time.

Framework · The three-questions check

When an alert fires: What's broken? Since when? What's the blast radius? These questions keep you from panic-rolling back a working deployment or restarting a healthy database.

  • What's broken? The error workflow tells me the workflow name, the exact node that threw, and the error message. I do not start by opening the editor and staring at the canvas. I start with the execution URL.
  • Since when? n8n stores the complete input and output data for every execution. When a workflow that has run successfully two hundred times suddenly fails, I compare the failing execution against the last successful one side by side. The difference in input data is almost always the cause.
  • What's the blast radius? If one workflow is failing, it is a logic bug. If every workflow is failing simultaneously, it is infrastructure. A PostgreSQL lock, a Redis outage in queue mode, or a network partition looks different from a bad expression in a single workflow. The blast-radius question tells me whether to page the platform engineer or debug the workflow logic. I decide in under sixty seconds.

The Metrics That Matter

You do not need a wall of graphs. You need three numbers, tracked per workflow, not globally.

  • Success rate. Percentage of executions in the last rolling window (usually 100 executions) that completed without triggering the error workflow. Global success rate is meaningless. A 99% global average means nothing if the 1% failure is your payment handler. For critical workflows, expect 99.5%+. Below 95%, investigate immediately.
  • P95 duration. Averages lie. A webhook handler that finishes in two seconds on average but takes 120 seconds at the 95th percentile is a time bomb. Your webhook provider will not care about your average when it starts timing out and retrying. If P95 drifts above twice the normal baseline for more than an hour, treat it as a pre-failure condition.
  • Retry rate. Every node that calls an external API should have retry-on-fail enabled. But retries are a symptom, not a solution. If a node retries more than five times per hundred executions, the integration is flaky. A rising retry rate predicts a hard outage before it happens.

Where do these numbers come from? I build a scheduled health-check workflow that queries the n8n internal API every hour:

// Code node: Query recent execution health
const baseUrl = $env.N8N_HOST || 'http://localhost:5678';
const apiKey = $env.N8N_API_KEY;

const response = await this.helpers.httpRequest({
  method: 'GET',
  url: `${baseUrl}/api/v1/executions`,
  headers: { 'X-N8N-API-KEY': apiKey },
  qs: {
    status: 'error',
    limit: 100,
    startedAfter: new Date(Date.now() - 60 * 60 * 1000).toISOString()
  }
});

const failed = response.data || [];
const byWorkflow = {};

for (const exec of failed) {
  const name = exec.workflowData?.name || 'Unknown';
  if (!byWorkflow[name]) byWorkflow[name] = 0;
  byWorkflow[name]++;
}

return [{
  json: {
    totalFailures: failed.length,
    byWorkflow,
    checkTime: new Date().toISOString()
  }
}];

If the health check itself starts failing, you know the problem is deeper than any single workflow.

Alert Routing: Not Every Alert Pages

Framework · Severity routing

The error workflow is the intake. Where the alert goes next is the decision that determines whether you sleep through the night. Build one centralised error handler, point every production workflow at it, classify by severity, fan out to the right channel.

Not every error warrants a page. A batch-import workflow that handles ten thousand records and fails on forty-seven of them because of invalid email addresses is a data quality issue. It needs to land in a review queue for the data team. A payment processing workflow that fails once is a revenue issue. It needs to wake someone up.

  • Critical workflows (order processing, payment handling, user auth) → PagerDuty and a high-priority Slack channel.
  • Warning patterns (rate limits, timeouts, 503s) → standard alerts channel for review during business hours.
  • Expected item-level failures in batch operations → dead-letter queue or review log, not a human.
// Code node: Severity classifier
const errorData = $input.first().json;
const workflowName = errorData.workflow?.name || 'Unknown';
const errorMessage = errorData.execution?.error?.message || '';

let severity = 'info';
const criticalWorkflows = ['Order Processing', 'Payment Handler', 'User Auth'];
const warningPatterns = ['rate limit', 'timeout', '503', '429'];

if (criticalWorkflows.some(w => workflowName.includes(w))) {
  severity = 'critical';
} else if (warningPatterns.some(p => errorMessage.toLowerCase().includes(p))) {
  severity = 'warning';
}

return [{
  json: {
    severity,
    workflowName,
    errorMessage,
    executionUrl: errorData.execution?.url,
    slackMessage: `*${severity.toUpperCase()}* ${workflowName}: ${errorMessage}`
  }
}];

Alert fatigue is how you miss a real outage buried in a thousand notifications. Separate your channels by urgency.

Dashboards for Workflow Ops

I do not believe in single panes of glass. They become wallpaper. If a dashboard is open on a screen that nobody looks at, it is decorative, not operational.

What I build instead is targeted visibility for three specific failure modes:

  • The daily health digest. A scheduled workflow emails me the last 24 hours: total executions, failure count per workflow, and any scheduled workflows that did not run. I care deeply about the "silent dog" problem. A missed schedule is worse than a failed execution because a failed execution leaves an error log. A schedule that never fires leaves nothing.
  • The slow-outlier list. Any execution whose duration exceeds twice the rolling average for that workflow. This catches logic errors that do not fail but burn time and money.
  • The dependency status board. A workflow that pings the external APIs my stack depends on — Stripe, SendGrid, HubSpot — and confirms they respond within their SLA. External dependency health is part of your workflow observability, not a separate concern.

If you need a UI, use n8n's own execution list filtered to errors, or use an external monitor like Uptime Kuma to check the /healthz endpoint, the editor, and a dedicated test webhook path. But stop trying to build a dashboard that mimics infrastructure monitoring.

Monitoring External Dependencies

Your workflow stack does not live in a vacuum. The most common root cause of failures I see is not bad workflow logic; it is a downstream API changing its behaviour or going offline.

There are two layers to this. First, harden the integration. Any node calling an external API should have retry-on-fail enabled with sensible defaults: three retries for fast APIs, two with longer waits for slow ones, and five with ten-second delays for rate-limited endpoints. But retries only help transient failures.

For fragile integrations, I implement a circuit breaker. After three consecutive failures, the workflow stops calling the API and sends an alert. It tests recovery every five minutes. This protects your execution capacity and prevents you from becoming a denial-of-service attack against a struggling provider.

Second, monitor the dependency proactively. A circuit breaker tells you the API is down after your workflows have already failed. A proactive monitor tells you before the hard failures start. The dependency status board is this monitor — a canary workflow that hits the API with a cheap request and measures response time.

Treat signature failures as security, not reliability

For webhooks coming into your stack, monitoring is also a security concern. Stripe, GitHub, Shopify, and Twilio all sign their payloads. A forged webhook event deactivating user accounts is a security incident, not a reliability issue. If signature verification fails, treat it as a critical security alert, not a routine error.

What to Do Monday Morning

You do not need a week-long observability initiative.

Set an error workflow on every production workflow

Thirty seconds per workflow. Do it now. No exceptions. An unhandled error that silently accumulates in the execution log is technical debt that compounds into an incident.

Build one centralised error handler with severity levels

Route critical errors to the channel where you will actually see them immediately. Route everything else to a review queue. Test the routing by deliberately breaking a credential and triggering the workflow.

Find and fix the slowest node in your highest-volume workflow

Inspect its last twenty executions. Find the P95 duration and identify the slowest node. Optimise that one node. It is usually an unbatched API call or a missing database index.

Schedule a quarterly fire drill for your error paths

Temporarily break a credential, trigger a failure, and verify the alert reaches its destination. Untested alerting is broken alerting. I have seen error workflows that have been silently failing for months because someone renamed the Slack channel they posted to.

Workflow monitoring is not about prettier charts. It is about answering the three questions — what's broken, since when, blast radius — in under two minutes at 2 AM. That is the difference between a minor fix and a morning of panic.