Grafana database connection tuning for shared, high-load instances
Connection tuning controls how many database connections each Grafana node opens, how many it keeps idle, and how long a connection lives before Grafana replaces it. In a shared instance with many viewers, scheduled alert rules and more than one node writing to the same database, those settings decide whether requests queue inside Grafana or fail at the database. SQLite is not suited to production, and the Grafana installation docs require MySQL 8.0 or later, or PostgreSQL 12 or later, for production and high availability. The connection pool sits between Grafana's server process and that database, so every dashboard query that touches stored state, every alert evaluation that saves state and every login session competes for the same connections. The defaults may not fit a larger load, especially when several nodes multiply the total number of connections the database must accept.
The settings to review are the database section of grafana.ini (or the matching environment variables), which control the maximum open connections, maximum idle connections and connection lifetime. The exact keys, their defaults and their behavior differ by Grafana version, so confirm them against the documentation for the version you run before changing anything. The most common failure to plan for is a connection lifetime longer than the idle timeout of the database or of a network device between Grafana and the database. Grafana can then hand out connections the server has already closed, which shows up as intermittent errors rather than a clean outage. Set the lifetime below the shortest timeout in the path, and confirm that timeout with your database team, because MySQL server timeouts and proxy or load balancer timeouts are often configured separately.
Verify changes against Grafana's own metrics rather than by feel. Grafana's metrics endpoint exposes database-related series that you can scrape with Prometheus, and the same stack can show whether requests wait for connections. On the database side, compare the connection count with the sum of pool limits across all nodes, and check for lock waits and slow statements during alert evaluation peaks. Ask your database owner for the connection limit configured on the server, the headroom reserved for administrators and any connection pooler in front of the database. Connection tuning is one part of capacity planning, and the Grafana high availability documentation covers the shared database setup that makes multiple nodes possible.
Connection pool settings and when each one fits
This table compares the connection pool settings a team adjusts on Grafana's database connection, with the risk at each extreme and the load pattern that calls for a change. Read each row against your own user count, alert rule volume and database limits. The main takeaway is that raising pool sizes without checking the database's connection ceiling usually moves the bottleneck rather than removing it.
| Setting | What it limits | Risk if set too high or too low | Load pattern that calls for a change |
|---|---|---|---|
| Maximum open connections | Total connections Grafana holds open to the database at once, per instance | Too high: the database hits its connection ceiling and other clients fail. Too low: queries queue inside Grafana and dashboards and alert evaluations slow down. | Many concurrent viewers or a large alert rule count, with queueing visible in Grafana's database metrics |
| Maximum idle connections | Connections kept open in the pool when no query is running | Too high: idle sessions consume database memory and count against limits. Too low: each burst of requests pays the cost of opening new connections. | Spiky traffic, such as a scheduled report or a morning login wave, where connection setup time shows up in latency |
| Connection maximum lifetime | How long a single connection may be reused before Grafana closes and replaces it | Too long: connections outlive a database timeout or failover and fail on first use. Too short: constant reconnects add overhead and load. | Database or load balancer idle timeouts, failovers or proxy rotations that drop sessions silently |
| Connection idle timeout | How long an unused connection stays in the pool before it is closed | Too long: stale sessions wait to fail. Too short: the pool churns connections during quiet periods. | Long quiet periods followed by bursts, often overnight with few viewers but scheduled alert evaluations |
| Database engine and version | Which driver behavior, timeouts and connection limits apply, for example MySQL 8.0 or later or PostgreSQL 12 or later | Unsupported or old versions can lack behavior the team assumes. SQLite is not suited to production concurrency. | Any move to a new database engine, major version or managed service, where defaults and limits may change |
| External connection pooler (optional) | A proxy layer, such as PgBouncer for PostgreSQL, that multiplexes many client connections onto fewer database sessions | Adds a component to size, monitor and patch. Pool mode settings that do not match Grafana's transaction use can cause errors. | Many Grafana instances or high connection counts that exceed what the database should accept directly |
How MySQL and PostgreSQL change the tuning work
MySQL closes connections that stay idle longer than the server's timeout, and Grafana gets no warning when it happens. The next query on a dropped pooled connection then fails. Grafana's connection lifetime must therefore end before the server closes the connection, so the two values have to be set together. Your DBA owns the server value, so get it before you choose the Grafana value.
- Server idle timeout: Run
SHOW VARIABLES LIKE 'wait_timeout';and compare the result with the lifetime you plan to set in the[database]section asconn_max_lifetime. - Lifetime below the timeout: Keep Grafana's lifetime comfortably shorter than the server value so connections are recycled before MySQL drops them.
- 8.4 LTS track: The 8.4 LTS line receives only necessary fixes after its first release, which suits a database that stays in place for years.
- 8.0 and later: Grafana requires MySQL 8.0 or later, so confirm the exact build against the Grafana installation docs before you commit.
- Innovation releases: Innovation releases are supported only until the next Innovation release, so a long-lived Grafana database should not sit on that track.
Before go-live, idle an instance past the server timeout and confirm Grafana still loads dashboards without errors.
PostgreSQL limits total client connections per server with max_connections, and every Grafana node draws from that same budget. Each node opens its own pool, so adding Grafana instances multiplies demand on the server. A connection pooler such as PgBouncer can sit between Grafana and the server to share a smaller set of server connections among many clients.
- Server connection limit: Check
max_connectionsand the current count inpg_stat_activityduring a busy period before raising Grafana's open connection setting. - Pooler case: Consider PgBouncer once several Grafana nodes or other applications share one server. Confirm with your DBA that the pool mode supports the session behavior your configuration relies on.
- Version window: PostgreSQL 14 is supported until November 12, 2026, and 18 is supported until November 14, 2030. Grafana's minimum is PostgreSQL 12, but PostgreSQL 13 and earlier are unsupported, so a new deployment should start on a version still in support.
- Major upgrades: Plan major moves with pg_dumpall and restore, pg_upgrade, or logical replication, and treat the Grafana connection settings as part of that change.
- Minor updates: Minor releases do not change the storage format, so they usually mean replacing executables and restarting the server.
Compare the peak connection count with max_connections and the total pool size across all Grafana nodes before you go live.
Some checks apply regardless of engine. Whichever database you run, the pool settings are only correct if they match the load Grafana creates. Viewer count, panel refresh rates and alert rule volume all increase concurrent queries. Read the database and Grafana signals together so you can tell whether slowness comes from the database, the pool or the dashboards.
- Pool size against load: Set the open and idle connection limits for Grafana against the number of nodes and the database connection budget, not against a single instance in isolation.
- Contention signals: Look for rising query latency, requests waiting for a connection and repeated connection errors in the database logs at the same time as dashboard slowness.
- Grafana's own metrics: Scrape the Grafana metrics endpoint with authentication enabled, and alert on slow queries and failing data sources.
- One change at a time: Adjust a single pool or lifetime setting, then observe for a full traffic cycle before changing another.
- Alert rule load: Alert evaluation also uses database connections, so test the pool with the real rule count, not only with dashboard traffic.
Record the pool settings, server limits and timeout values in your change log so the next tuning session starts from known values.
How to set and verify the pool on a running Grafana
This sequence moves a running Grafana from its current connection settings to tuned pool and lifetime values, one node at a time, with a check after each change. The result is a documented baseline, a verified configuration and evidence that alert evaluation and query latency hold under load.
Record current database limits and timeouts
Before changing anything, the database owner and the Grafana administrator record the server's maximum connection setting, the idle and wait timeouts configured on the database server, any connection proxy or pooler in front of it, and the current pool values in the Grafana configuration file on each node. Confirm the values with the database administrator instead of relying on defaults, because the MySQL or PostgreSQL limit must comfortably exceed the total of all Grafana nodes multiplied by the open connections per node. Done when the values sit in a change record that the team can compare against later checks.
Measure the baseline connection count and waits
Capture the number of connections Grafana holds to the database on each node, along with the database's own view of active sessions, waiting queries and lock waits during a typical business window and during alert evaluation peaks. Grafana's own metrics endpoint can show request latency and database-related errors, which helps link slow dashboards to database contention. Done when the team has a baseline table of connections per node and wait signals per time window, so later changes have something to be measured against.
Set pool and lifetime values on one node
On a single Grafana node, the administrator sets the maximum open connections, maximum idle connections and connection lifetime in the database section of the configuration file, choosing the lifetime to end before any idle or wait timeout enforced by the database server or a proxy in between. Keep the change in version-controlled configuration and apply it through the same change control used for other production configuration, with a documented rollback to the recorded values. Done when the file change is reviewed, approved and committed.
Restart the pilot node and check connections
The administrator restarts only the pilot node during an approved window and confirms it starts cleanly. Within the same window, the team checks that the node's connection count stays under the configured maximum and that idle connections are being released rather than accumulating. Done when the connection count on the pilot node matches the new limits and the database shows no new waiting sessions attributable to Grafana.
Check logs and alert evaluation on the pilot
The team reviews the Grafana server logs on the pilot node for database timeout, connection refused or too many connections errors, and confirms that alert rule evaluations continue to run on their scheduled intervals in the alerting views. Errors such as connection reset or closed by the server suggest the lifetime is longer than a timeout somewhere in the path, so the lifetime should be lowered before continuing. Done when the logs show no timeout errors over the observation period and alert evaluations complete on schedule.
Run a representative load test before rollout
Before applying the change to the remaining nodes, the team runs a load test that mirrors real usage, including concurrent dashboard viewers, scheduled panel refreshes and the full set of alert rules. Compare query latency, error rates and database waits against the baseline recorded earlier. Done when latency stays stable at the agreed targets and the database shows no growing queue of waiting connections during the test.
Roll the configuration to the remaining nodes
The administrator applies the same reviewed configuration to each remaining node one at a time, restarting each node and repeating the connection, log and alert evaluation checks before moving on. Keep the previous values available so any node can be reverted. Done when every node reports connections within the configured limits, no node logs timeout errors, and the combined connection total stays within the database limit recorded in the first step.
Record the final state and schedule a review
The team saves the final pool values, baseline and post-change measurements, load test results and the change record in the same repository or ticket system used for other production changes. They also schedule a recurring review of connection counts and database waits, especially after adding dashboards, alert rules or Grafana nodes. Done when the change is closed in change control with the evidence attached and the review date is assigned to a named owner.
Spotting database contention in Grafana's own metrics
Pool exhaustion and database contention look like general slowness from the user's chair, so the first job is to separate them from other causes using Grafana's own telemetry. Start by scraping the Grafana metrics endpoint with Prometheus and watching database-related request latency alongside alert rule evaluation time. When both rise together while CPU and memory on the Grafana nodes stay flat, the bottleneck is more likely the database connection path than the application. If only dashboard load times rise, look at panel query latency to the data sources instead. Metric names and labels change between releases, so confirm the exact names in the Grafana metrics documentation for your version before you build alerts on them. The scraping setup, the endpoint protection and the dashboards for slow queries are covered in the sibling topic on monitoring Grafana itself with Prometheus metrics and tracing.
Read the Grafana side and the database side at the same moment. On the database server, track the number of client connections against the configured ceiling, the count of idle versus active sessions, and waits on locks. A Grafana pool that is saturated while the database shows many sessions waiting on locks points to contention inside the database, often from long-running alert queries or from migrations. A Grafana pool that is saturated while the database has spare connection capacity points to a Grafana-side limit, such as the max open connections value being too low for the number of concurrent alert evaluations. Record the timing of both sides so you can line up a Grafana latency spike with a lock wait spike. Ask your database team which connection and lock views they already monitor for MySQL or PostgreSQL, since those views differ by engine and version.
Before changing any setting, decide what evidence would justify a change and what would roll it back. Run a controlled test against a non-production copy with a realistic number of alert rules and viewers, then compare the same Grafana and database metrics before and after each change to the pool limits or connection lifetime. Change one value at a time, because a higher open connection limit can move the bottleneck onto the database rather than remove it. Record the baseline numbers, the change and the observed result in your change log. If the metrics show lock contention that a pool change does not relieve, treat it as a database capacity or query design problem and plan that work with the database owners rather than continuing to tune Grafana.
Failure modes that appear when the pool is wrong
Connection pool problems rarely show up as a clear database error. They appear as dashboards that hang, alerts that arrive late or twice, and sessions that drop for no visible reason. Each card below names the first symptom a team sees and the setting or check that usually explains it.
Connections closed by idle timeout
Grafana keeps pooled connections open between requests. If the database or a network device closes an idle connection first, the next query fails with a dropped-connection error. Users see intermittent errors on dashboards that worked minutes earlier. Check the database server's idle timeout, such as wait_timeout on MySQL, and set the Grafana connection lifetime below it so Grafana retires connections before the server does. Also check firewall idle timeouts between Grafana and the database.
Connection limit exhausted across HA nodes
Each Grafana server holds its own pool, so the total connection count grows with every node added behind the load balancer. When the sum of open connections reaches the database's max_connections limit, new logins and queries are refused. The first symptom is usually login failures or pages that time out while the database itself looks healthy. Compare the per-node max_open_conns multiplied by node count against the server limit, and leave headroom for administrators and maintenance jobs.
Alert evaluation falling behind
Alert rule evaluation reads and writes state in the database. When connections are scarce, evaluations wait for a free connection, run late, and leave gaps in the alert history. Teams notice missing evaluation points or alerts that resolve and fire later than expected. Look at Grafana's own metrics for evaluation duration and missed iterations, and check whether the pool is saturated during the same windows. Raising the open connection cap only helps if the database has spare capacity for it.
Duplicate notifications without HA alerting setup
Running two or more active Grafana servers without the additional alerting configuration means each node can evaluate the same rules and send the same notification. The first symptom is duplicate pages or messages for a single incident. This is a configuration gap rather than a pool setting, but it often appears alongside pool changes during HA rollouts. Confirm the documented alerting HA settings are in place before scaling out, and test with a non-critical rule.
Slow dashboards from database lock waits
When many queries hit the same database tables, such as dashboard, session or alert state tables, transactions queue behind each other. Users experience dashboards that load slowly or stall, while CPU on the Grafana servers stays low. Check database lock wait and slow query data during the slow periods, and compare them with the number of concurrent connections in use. A pool that is too large can increase contention, so the fix may be fewer connections, not more.
Security and operational points for database connections
Give Grafana its own database account and grant it only what its own schema needs. Grafana creates and migrates its tables at startup, so the account must be able to do that work on its database, but there is no reason for it to hold server-wide administrative rights or access to other applications' schemas. Keep the account separate from any admin login used for upgrades or recovery, so a compromised Grafana process cannot change the database server itself. Confirm the exact grants your Grafana version needs during a test upgrade in a non-production environment, because the required set can change between releases. If the database is shared with other services, check that connection limits set for the Grafana account match the pool sizes you chose, since the database enforces its own ceiling regardless of what Grafana is configured to open.
Decide whether connections between Grafana and the database must be encrypted. Many regulated environments require this for data in transit, and the database side must support TLS for it to work. Check the database driver and TLS settings for the Grafana version you run, and confirm which certificate authority and hostname checks your platform requires. Test a forced-TLS connection against a database with a non-default certificate chain before go-live. Store the database password, and any TLS key material, in a secrets store or the mechanism your platform already uses for secret injection rather than in a plain configuration file. Plan rotation as a documented procedure: change the password on the database, update the secret, restart or reload Grafana in a planned window, and watch for failed logins in both the Grafana logs and the database audit log. Pool settings that cause connection churn during rotation are worth noting in the runbook.
Record every change to pool size, connection lifetime and idle limits in change control, with the reason, the Grafana version, the database version and the observed effect on contention metrics. The same change record should cover backup and restore windows. A logical dump or a replica-based backup opens its own connections, and a restore test can briefly double the number of clients on the database. Confirm the connection ceiling of your database and reserve headroom for backup jobs, restore drills and administrative sessions before raising Grafana's pool limits. Schedule restore tests outside peak alert evaluation periods, and make sure the restored instance is not pointed at the production database by accident. The backup and restore section of this page covers the procedure itself; here the question is whether the pool settings leave room for it. Ask your database team which maintenance windows, backup tools and audit requirements apply, since these vary by platform and by the database engine you chose.
Limits to confirm in your environment before changing the pool
The right pool size depends on limits that sit outside Grafana: what the database server allows, who else uses it, and how traffic reaches Grafana. Confirm these before you change any setting, because a larger pool only helps when the database and the proxies in front of it can accept the extra connections.
Database maximum connection limit
Check the server's maximum connection setting and how much of it other applications already use. On MySQL, read max_connections from the server. On PostgreSQL, read max_connections and the number of sessions already open. Grafana's pool across every instance must fit in the remaining headroom, with room left for administrators and maintenance jobs. A Grafana pool that works on one instance can exhaust the server once you add a second.
Database version and support end date
Record the exact MySQL or PostgreSQL version and its support end date before you tune connection behavior. Connection handling, timeout defaults and authentication methods change between releases, so settings tested on one version may behave differently on another. Grafana's minimum supported versions also set what you can run. Plan any database upgrade as a separate change, not as part of the pool work.
External connection pooler in the path
Check whether an external pooler such as PgBouncer already sits between Grafana and PostgreSQL, or a proxy or database router sits between Grafana and MySQL. A pooler changes which limit applies, since the server may see far fewer connections than Grafana opens. Confirm the pooling mode, because some modes restrict session features that Grafana may rely on. Document the pooler's own maximum client and server connection settings.
Grafana Live limits in HA
Confirm whether your instances run in high availability, because the documented limitations of Grafana Live apply there. Streaming panels hold long-lived connections that count against the same proxy and server limits as normal requests. Check whether your deployment uses Grafana Live at all, and whether those streams change how many connections each instance holds open at once.
Load balancer connection behavior
Find out how the load balancer in front of Grafana handles idle connections, keep-alive timers and connection reuse. Its idle timeout should not be shorter than the connection lifetime you plan to set in Grafana, or the balancer will drop sessions that Grafana still treats as healthy. Check the maximum connections per backend and whether the balancer reuses connections to the database path, if it proxies that traffic.
Exact settings in your Grafana version
Read the database section of the configuration file for your installed version and confirm the key names and defaults there, not in a blog post or an older guide. Confirm also whether the environment variables you use override the file, and which values your provisioning or container images set. Record the current effective values before you change anything, so you can roll back to the same state.
Common questions about tuning Grafana database connections
What drives the cost of tuning Grafana database connections?
The cost is driven mainly by how much of the Grafana estate is in scope and how much evidence exists about its current behavior. A fixed-scope engagement is priced from a written scope, so the main inputs are the number of Grafana instances, the database engine and its topology (single server, replicas, or a managed service), the number of users and alert rules you expect to run, and whether a load test is included. One-time work covers reviewing current pool settings, measuring Grafana's database metrics under realistic load, changing configuration and verifying the result. Recurring costs appear only if you add a retainer for upgrades, re-tuning after growth, or continuous monitoring. Ask any quote to list each of these items separately.
How long does a database connection tuning exercise take?
Duration depends on how many instances share the database, how quickly you can produce representative load, and how many maintenance windows the change needs. Small single-instance setups with clear metrics take less time than multi-instance, high-availability deployments with many alert rules, where each change has to be observed over a period of normal activity. Timing also depends on your change approval process and on whether a database restart or a Grafana restart is needed to apply new settings. Ask for a timeline in the written scope that shows measurement, change windows, and a verification step, rather than a single duration for the whole exercise.
What does the internal team need to provide for this work?
The work needs access and data more than engineering hours from your side. Expect to provide read access to the Grafana configuration and its database metrics, credentials or a read-only account for the database to view connection counts and wait events, and access to the Grafana logs. A representative load profile helps, including typical concurrent viewers, dashboard refresh rates, and the number of alert rules. Plan a maintenance window for applying changes and a rollback path. Your team should also name an owner who can approve database configuration changes and confirm when the system is safe to restart.
Can our own team tune Grafana database connections without a partner?
Yes, a capable platform or database team can do this internally if it has the skills and time to measure before changing anything. The core steps are documented in the Grafana configuration reference, and the database side depends on your engine. The common risk is changing several settings at once without a baseline, which makes it hard to tell which change helped or caused a new failure. An outside partner adds value mainly through an existing measurement method, a known set of failure patterns, and an independent review. Decide based on who will own the settings after the work and whether you have someone who can read Grafana's own metrics during peak use.
When should we add an external connection pooler in front of the database?
Consider an external pooler when many Grafana instances, or many other applications, open more connections than the database can serve efficiently, or when connection churn from short-lived requests becomes a visible cost. PgBouncer is a widely used pooler for PostgreSQL that sits between applications and the server. Adding a pooler is an architecture change, not just a setting, so it affects transaction handling, prepared statements and session state, and it needs its own monitoring. Tune Grafana's in-process pool first so you know what it actually needs, then add a pooler only if measurements show the database is still constrained. Confirm compatibility with your Grafana version before deploying one.
How does tuning differ between MySQL and PostgreSQL for Grafana?
The Grafana settings are the same in both engines, but the database side differs. PostgreSQL uses a process-per-connection model, so connection counts have a direct memory cost on the server, and you may need an external pooler sooner. MySQL, with InnoDB, handles many connections through threads and has its own timeout behavior, so the connection lifetime setting must be shorter than the server's idle timeout to avoid stale connections. Check the supported versions for your engine first: PostgreSQL 14 is supported until November 12, 2026, and MySQL 8.4 is an LTS track. Confirm the timeout and limit values on your own server before choosing settings, because defaults vary by version and by managed service.
Will tuning the database connection pool alone fix slow dashboards?
No. Connection pool tuning only helps when Grafana is waiting for database connections or when the database is saturated by connection overhead. Slow dashboards are often caused by expensive queries from data sources, heavy panel refresh rates, large time ranges, or alert rules that evaluate too often, none of which a pool setting changes. Start by checking Grafana's own metrics for query duration and connection wait, then examine the slow data sources and dashboards. If the pool is not the bottleneck, changes there will not improve the user experience, and you may add risk without benefit.
How DeployOpen scopes and delivers Grafana database tuning
DeployOpen treats connection tuning as part of the database and Grafana configuration it runs inside your infrastructure, not as a one-off setting change. We start from your user counts, alert rule volume and database platform, then agree the changes and checks in writing before any work begins.
How we scope
- Confirm which database Grafana uses (MySQL or PostgreSQL) and the versions your environment runs
- Record concurrent users, alert rule counts and evaluation intervals that drive connection demand
- Agree in writing which pool settings, timeouts and metrics dashboards are in and out of scope
How we build
- Set maximum open and idle connection values from measured contention, not from defaults alone
- Align connection lifetime with the idle timeout configured on your MySQL or PostgreSQL server
- Test changes in a non-production copy under representative alert and dashboard load before rollout
How we hand over
- Deliver the final configuration as files your team can review, version and redeploy
- Document the Grafana metrics that show pool saturation and database contention, with alert thresholds agreed with you
- Provide a runbook for changing pool settings after upgrades, database moves or new alert rule batches
How we support
- Engagements are fixed-scope, with deliverables and timelines agreed in writing before work starts
- Ongoing support, upgrades and continuous testing are available as a retainer
- Review pool metrics with your team after major Grafana upgrades or significant growth in users or alert rules

