A service mesh abstracts network communication between microservices โ but it also creates a rich observability layer. Istio, Linkerd, and Consul Connect all expose metrics, traces, and connection security status automatically, without requiring changes to your application code. This guide covers how to use that data effectively to monitor production systems.
What Service Meshes Monitor by Default
Every major service mesh injects a sidecar proxy alongside your application containers. That proxy observes all incoming and outgoing traffic and reports:
- Request volume: Requests per second (RPS) per service-to-service edge.
- Success rate: Percentage of requests returning 2xx vs. 4xx/5xx โ the most important signal.
- Latency percentiles: P50, P90, P99, P999 per service.
- mTLS status: Whether connections are mutually authenticated (security posture visibility).
- Retries and timeouts: How often the mesh is retrying or timing out requests (circuit breaker activity).
This is essentially the Four Golden Signals โ latency, traffic, errors, and saturation โ applied at every service boundary automatically.
Istio Monitoring
Key Istio Metrics
Istio's Envoy sidecars expose metrics at /stats/prometheus. The most important standard metrics:
istio_requests_totalLabels: source_workload, destination_service, response_code
Total request count by source, destination, and status code
istio_request_duration_millisecondsLabels: source_workload, destination_service, response_code
Histogram of request latencies
istio_request_bytesLabels: source_workload, destination_service
Request payload sizes (histogram)
istio_tcp_connections_opened_totalLabels: source_workload, destination_workload
TCP connection count for L4 traffic
Essential Istio PromQL Queries
# Success rate per destination service (last 1 minute)
sum(rate(istio_requests_total{destination_service_name="payments", response_code!~"5.*"}[1m]))
/
sum(rate(istio_requests_total{destination_service_name="payments"}[1m]))
# P99 latency for a specific service
histogram_quantile(0.99,
sum(rate(istio_request_duration_milliseconds_bucket{
destination_service_name="payments"
}[5m])) by (le)
)
# Request rate per service (RPS)
sum(rate(istio_requests_total{destination_service_namespace="production"}[1m]))
by (destination_service_name)Kiali: Istio's Service Graph Dashboard
Kiali is the canonical Istio observability UI. It visualizes the service topology as a graph where edge thickness indicates traffic volume and edge color indicates success rate (green = healthy, red = high error rate). Install Kiali alongside Istio and connect it to your Prometheus instance for real-time service graph data.
๐ก Monitor your services uptime every 30 seconds โ get alerted in under a minute
Trusted by 100,000+ websites ยท Free tier available
Linkerd Monitoring
Linkerd's Golden Signals Dashboard
Linkerd's linkerd viz extension installs a Prometheus instance and a pre-built Grafana dashboard. The CLI also provides a real-time golden signals view:
# Real-time golden signals for all deployments linkerd viz stat deployments -n production # Per-route metrics for a specific service linkerd viz routes svc/payments -n production # Live tail of requests to a specific pod linkerd viz tap deployment/payments -n production --to svc/database
Key Linkerd Prometheus Metrics
response_totalTotal responses by classification (success/failure/l5d-proxy-error)
response_latency_msLatency histogram with source and destination labels
tcp_open_connectionsCurrent open TCP connections (saturation signal)
route_response_totalPer-HTTP-route request counts (with ServiceProfile routes configured)
Consul Connect Monitoring
Consul Connect uses Envoy sidecars (same as Istio) and exposes metrics via the Consul agent. Consul's metrics cover both the service mesh layer and the service registry:
# Consul agent metrics endpoint (statsd format by default)
# Enable Prometheus metrics in consul agent config:
{
"telemetry": {
"prometheus_retention_time": "60s",
"disable_hostname": true
}
}
# Key metrics to watch:
# consul.health.service.passing โ services with passing health checks
# consul.health.service.warning โ services with warning health checks
# consul.health.service.critical โ services with critical health checks (alert on this)
# consul.rpc.request โ RPC request rate to Consul serversDistributed Tracing in Service Meshes
Service mesh proxies can participate in distributed tracing but require application cooperation for end-to-end traces:
Critical: Header Propagation Required
Service mesh proxies inject trace headers (B3 or W3C) into incoming requests. For traces to be connected across services, your application code must extract these headers from incoming requests and inject them into all outgoing requests. Failing to propagate headers creates disconnected trace fragments.
Istio Distributed Tracing Configuration
# MeshConfig: configure Jaeger as the tracing backend
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
meshConfig:
enableTracing: true
defaultConfig:
tracing:
sampling: 10.0 # 10% sampling rate
extensionProviders:
- name: jaeger
opentelemetry:
port: 4317
service: jaeger-collector.monitoring.svc.cluster.localProduction Alerting Rules for Service Meshes
# Prometheus alert rules for Istio
groups:
- name: service-mesh
rules:
- alert: HighErrorRate
expr: |
sum(rate(istio_requests_total{response_code=~"5.*"}[5m]))
/
sum(rate(istio_requests_total[5m])) > 0.05
for: 5m
labels:
severity: critical
annotations:
summary: "Error rate > 5% in service mesh"
- alert: HighP99Latency
expr: |
histogram_quantile(0.99,
sum(rate(istio_request_duration_milliseconds_bucket[5m])) by (le, destination_service_name)
) > 1000
for: 10m
labels:
severity: warning
annotations:
summary: "P99 latency > 1s for {{ $labels.destination_service_name }}"
- alert: ServiceMTLSNotMutual
expr: |
sum(istio_requests_total{connection_security_policy!="mutual_tls"}) > 0
for: 1m
labels:
severity: warning
annotations:
summary: "Traffic detected without mTLS"
Monitor the external endpoints your service mesh exposes
Better Stack monitors your ingress gateway URLs and external API health endpoints with 30-second check intervals. Complete the observability picture beyond the mesh.
Try Better Stack Free โService Mesh vs. Application-Level Monitoring
A common misconception is that a service mesh replaces application-level instrumentation. It doesn't โ the two are complementary:
Service mesh monitors
- Network-level latency (at proxy)
- HTTP status codes at L7
- mTLS and security policy compliance
- TCP connections and bytes
- Service-to-service topology
Application instrumentation monitors
- Business metrics (orders/sec, checkout value)
- Database query time (within the pod)
- Cache hit/miss rates
- Queue depth and consumer lag
- Custom error types beyond HTTP status codes
Frequently Asked Questions
What metrics does Istio expose by default?
Istio exposes request count (istio_requests_total), request duration histogram (istio_request_duration_milliseconds), byte sizes (istio_request_bytes, istio_response_bytes), and TCP metrics. All include source/destination workload and namespace labels plus HTTP response code.
How does Linkerd monitoring differ from Istio?
Linkerd uses a lightweight Rust-based proxy and exposes simpler golden signal metrics (success rate, RPS, latency) with no configuration. Istio's Envoy sidecar provides more granular metrics but requires more resources. Linkerd's built-in linkerd viz dashboard provides immediate golden signal visibility; Istio's equivalent is Kiali.
Do I still need application-level metrics if I have a service mesh?
Yes โ the mesh monitors network-layer metrics at the proxy. Business metrics (order volume, user sign-ups), internal latency (database query time, cache performance), and custom application errors are invisible to the mesh and require application-level instrumentation.
How do I get end-to-end distributed traces across a service mesh?
Configure your mesh to send traces to a backend (Jaeger, Tempo, Honeycomb). Critically, your application code must propagate B3 or W3C TraceContext headers from incoming requests to all outgoing requests. Without this propagation, traces from different services appear as disconnected fragments.
Related Monitoring Guides
Alert Pro
14-day free trialStop checking โ get alerted instantly
Next time your microservices goes down, you'll know in under 60 seconds โ not when your users start complaining.
- Email alerts for your microservices + 9 more APIs
- $0 due today for trial
- Cancel anytime โ $9/mo after trial