Definition
- Flink Web Dashboard – A built-in UI served by the JobManager that visualizes the job graph, per-operator backpressure, checkpoint history, watermarks, and exceptions.
- Flink Metrics System – Exports numeric time series through reporters (Prometheus, Datadog) for dashboards, historical trends, and alerting.
- Key throughput metrics – numRecordsInPerSecond and numRecordsOutPerSecond per operator.
- Key checkpoint metrics – lastCheckpointDuration, lastCheckpointSize, and completed/failed checkpoint counts.
- Key state metrics – State size per operator, visible via checkpoint size.
- Key backpressure metrics – busyTimeMsPerSecond, backPressuredTimeMsPerSecond, idleTimeMsPerSecond per operator.
- Consumer lag – For Kafka sources, records-lag-max tells whether the job is keeping up with input.
Running a Flink job at the National Bank of India is like running the payments processing line in a branch. The Web Dashboard is the live camera feed on the wall: you see each station, whether any station has a queue forming behind it, and whether the overnight safe-backup finished on time. The metrics system is the set of sensors wired to head office (Prometheus and Grafana), recording throughput, delays, and backup times minute by minute, with alarms that page the on-call engineer when something trends the wrong way.
Understanding the Concepts
What does the Flink Web Dashboard show?
The Web Dashboard, served by the JobManager, is the first stop for live inspection. It shows the logical and physical job graph, per-operator parallelism, backpressure status, checkpoint history, watermark progress, and recent exceptions.
Flink Web Dashboard tabs:
Overview: Job graph with operator parallelism
Backpressure: Per-operator backpressure status (colored)
Checkpoints: History, duration, size, success/failure
Watermarks: Event-time progress per operator
Exceptions: Recent failures and restarts
Metrics: Raw metric values per operator
Access: http://jobmanager-host:8081
package com.bank.monitoring;
// The Web Dashboard is built-in, no code needed
// Access at: http://jobmanager:8081
//
// Key views for NBI fraud pipeline:
// 1. Job graph: verify operator chain and parallelism
// 2. Backpressure tab: spot which operator is bottleneck
// 3. Checkpoints tab: verify checkpoints are completing
// 4. Exceptions tab: check for recent failures
How do you export metrics to Prometheus and Grafana?
Flink exposes metrics through reporters. The most common setup uses the Prometheus reporter, which publishes an endpoint that Prometheus scrapes. Grafana then builds dashboards and alerts from the scraped data.
# flink-conf.yaml: enable Prometheus reporter
metrics.reporter.prom.factory.class:
org.apache.flink.metrics.prometheus.PrometheusReporterFactory
metrics.reporter.prom.port: 9249
# Prometheus scrape config:
scrape_configs:
- job_name: 'flink'
static_configs:
- targets: ['taskmanager-1:9249', 'taskmanager-2:9249']
package com.bank.monitoring;
public class PrometheusMetricsDemo {
// Key Prometheus queries for Grafana dashboards:
//
// Throughput:
// flink_taskmanager_job_task_operator_numRecordsInPerSecond
// flink_taskmanager_job_task_operator_numRecordsOutPerSecond
//
// Checkpoint duration:
// flink_jobmanager_job_lastCheckpointDuration
//
// Checkpoint size:
// flink_jobmanager_job_lastCheckpointFullSize
//
// Backpressure:
// flink_taskmanager_job_task_busyTimeMsPerSecond
// flink_taskmanager_job_task_backPressuredTimeMsPerSecond
//
// Kafka lag:
// flink_taskmanager_job_task_operator_KafkaConsumer
// _records_lag_max
}
What does increasing checkpoint duration indicate?
Steadily increasing checkpoint duration usually means state is growing or the state backend is under pressure. If a checkpoint cannot finish before the next one starts, the job can stall.
Checkpoint duration trend:
Time Duration State Size Status
10:00 2.1s 500 MB Healthy
10:05 3.4s 650 MB Growing
10:10 5.8s 900 MB Warning
10:15 12.1s 1.4 GB Danger
10:20 TIMEOUT 1.9 GB STALL
Root cause: state growing without bound
Fix: add state TTL, enable incremental checkpoints,
increase managed memory
// Prometheus alert for checkpoint duration
// alert: FlinkCheckpointSlowing
// expr: rate(flink_jobmanager_job_lastCheckpointDuration[10m]) > 0.5
// for: 10m
// labels:
// severity: warning
// annotations:
// summary: "Checkpoint duration increasing for {{ $labels.job_name }}"
What does growing state size indicate?
Continuously growing state with no plateau signals a state leak. The most common cause is keyed state that is never cleaned up, such as a per-key map or timer that grows without bound.
package com.bank.monitoring;
import org.apache.flink.api.common.state.StateTtlConfig;
import org.apache.flink.api.common.state.ValueStateDescriptor;
import org.apache.flink.api.common.time.Time;
public class StateLeakFixDemo {
// PROBLEM: state grows without bound
// Per-account MapState with entries never removed
// State size: 500MB -> 1GB -> 2GB -> 4GB -> OOM
// FIX 1: State TTL (automatic cleanup)
public static ValueStateDescriptor<String> ttlState() {
ValueStateDescriptor<String> desc =
new ValueStateDescriptor<>("accountData", String.class);
StateTtlConfig ttl = StateTtlConfig
.newBuilder(Time.hours(24))
.setUpdateType(StateTtlConfig.UpdateType.OnCreateAndWrite)
.cleanupFullSnapshot()
.build();
desc.enableTimeToLive(ttl);
return desc;
}
// FIX 2: Explicit cleanup in onTimer
// Register cleanup timer when state is created
// Clear state when timer fires
}
What does backpressure on a specific operator indicate?
Backpressure concentrated on one operator identifies the bottleneck. That operator cannot keep up, so everything upstream slows. The busy operator has high busyTime and zero backPressuredTime.
Backpressure diagnosis:
Operator Busy% BackPressured% Idle%
────────── ───── ────────────── ─────
KafkaSource 12% 83% 5% <-- waiting
Enricher 18% 77% 5% <-- waiting
FraudScorer 95% 0% 5% <-- BOTTLENECK
AlertSink 30% 0% 70% <-- idle
FraudScorer is the bottleneck:
- 95% busy (doing work)
- 0% backpressured (not waiting on anyone downstream)
- Everything upstream is backpressured behind it
Fix: increase FraudScorer parallelism, optimize scoring logic,
or check for key skew
// Grafana query to find the bottleneck operator:
// SELECT operator, avg(busyTimeMsPerSecond)
// FROM flink_task_metrics
// WHERE backPressuredTimeMsPerSecond < 50
// AND busyTimeMsPerSecond > 900
// This finds operators that are busy but NOT backpressured
// = they are the bottleneck
What does rising Kafka consumer lag indicate?
Rising Kafka lag means the job as a whole is slower than the input rate. This ties back to backpressure: the pipeline cannot consume as fast as the source produces, so unconsumed records accumulate in Kafka.
Kafka lag trend:
Time Lag (records) Throughput (rec/s) Status
10:00 1,000 10,000 Healthy
10:05 15,000 8,000 Falling behind
10:10 50,000 6,000 Growing lag
10:15 150,000 5,000 Critical
Root cause: throughput < input rate
Fix: find backpressured bottleneck, increase parallelism,
optimize slow operator, or scale external system
// Prometheus alert for Kafka lag
// alert: FlinkKafkaLagHigh
// expr: flink_kafka_consumer_records_lag_max > 100000
// for: 5m
// labels:
// severity: critical
// annotations:
// summary: "Kafka lag exceeding 100K for {{ $labels.topic }}"
How do you correlate metrics to find root cause?
The real skill is correlating multiple metrics into a single root-cause story. Backpressure plus rising lag plus a busy operator points directly at the culprit.
Correlation example:
Observation 1: Kafka lag growing
Observation 2: Checkpoint duration increasing
Observation 3: FraudScorer 95% busy, 0% backpressured
Observation 4: State size growing for FraudScorer
Root cause story:
FraudScorer has a state leak (state never cleaned up)
--> state grows
--> checkpoint size and duration increase
--> FraudScorer becomes bottleneck (slow state access)
--> backpressure propagates upstream
--> source slows, Kafka lag grows
Fix: add state TTL to FraudScorer
Result: state plateaus, checkpoints shrink,
backpressure clears, lag drains
What should a senior engineer know about monitoring?
A senior engineer should alert on trends rather than absolute values, correlate metrics across operators, watch failed-checkpoint and restart counts, and enable latency markers only when investigating because they add overhead.
package com.bank.monitoring;
public class SeniorMonitoringChecklist {
// Senior monitoring checklist for NBI Flink jobs:
//
// 1. Alert on checkpoint duration TREND (rate of change)
// not just absolute value
// 2. Alert on state size GROWTH (sustained increase)
// 3. Alert on Kafka lag exceeding threshold
// 4. Monitor restart count (frequent restarts = hidden problem)
// 5. Monitor failed checkpoint count
// 6. Correlate: backpressure + lag + busy operator = root cause
// 7. Latency markers: enable only during investigation
// (they add overhead in high-throughput jobs)
// 8. Set up PagerDuty/OpsGenie alerts for critical metrics
//
// Grafana dashboard panels:
// Row 1: Throughput (records/sec) per operator
// Row 2: Checkpoint duration + size
// Row 3: Backpressure per operator (busy/backpressured/idle)
// Row 4: Kafka consumer lag
// Row 5: State size per operator
// Row 6: Restart count + failed checkpoints
}
Visual Overview
Flink Monitoring Architecture
┌────────────────────────────────────────────────┐
│ Flink Cluster │
│ │
│ JobManager ──▶ Web Dashboard (:8081) │
│ │ (job graph, checkpoints, │
│ │ backpressure, exceptions) │
│ │ │
│ TaskManager-1 ──▶ Prometheus Reporter (:9249) │
│ TaskManager-2 ──▶ Prometheus Reporter (:9249) │
│ TaskManager-3 ──▶ Prometheus Reporter (:9249) │
└────────────────────────┬───────────────────────┘
│ scrape
▼
┌────────────────────────────────────────────────┐
│ Prometheus Server │
│ (stores time-series metrics) │
└────────────────────────┬───────────────────────┘
│ query
▼
┌────────────────────────────────────────────────┐
│ Grafana Dashboards │
│ ┌──────────┐ ┌──────────┐ ┌───────────────┐ │
│ │Throughput│ │Checkpoint│ │ Backpressure │ │
│ │ rec/sec │ │ duration │ │ per operator │ │
│ └──────────┘ └──────────┘ └───────────────┘ │
│ ┌──────────┐ ┌──────────┐ ┌───────────────┐ │
│ │Kafka Lag │ │State Size│ │ Restart Count │ │
│ └──────────┘ └──────────┘ └───────────────┘ │
│ │
│ Alert Rules ──▶ PagerDuty / OpsGenie │
└────────────────────────────────────────────────┘
Trouble Indicators:
Metric Healthy Trouble
────── ─────── ───────
Checkpoint duration 2-5s stable Growing toward interval
State size Plateau Continuous growth
Backpressure None Concentrated on 1 operator
Kafka lag < 1000 Growing without bound
Restart count 0 Increasing
Key Takeaway
Monitoring a Flink job combines the built-in Web Dashboard with the metrics system exported to Prometheus and Grafana. The Web Dashboard is the first stop for live inspection: it shows the job graph, per-operator backpressure, checkpoint history, watermark progress, and recent exceptions. For continuous monitoring, the Prometheus reporter exports metrics that Grafana visualizes with dashboards and alerts.
The real skill is interpreting the metrics. Steadily increasing checkpoint duration means state is growing or the backend is under pressure. Continuously growing state with no plateau signals a state leak. Backpressure concentrated on one operator identifies the bottleneck. Rising Kafka lag means the job is slower than the input rate. The senior insight is to alert on trends and correlate metrics: backpressure plus rising lag plus a busy operator points straight at the culprit.
At the National Bank of India, our real-time fraud job started missing latency targets. Rather than guess, I read the metrics. State size was climbing with no plateau, checkpoint duration was lengthening, the fraud operator's backpressure was rising, and Kafka lag was increasing. Correlating those told a single story: the fraud operator had a state leak that made it the bottleneck. The fix was adding state TTL, after which state plateaued, checkpoints shrank, backpressure cleared, and lag drained.
Being able to name which metric reveals which failure mode, correlate them into a root cause, and alert on trends instead of reacting after a crash is exactly what keeps a production streaming platform healthy.
Remember one sentence: Monitor checkpoint duration, state size, operator backpressure, and Kafka lag, and correlate them to find the root cause before the job crashes.
---