Grafana Interview Questions

High Availability Deployment

questions
Scroll to track progress

Your Grafana instance (single node) serves 200 dashboards to 500 users. It's in your critical path: if Grafana is down, your entire on-call team is blind during incidents. You have 99.95% uptime SLA. Design a high-availability Grafana deployment that survives node failures, database failures, and network partitions.

Implement multi-layer HA architecture: (1) Load balancing—deploy 3+ Grafana nodes behind a load balancer (ALB, nginx). Distribute user sessions across nodes. (2) Shared database—use managed PostgreSQL (RDS, Cloud SQL) with automatic failover. All Grafana nodes read/write to shared database, ensuring consistent state. (3) Session distribution—use sticky sessions or distributed session store (Redis) so user sessions survive node failures. (4) Data consistency—database replication ensures if primary DB fails, replicas take over. Use synchronous replication for zero data loss. (5) Network resilience—deploy Grafana nodes across multiple availability zones (AZs). If one AZ fails, traffic routes to other AZs. (6) Health checks—load balancer performs health checks on Grafana nodes every 5s. Unhealthy nodes are removed from rotation. (7) Graceful degradation—if 1 of 3 nodes fails, service continues at 67% capacity. Auto-scaling triggers to add replacement node. Implement monitoring of HA metrics: node health status, database replication lag, session distribution. Alert if any node is unhealthy. Test failover monthly: kill a node, verify traffic routes to others, user experience is seamless. Set up automated rollback: if a Grafana update causes health check failures, auto-roll back. For critical incidents, implement manual override: switch to read-only mode (serve cached dashboards) to reduce load on database. Document runbook: failure scenarios and recovery steps.

Follow-up: Your database is in us-east. If an earthquake takes down the entire us-east region, all Grafana nodes lose database connectivity. How would you architect for regional failover?

Your Grafana nodes are deployed in Kubernetes. During an update, you need to restart all pods to deploy new version. Currently, restarting a pod causes user sessions to drop (live dashboard viewers lose their data). Design a zero-downtime update process.

Implement zero-downtime deployment: (1) Rolling updates—use Kubernetes rolling deployment: replace 1 pod at a time, waiting for it to become healthy before replacing the next. During update, 90% of pods are always available. (2) Pod disruption budgets—set PodDisruptionBudget: ensure at least 2 pods are always available. Kubernetes won't evict 3rd pod during update if it would violate this. (3) Graceful shutdown—when Grafana receives termination signal, it waits for in-flight requests to complete before exiting (graceful drain). Set terminationGracePeriodSeconds to 30s. (4) Connection draining—update load balancer to drain connections from pod being removed, preventing new requests from routing to it. (5) Health check timing—use readinessProbe to signal when pod is ready to serve requests. Only traffic is routed after readiness check passes. (6) Session persistence—use Redis-backed sessions so if a user's session moves to a different pod, they're not logged out. (7) Smoke testing—after each pod becomes ready, run synthetic tests to verify health (API calls, dashboard loads). Alert if test fails; auto-rollback. Implement canary deployments: deploy new version to 1 pod, run 10 minutes of smoke tests, then roll out to remaining pods. Monitor error rates during roll out; if 5x increase, auto-roll back. Set up automated rollback: if pod health checks fail repeatedly after update, auto-revert to previous version. Document runbook: expected downtime (zero), rollback procedure, manual intervention steps.

Follow-up: Your graceful drain waits 30 seconds, but long-running requests (large dashboard export) can take 5 minutes. Pods are force-killed mid-request, causing user visible failures. How do you handle long-running requests?

Your Grafana cluster has 3 nodes. A networking issue causes a split-brain partition: 2 nodes on one side, 1 node on the other. Both groups think they're the primary and issue conflicting writes to the database. Dashboards are now inconsistent: some users see old versions, others see new. Design recovery from split-brain scenarios.

Implement split-brain detection and recovery: (1) Database quorum writes—require quorum (2 out of 3 database replicas) to acknowledge writes. If split-brain occurs, minority partition (1 node) can't write, preventing divergence. (2) Session clustering—use distributed session locks (Redis/etcd). If partition occurs, node holding lock continues serving; other partitions go read-only. (3) Fencing—implement fencing mechanism: if a node detects network partition, it alerts ops and stops accepting writes. (4) Conflict resolution—if writes do diverge, implement last-write-wins with timestamps. During recovery, merge conflicts and alert admin for manual review. (5) Recovery procedure—when partition heals, detect conflicts and resolve: prioritize recent writes, keep audit trail. (6) Read-only fallback—during partition, allow read-only queries (serve cached dashboards). Writes are queued and replay after partition heals. (7) Alerting—immediately alert ops on partition detection: "split-brain detected. Serving read-only." Measure MTTR (mean time to resolve). For the conflict in the scenario, implement dashboard version comparison: show which version is newer, what changed, allow manual selection of version to keep. Set up automated tests simulating partitions: kill network connectivity between nodes, verify proper behavior. Recovery time target: <5 minutes from partition heal to full consistency. Document runbook: partition symptoms, recovery steps, when to escalate to AWS/cloud provider.

Follow-up: Your split-brain recovery worked, but now user A sees dashboard version from 2 hours ago while user B sees current version. They're debugging together and see conflicting data. How do you reconcile eventually-consistent state for users?

Your Grafana cluster experiences a cascading failure: load balancer routes traffic to an unhealthy node; that node times out; load balancer marks it unhealthy; traffic routes to remaining nodes; they get overloaded; health checks start failing; they get marked unhealthy too. Within 2 minutes, all nodes are down. Design a defensive system against cascading failures.

Implement cascading failure prevention: (1) Load balancing strategy—use connection draining and timeout tuning: if a node responds slowly (>5s), reduce traffic to it gradually instead of abruptly. (2) Circuit breaker—implement circuit breaker: if backend returns errors on >50% of requests, circuit-break that backend (return errors to clients instead of retrying). This prevents pile-up. (3) Slow-client detection—if a client requests a dashboard that takes forever to load, timeout the request and try different backend. Don't wait for first backend. (4) Bulkhead isolation—separate connection pools for different dashboard types (small/fast vs. large/slow). This prevents one type from consuming all connections. (5) Adaptive health checks—health check timeout increases with load: under light load, timeout is 2s; under heavy load, increase to 5s. This prevents false-positive failures. (6) Request shedding—when Grafana hits 90% CPU, start rejecting requests (HTTP 503). Better to fail fast than cascade. (7) Graceful queue shedding—if request queue is growing (backlog building), drop lowest-priority requests (P2: exports) instead of queueing forever. Implement comprehensive metrics: latency distribution, error rate by backend, health check pass/fail rate, queue depth. Build alerting on early warning signs: "queue depth growing, suggesting overload." Implement load testing: simulate traffic ramp, measure at what point cascading failure begins. Set target: "should handle 2x peak traffic without cascading failure." Create runbook for overload events: manual traffic shaping steps, emergency fallback (read-only mode), escalation path.

Follow-up: Your request shedding returns HTTP 503 to users. Users are confused—they don't know why dashboards are failing. How do you communicate unavailability gracefully?

Your Grafana deployment is behind a reverse proxy (nginx) that terminates SSL/TLS. During peak traffic (10K requests/sec), the nginx layer becomes a bottleneck. SSL handshakes are timing out. Design a scalable SSL/TLS strategy.

Implement scalable SSL/TLS: (1) SSL termination distribution—instead of single nginx, deploy multiple SSL-terminating proxies (Layer 7 LBs) behind a network LB (Layer 4 LB). Layer 4 LB distributes TCP connections across proxy layer. (2) SSL session resumption—enable server-side SSL session caching (tickets). Clients resuming sessions skip full handshake, reducing overhead. (3) SSL/TLS version tuning—prefer TLS 1.3 (faster than 1.2). Disable old protocols (SSL 3.0, TLS 1.0). (4) Certificate management—use short-lived certificates (renew every 3 months) to reduce compromise window. Automate renewal with cert-manager. (5) Connection multiplexing—use HTTP/2 or HTTP/3 (QUIC). These multiplex multiple requests over single connection, reducing handshake overhead. (6) Hardware acceleration—if available, use hardware SSL offload (specialized network cards). Speeds up encryption/decryption. (7) Monitoring—track SSL connection metrics: handshake latency, session hit rate, certificate expiry. Alert if handshake latency spikes. Implement load testing: measure max SSL handshakes/sec your infrastructure can handle. Test certificate rotation without downtime. For debugging performance, use OpenSSL s_client to measure handshake time directly. Document SSL/TLS architecture: certificate lifecycle, monitoring expectations, troubleshooting guide.

Follow-up: Your HTTP/2 implementation is enabling multiplexing, but you notice browsers are still opening multiple connections (not multiplexing). How do you diagnose and fix connection reuse?

Your Grafana cluster is deployed across us-east and us-west. A user in us-west connects to Grafana and experiences high latency (requests round-trip 5 times across US). You're not routing users to the nearest region. Design a geo-aware routing strategy.

Implement geo-aware routing: (1) Global load balancing—use global/geo-aware load balancer (AWS Global Accelerator, Cloudflare, DNS geo-routing). Route users to nearest regional endpoint. (2) DNS geo-routing—use DNS providers (Route53, Cloudflare) with latency-based or geolocation routing. When user queries DNS, return IP of nearest datacenter. (3) Regional Grafana instances—deploy Grafana instances in each region (us-east, us-west, eu-central). All instances share a replicated database for consistency. (4) Session affinity—once user is routed to a region, keep them in that region (sticky routing). Move between regions only if that region fails. (5) Data replication—replicate dashboard configurations, datasource settings, and user data across regions using database replication. Latency of replication is acceptable (eventual consistency). (6) Fallback routing—if nearest region is down, route to secondary region. Accept higher latency for availability. (7) Performance measurement—track latency to each region. Monitor for anomalies: "us-west latency suddenly 5x higher; investigate us-west connectivity." Create geo-aware dashboards: per-region metrics showing user experience by region. Test failover: take down us-west, verify users in west coast get routed to us-east gracefully. Document expected latencies: us-east user sees 50ms, us-west user sees 50ms, eu-west user sees 100ms to nearest region. Set up alerts: if latency to a region exceeds threshold, alert ops.

Follow-up: Your geo-routing works, but a user in London gets routed to us-east (wrong) instead of eu-central (correct). DNS geo-routing is unreliable. How would you improve routing accuracy?

Your Grafana database (PostgreSQL) is the single point of failure. If database goes down, all Grafana instances stop working (can't load dashboards, user info, etc.). Design a highly-available database layer.

Implement HA database architecture: (1) Replication—set up primary-replica replication: primary accepts writes, replicas replicate changes. If primary fails, promote replica to primary. (2) Automatic failover—use patroni, pgbouncer, or managed database service (RDS) with automatic failover. Detection time <30s; failover <60s. (3) Synchronous replication—configure synchronous replication: primary waits for replica to acknowledge writes. Zero data loss on failover. (4) Connection pooling—use pgbouncer to pool connections. Masks failover: clients reconnect to pool, which re-routes to new primary. (5) Read-only queries—scale reads by routing read queries to replicas. Reduce load on primary. (6) Backup and recovery—automated daily backups to S3 (point-in-time recovery). Test recovery monthly. (7) Monitoring—track database metrics: replication lag, query latency, connection pool utilization. Alert if lag >5s or primary unavailable. Implement database performance tuning: index optimization, slow query logging. For Grafana specifically, most queries are read-heavy; use replicas for dashboard queries. For critical writes (alert rule creation), go to primary. Set up canary: run representative workload on replica, compare performance to primary. Alert if divergence suggests replica corruption. Document recovery playbook: failover procedure, data recovery from backups, split-brain recovery.

Follow-up: Your database failover works, but during failover, queries briefly fail with "connection refused". A critical dashboard query fails. How do you handle brief unavailability?

Your Grafana infrastructure has redundancy at every layer: multiple nodes, load balancer, HA database, replicated storage. Despite all this, you had a 15-minute outage last month. Root cause: a bug in a Grafana update caused all instances to panic. Redundancy didn't help because all instances failed simultaneously. Design a defense-in-depth strategy against correlated failures.

Implement defense against correlated failures: (1) Canary deployments—deploy updates to 1 instance first. Run smoke tests for 30 minutes. If any errors, auto-rollback. Only then roll out to other instances. (2) Version pinning—don't auto-upgrade Grafana. Control upgrade cadence. Test updates in staging before production. (3) Feature flags—ship Grafana updates with new features disabled by default. Enable features gradually per team. If a feature causes panic, toggle it off. (4) Kill switch—implement emergency kill switch: if Grafana cluster is failing, ops can disable problematic feature via console. (5) Runbook-driven operations—document failure scenarios: what to do if Grafana panics, how to roll back. Train ops on runbook. (6) Blast radius limiting—segment Grafana deployments: critical dashboards on separate cluster from non-critical. If critical cluster fails, non-critical still works. (7) Read-only fallback—if Grafana logic is broken, serve cached dashboard versions (read-only mode) from static content or CDN. This buys time for engineering to fix. For the bug in the scenario, implement fuzzing: before releasing Grafana update, fuzz test core code paths with random inputs. Catch panics in staging. Set up continuous deployment testing: every Grafana PR runs through extended test suite (integration tests, performance tests, chaos testing). For on-call, implement an incident runbook: "Grafana cluster failing → enable read-only mode → investigatebug → roll back version → restore write mode." Recovery time target: <10 minutes from incident detection to restore. Document lessons learned: why single correlated failure took out all instances; what changed to prevent recurrence.

Follow-up: Your read-only fallback serves cached dashboards, but the cache is stale (1 hour old). A team is making critical deployment decisions based on stale metrics during the outage. What's acceptable staleness?

Want to go deeper?