diff --git a/apps/studio/components/interfaces/Observability/DatabaseInfrastructureSection.tsx b/apps/studio/components/interfaces/Observability/DatabaseInfrastructureSection.tsx
index 61f6dbfca12..9c92aac9781 100644
--- a/apps/studio/components/interfaces/Observability/DatabaseInfrastructureSection.tsx
+++ b/apps/studio/components/interfaces/Observability/DatabaseInfrastructureSection.tsx
@@ -169,8 +169,8 @@ export const DatabaseInfrastructureSection = ({
-
- Connections
+
+ Peak Connections
@@ -178,7 +178,7 @@ export const DatabaseInfrastructureSection = ({
{errorMessage}
) : connections.max > 0 ? (
- {connections.current}/{connections.max}
+ {connections.peak}/{connections.max}
) : (
--
diff --git a/apps/studio/components/interfaces/Observability/DatabaseInfrastructureSection.utils.test.ts b/apps/studio/components/interfaces/Observability/DatabaseInfrastructureSection.utils.test.ts
index de1bdbaf819..75e97896df7 100644
--- a/apps/studio/components/interfaces/Observability/DatabaseInfrastructureSection.utils.test.ts
+++ b/apps/studio/components/interfaces/Observability/DatabaseInfrastructureSection.utils.test.ts
@@ -192,103 +192,114 @@ describe('parseInfrastructureMetrics', () => {
})
describe('parseConnectionsData', () => {
+ const buildResponse = (
+ values: Array
+ ): InfraMonitoringMultiResponse => ({
+ data: values.map((v, i) => ({
+ period_start: `2026-05-22T00:0${i}:00.000Z`,
+ values: { pg_stat_database_num_backends: v as string | undefined },
+ })),
+ series: {
+ pg_stat_database_num_backends: {
+ format: 'number',
+ total: 0,
+ totalAverage: 0,
+ yAxisLimit: 100,
+ },
+ },
+ })
+
it('returns zeros when data is undefined', () => {
- expect(parseConnectionsData(undefined, undefined)).toEqual({ current: 0, max: 0 })
+ expect(parseConnectionsData(undefined, undefined)).toEqual({ peak: 0, max: 0 })
expect(parseConnectionsData(undefined, { maxConnections: 100 })).toEqual({
- current: 0,
- max: 0,
+ peak: 0,
+ max: 100,
})
})
- it('parses connections data correctly', () => {
- const mockInfraData: InfraMonitoringMultiResponse = {
- data: [],
- series: {
- pg_stat_database_num_backends: {
- format: 'number',
- total: 150,
- totalAverage: 25.5,
- yAxisLimit: 100,
- },
- },
- }
+ it('returns the peak value across the window, not totalAverage', () => {
+ const mockInfraData = buildResponse([4, 4, 6, 4, 5, 4])
+ // totalAverage in series is intentionally stale to ensure we ignore it
+ mockInfraData.series.pg_stat_database_num_backends.totalAverage = 25
- const mockMaxData = { maxConnections: 100 }
+ const result = parseConnectionsData(mockInfraData, { maxConnections: 100 })
- const result = parseConnectionsData(mockInfraData, mockMaxData)
-
- expect(result).toEqual({ current: 26, max: 100 }) // 25.5 rounded to 26
+ expect(result).toEqual({ peak: 6, max: 100 })
})
- it('handles string values for connections', () => {
- const mockInfraData: InfraMonitoringMultiResponse = {
- data: [],
- series: {
- pg_stat_database_num_backends: {
- format: 'number',
- total: 150,
- totalAverage: '30.7',
- yAxisLimit: 100,
- },
- },
- }
+ it('rounds the peak value', () => {
+ const mockInfraData = buildResponse([3, 5.6, 4])
- const mockMaxData = { maxConnections: 100 }
+ const result = parseConnectionsData(mockInfraData, { maxConnections: 100 })
- const result = parseConnectionsData(mockInfraData, mockMaxData)
-
- expect(result).toEqual({ current: 31, max: 100 }) // 30.7 rounded to 31
+ expect(result).toEqual({ peak: 6, max: 100 })
})
- it('returns current connections even when maxConnectionsData is undefined', () => {
- const mockInfraData: InfraMonitoringMultiResponse = {
- data: [],
- series: {
- pg_stat_database_num_backends: {
- format: 'number',
- total: 150,
- totalAverage: 25,
- yAxisLimit: 100,
- },
- },
- }
+ it('handles string values when computing peak', () => {
+ const mockInfraData = buildResponse(['4', '7', '5.4'])
+
+ const result = parseConnectionsData(mockInfraData, { maxConnections: 100 })
+
+ expect(result).toEqual({ peak: 7, max: 100 })
+ })
+
+ it('skips missing values when computing peak', () => {
+ const mockInfraData = buildResponse([5, undefined, 7, undefined])
+
+ const result = parseConnectionsData(mockInfraData, { maxConnections: 100 })
+
+ expect(result).toEqual({ peak: 7, max: 100 })
+ })
+
+ it('skips empty-string values when computing peak', () => {
+ const mockInfraData = buildResponse(['5', '', '7', ''])
+
+ const result = parseConnectionsData(mockInfraData, { maxConnections: 100 })
+
+ expect(result).toEqual({ peak: 7, max: 100 })
+ })
+
+ it('returns peak connections even when maxConnectionsData is undefined', () => {
+ const mockInfraData = buildResponse([4, 9, 6])
const result = parseConnectionsData(mockInfraData, undefined)
- expect(result).toEqual({ current: 25, max: 0 })
+ expect(result).toEqual({ peak: 9, max: 0 })
})
it('returns 0 max when maxConnections is missing from data object', () => {
- const mockInfraData: InfraMonitoringMultiResponse = {
- data: [],
- series: {
- pg_stat_database_num_backends: {
- format: 'number',
- total: 150,
- totalAverage: 25,
- yAxisLimit: 100,
- },
- },
- }
+ const mockInfraData = buildResponse([4])
- const mockMaxData = {}
+ const result = parseConnectionsData(mockInfraData, {})
- const result = parseConnectionsData(mockInfraData, mockMaxData)
-
- expect(result).toEqual({ current: 25, max: 0 })
+ expect(result).toEqual({ peak: 4, max: 0 })
})
- it('returns 0 current when connections metric is missing', () => {
+ it('returns 0 peak when data array is empty', () => {
const mockInfraData: InfraMonitoringMultiResponse = {
data: [],
series: {},
}
- const mockMaxData = { maxConnections: 100 }
+ const result = parseConnectionsData(mockInfraData, { maxConnections: 100 })
- const result = parseConnectionsData(mockInfraData, mockMaxData)
+ expect(result).toEqual({ peak: 0, max: 100 })
+ })
- expect(result).toEqual({ current: 0, max: 100 })
+ it('returns 0 peak when connections metric is missing from data points', () => {
+ const mockInfraData: InfraMonitoringMultiResponse = {
+ data: [
+ {
+ period_start: '2026-05-22T00:00:00.000Z',
+ values: { avg_cpu_usage: '50' },
+ },
+ ],
+ series: {},
+ }
+
+ const result = parseConnectionsData(mockInfraData, { maxConnections: 100 })
+
+ expect(result).toEqual({ peak: 0, max: 100 })
})
it('handles single-response format (legacy)', () => {
@@ -300,10 +311,8 @@ describe('parseConnectionsData', () => {
yAxisLimit: 100,
}
- const mockMaxData = { maxConnections: 100 }
+ const result = parseConnectionsData(mockInfraData, { maxConnections: 100 })
- const result = parseConnectionsData(mockInfraData, mockMaxData)
-
- expect(result).toEqual({ current: 0, max: 100 })
+ expect(result).toEqual({ peak: 0, max: 100 })
})
})
diff --git a/apps/studio/components/interfaces/Observability/DatabaseInfrastructureSection.utils.ts b/apps/studio/components/interfaces/Observability/DatabaseInfrastructureSection.utils.ts
index 03cf8e4ebbc..85ae7b5f058 100644
--- a/apps/studio/components/interfaces/Observability/DatabaseInfrastructureSection.utils.ts
+++ b/apps/studio/components/interfaces/Observability/DatabaseInfrastructureSection.utils.ts
@@ -64,7 +64,7 @@ export function parseInfrastructureMetrics(
}
type ConnectionsData = {
- current: number
+ peak: number
max: number
}
@@ -76,15 +76,21 @@ export function parseConnectionsData(
infraData: InfraMonitoringResponse | undefined,
maxConnectionsData: MaxConnectionsData | undefined
): ConnectionsData {
- if (!infraData) {
- return { current: 0, max: 0 }
+ const max = maxConnectionsData?.maxConnections ?? 0
+
+ if (!infraData || !('series' in infraData)) {
+ return { peak: 0, max }
}
- const series = 'series' in infraData ? infraData.series : {}
+ // Show the highest connection count observed in the selected window rather
+ // than the window's totalAverage. The average varies with bucket granularity
+ // (e.g. 1h vs 1m) and is hard to reason about; peak is interval-stable and
+ // the more actionable signal for headroom against the connection limit.
+ let peak = 0
+ for (const point of infraData.data ?? []) {
+ const n = parseNumericValue(point?.values?.pg_stat_database_num_backends)
+ if (n > peak) peak = n
+ }
- const currentVal = series.pg_stat_database_num_backends?.totalAverage
- const current = Math.round(parseNumericValue(currentVal))
- const max = maxConnectionsData?.maxConnections || 0
-
- return { current, max }
+ return { peak: Math.round(peak), max }
}
diff --git a/apps/studio/components/interfaces/Settings/Infrastructure/InfrastructureConfiguration/InstanceNode.tsx b/apps/studio/components/interfaces/Settings/Infrastructure/InfrastructureConfiguration/InstanceNode.tsx
index 203ecbb0b12..f6a3427ba7c 100644
--- a/apps/studio/components/interfaces/Settings/Infrastructure/InfrastructureConfiguration/InstanceNode.tsx
+++ b/apps/studio/components/interfaces/Settings/Infrastructure/InfrastructureConfiguration/InstanceNode.tsx
@@ -201,7 +201,7 @@ export const PrimaryNode = ({ data }: NodeProps>) => {
<>
ยท
- {connections.current}/{connections.max} conns
+ {connections.peak}/{connections.max} conns
>
)}
diff --git a/apps/studio/hooks/analytics/useComputeMetrics.ts b/apps/studio/hooks/analytics/useComputeMetrics.ts
index 37b84320451..6ca5e0e42e6 100644
--- a/apps/studio/hooks/analytics/useComputeMetrics.ts
+++ b/apps/studio/hooks/analytics/useComputeMetrics.ts
@@ -13,7 +13,7 @@ export type ComputeMetrics = {
cpu: number
disk: number
memory: number
- connections: { current: number; max: number }
+ connections: { peak: number; max: number }
isLoading: boolean
isError: boolean
}