Private beta

Database monitoring

Find the statement, the lock or the config change behind a slow database, all in one view.

14 days, all features, no credit card required.

InfrastructureDatabasespayments-db-prodlast 15 minutesInteractive
payments-db-prod
Databases payments-db-prod Live Health :Degraded
COLLECTION
◀Last 15 Minutes▶
EnginePostgreSQL 16.4 HostingRDS Instancedb-PAYMENTS7Q2XK4 Regioneu-west-1
FullSampledBaseline Full on role = payments_api for the next 60 min. Literal values are being captured. Sampled: normalized statements, a sample of runs and their plans. No literal values are kept. Baseline: instance metrics and health only. Switch to Sampled to see statements.
Queries / s L
4,120

Last 1h

Mean latency L
0.94 ms

Total time over calls

Statements tracked L
1,864

of pg_stat_statements.max 5,000

Execution time L
13,940 s

Last 1h, all statements

Top statements by total time

iPlan column i6 of 1,864
Statement LCalls LTotal LMean LRows / call LShare of time LPlan L
SELECT * FROM orders WHERE customer_id = $1 AND status = $2 ORDER BY created_at DESC LIMIT $31,204,3312,890 s2.4 ms20Index Scan
UPDATE ledger_entries SET balance = balance + $1 WHERE account_id = $2384,1202,343 s6.1 ms1Index Scan
SELECT p.id, p.amount, r.amount AS refunded FROM payments p JOIN refunds r ON r.payment_id = p.id2,4121,958 s812 ms500Seq Scan
INSERT INTO audit_log (actor_id, action, payload, created_at) VALUES ($1, $2, $3, $4)2,100,0001,260 s0.60 ms1Insert
SELECT count(*) FROM sessions WHERE expires_at < now()1,440922 s640 ms1Seq Scan
DELETE FROM idempotency_keys WHERE created_at < $196404 s4.21 s18,400Index Scan

Time spent per second, by statement

iLast 15 minutes
14:3614:4014:4414:4814:51
orders lookupledger UPDATEpayments ⨝ refunds1,861 others

Execution time by application

iLast 1h: 13,940 s
payments-api62%
ledger-sync21%
audit-writer9%
session-sweeper6%
other2%
queryid application payments-api Normalized
SELECT * FROM orders WHERE customer_id = $1 AND status = $2 ORDER BY created_at DESC LIMIT $3
Calls L
1,204,331

Last 1h

Mean L
2.4 ms

Total time over calls

Rows read / returned L
1:1

Reads match returns

Share of instance time L
20.7%

2,890 s of 13,940 s

Explain plan

iFull auto_explain actuals
Limit

actual 2.1 msrows 20 est. rows 20

Index Scan using orders_customer_status_idx on orders

actual 2.0 msrows 20 loops 1

Index Cond: (customer_id = $1) AND (status = $2)Buffers: shared hit=24 read=2
Planning 0.08 msExecution 2.1 msHealthy plan

Wait events

iShare of time, last 1h
CPU2,081 s72%Query
IO:DataFileRead607 s21%Query
LWLock:BufferMapping202 s7%Query
No heavyweight lock waits for this statement

Samples

iEvery run, with literal values
TimeDuration LRows LApplicationClientParameters LSource
14:51:07.2125.8 ms22payments-api10.4.9.18$1 = 'c_88213', $2 = 'settled', $3 = 25Full
14:48:55.9044.1 ms18payments-api10.4.12.31$1 = 'c_10442', $2 = 'settled', $3 = 20Full
14:44:12.6303.0 ms20payments-api10.4.9.22$1 = 'c_88213', $2 = 'settled', $3 = 20Full
14:39:40.0712.5 ms20payments-api10.4.9.18$1 = 'c_10442', $2 = 'settled', $3 = 20Full
14:31:03.5582.0 ms19payments-api10.4.12.31$1 = 'c_88213', $2 = 'settled', $3 = 20Full
14:27:48.1171.9 ms7payments-api10.4.9.22$1 = 'c_57120', $2 = 'pending', $3 = 20Full
14:22:15.4831.7 ms20payments-api10.4.12.31$1 = 'c_10442', $2 = 'settled', $3 = 20Full
Locks held M
3,412 of 6,400

Ceiling = max_locks_per_transaction 16 x max_connections 400

Blocked sessions L
3

Behind 1 holder

Longest lock wait L
14 s

Lock:tuple on ledger_entries

Deadlocks M
0

Last 1h

Lock counts

iMetrics, last 15 minutes
Locks heldCeiling 6,400Blocking episode
6,4000 max_locks_per_transaction 16 × 400 connections 3,412
14:3614:3914:4214:4514:4814:51

Blocking now

iLatest snapshot 14:51:16, a new one every 10 s
pid 48121app_paymentsRowExclusiveLockledger_entriesidle in transaction 14 sQueryblocks 3
pid 48210app_paymentswaiting Lock:tuple14 s
pid 48233app_paymentswaiting Lock:tuple11 s
pid 48302ledger-syncwaiting Lock:tuple6 s

Holder last ran: UPDATE ledger_entries SET balance = balance + $1 WHERE account_id = $2

Blocking in the selected range

iLast 15 minutes, 14:36:16 to 14:51:16 (90 snapshots)
Holder LUserLock modeRelationMax blocked LLongest wait LFirst seenLast seenSnapshots L
pid 48121app_paymentsRowExclusiveLockledger_entries314 s14:51:0214:51:16, ongoing2
pid 47960ledger-syncShareLockledger_entries28 s14:44:2014:44:302
pid 47712app_paymentsAccessExclusiveLockpayments641 s14:39:0014:39:405
Tables L
42

database = payments

Size M
97.9 GB

Tables and indexes

Unused indexes M
2

8.0 GB, 0 scans in 30d

Columns never queried D
7

No statement references them in 30d

Tables by share of I/O

iClick a table to see its columns
TableRows MSize MSeq scans MIndex reads MShare of I/O MUnqueried columns D
payments4.1M3.8 GB3,8521.2M2
orders12.6M9.1 GB121.2M0
ledger_entries48.2M22.4 GB0384K1
audit_log210M61.0 GB004
sessions880K0.4 GB1,44000
refunds220K0.1 GB02,4120

Columns of paymentsordersledger_entriesaudit_logsessionsrefunds

iStatement references, last 30d
ColumnTypeStatements DStatus
iduuid412Primary key
customer_iduuid130Indexed
amountnumeric(12,2)96
statustext88
created_attimestamptz54Filtered, not indexed
legacy_gateway_reftext0Never queried
gateway_responsejsonb0Never queried
iduuid220Primary key
customer_iduuid164Indexed
statustext151Indexed
created_attimestamptz143
totalnumeric(12,2)72
currencychar(3)41
shipping_addressjsonb18
idbigint96Primary key
account_iduuid210Indexed
balancenumeric(14,2)184
entry_typetext61
created_attimestamptz77
payment_iduuid33
memotext0Never queried
idbigint3Primary key
actor_iduuid2Indexed, never read
actiontext2
payloadjsonb1
created_attimestamptz2
ip_addressinet0Never queried
user_agenttext0Never queried
request_iduuid0Never queried
session_reftext0Never queried
iduuid58Primary key
user_iduuid44Indexed
expires_attimestamptz6Filtered, not indexed
datajsonb12
created_attimestamptz9
iduuid24Primary key
payment_iduuid19Indexed
amountnumeric(12,2)17
reasontext8
created_attimestamptz11

Indexes

iLast 30d
IndexSize MReads MStatus
payments_pkey210 MB1.2M
payments_customer_id_idx190 MB380K
orders_customer_status_idx640 MB1.2M
ledger_entries_account_id_idx1.1 GB384K
refunds_payment_id_idx12 MB2,412
payments_legacy_gateway_ref_idx1.8 GB0Unused
audit_log_actor_idx6.2 GB0Unused

Changes last 14 days

iHealthyDegradedChange
Oct 21Oct 22Oct 23Oct 24Oct 25Oct 26Oct 27Oct 28Oct 29Oct 30Oct 31Nov 1Nov 2Nov 3
Resource health M
Configuration changes L11
i RDS parameter group: dbm-payments-pg16
Search
Search13 lines
2 Differences Found Show only differences
1# RDS parameter group dbm-payments-pg16
1# RDS parameter group dbm-payments-pg16
2shared_preload_libraries = 'pg_stat_statements,auto_explain'
2shared_preload_libraries = 'pg_stat_statements,auto_explain'
3shared_buffers = 16GB
3shared_buffers = 16GB
4max_connections = 400
4max_connections = 400
5max_locks_per_transaction = 64
5max_locks_per_transaction = 16
6work_mem = 16MB
6work_mem = 16MB
7track_io_timing = on
7track_io_timing = on
8log_min_duration_statement = 500ms
8log_min_duration_statement = 500ms
9auto_explain.log_format = json
9auto_explain.log_format = json
10auto_explain.log_analyze = on
10auto_explain.log_analyze = on
11auto_explain.log_timing = off
11auto_explain.log_timing = off
12auto_explain.sample_rate = 0.01
12auto_explain.sample_rate = 0.01
13statement_timeout = 0
13statement_timeout = 30s
Why it matters

One database view for the whole team

Developers see what their code asks

Every statement a service sends, normalized, with its plan, what it waited on, and the runs behind it down to the application and client that sent each one.

DBAs fix the database, not the dashboard

Top statements, blocking chains, unused indexes and parameter drift on one page per instance, each number marked with where it came from.

Platform teams pay for detail only when it helps

A light baseline on every instance, sampled statements where it matters, and full capture for one role for an hour, switched off on its own.

From slow to solved

Every answer a slow database owes you, in one place

Queries

Know which statements cost you the most

Literal values are folded into $1, $2, so a million runs of a statement add up to one row: calls, total and mean time, rows per call, its share of the instance’s time and the plan it ran. Sequential scans stand out before they turn into an incident.

Databasespayments-db-prodQueriestop statementsInteractive
Plans and samples

Go from a slow statement to the run that hurt

Open a statement to see the plan it actually ran, what it waited on, and every run with its duration, rows, application and client. With Full collection on, each run keeps its literal parameters, so you can replay the exact query.

Databasespayments-db-prodQueriesorders by customerInteractive
Locks

See who is blocking whom, right now

A live blocking tree shows the session holding the lock, every session queued behind it and the statement it last ran, refreshed every 10 seconds. Each blocking episode in the range is kept, so the one at 3 a.m. is still there in the morning.

Databasespayments-db-prodLocksblocking nowInteractive
Schema and indexes

Find the indexes and columns nobody uses

Tables ranked by their share of I/O, indexes with no reads in 30 days, and columns no statement has touched. Drop the dead weight, and add the index a filtered column is missing.

Databasespayments-db-prodSchema & indexesInteractive
Configuration

Catch the config change behind the regression

Every parameter change lands on the instance’s health timeline, and any two versions compare side by side. Here max_locks_per_transaction dropped from 64 to 16 on Nov 1, and the instance turned Degraded the next day.

Databasespayments-db-prodConfigurationcompareInteractive
Collection

Collect as much as the moment needs

Detail is a switch, not a contract. Every instance starts light, and you turn up what you collect for the scope and the time you choose.

BaselineAlways on

Health and instance metrics for every database you run: connections, throughput, replication, storage and the configuration timeline.

For every instance, all the time

SampledThe everyday level

Normalized statements with their timing, a sample of runs, explain plans, wait events, locks and schema usage.

For the databases you care about

FullWhen you’re chasing one

Every run with its literal values, scoped to a role, an application or a database, and switched back to Sampled when the time runs out.

For one scope, for an hour
Database monitoring (private beta)

Stop guessing which query to fix

Connect a database and see its top statements, locks and indexes in minutes.

14 days, all features, no credit card required.