At a glance
The live throughput of your PostgreSQL instance: how many statements per second it is executing right now. This is the database’s pulse. On its own it is neither good nor bad: a healthy reporting database might idle at 5 QPS while a busy OLTP primary sustains 12,000. Its value is as a baseline. Once you know your normal range, every other Capacity and Performance card reads differently. A latency spike at 3x normal QPS is load; the same spike at flat QPS is a regression.
| What it tracks | Statements executed per second across the instance, averaged over the live sampling window. It is the rate of work, not the number of connections or the amount of data. |
| Data source | Derived from the xact_commit + xact_rollback and statement counters in pg_stat_database, sampled twice and differenced over the interval. Where pg_stat_statements is installed, the calls counter gives a finer statement-level rate. |
| Time window | RT (real-time; the rate is computed from the delta between two close samples and refreshed continuously). |
| Alert trigger | None. This is a context and baselining card, not an alerting one. The actionable thresholds live on the latency, error-rate and saturation cards that QPS gives context to. |
| Roles | owner, engineering, operations |
| What it is not | Not a measure of useful work. A QPS spike can be genuine demand, a retry storm from a failing dependency, or a scraper hammering an unindexed endpoint. QPS tells you the volume; the sibling cards tell you the quality. |
Calculation
PostgreSQL does not expose a ready-made “queries per second” gauge, so Vortex IQ derives the rate from monotonic counters by sampling and differencing:pg_stat_statements.calls(preferred): when thepg_stat_statementsextension is installed, summing thecallscolumn across all statements gives a true count of statement executions. The delta between two samples, divided by the elapsed seconds, is the statement rate. This is the most accurate basis because it counts every executed statement, including those inside functions.pg_stat_databasetransaction counters (fallback): whenpg_stat_statementsis not available, Vortex IQ usesxact_commit + xact_rollbackfrompg_stat_databaseas a proxy. This counts transactions, not statements, so a workload that batches many statements per transaction will read lower than the true statement rate. It is still a faithful baseline because the ratio stays stable for a given workload.
Worked example
A platform team runs a PostgreSQL 16 primary behind an inventory and order API. Normal weekday QPS sits between 1,800 and 2,600. Snapshot taken on 22 Apr 26 at 12:05 BST.| Sample | pg_stat_statements.calls (cumulative) | Time |
|---|---|---|
| Previous | 4,812,440,118 | 12:04:55 |
| Current | 4,812,627,418 | 12:05:05 |
187,300 calls over 10 seconds, so the live reading is 18,730 QPS, roughly 8x the normal ceiling. Nothing else is on fire yet: latency is still within band, errors are flat. The headline simply shows a number far above baseline, which is exactly the signal this card exists to give.
The on-call DBA does not panic but does investigate, because 8x baseline is either a very good day or a problem:
SELECT against the product-availability endpoint running 14,000 times per second from one IP range: a scraper or a misbehaving client retry loop.
Two takeaways the team records:
- QPS is only meaningful against a baseline and against demand. The same 18,730 reading would be a triumph if orders had risen with it and a crisis if they had not. The number alone decides nothing; the pairing does.
- A QPS spike with flat orders is almost always non-revenue traffic: a scraper, a retry storm from a failing dependency, a cache that just went cold, or a runaway cron. The fix is rate-limiting or caching at the application or edge, not scaling the database to serve traffic that produces no value.
Sibling cards
| Card | Why pair it with Queries per Second | What the combination tells you |
|---|---|---|
| Query Latency p95 (ms) | Latency under load is the real question. | Rising p95 with rising QPS is load; rising p95 with flat QPS is a regression or a lock. |
| Query Latency p50 (ms) | The typical-query view under the same throughput. | p50 holding while QPS climbs means the instance has headroom. |
| Query Error Rate % | Errors as a fraction of this volume. | A QPS spike that is mostly errors is a retry storm, not demand. |
| Connection Pool Saturation % | The capacity the traffic consumes. | QPS up with saturation up is healthy scaling; QPS flat with saturation up is a connection leak. |
| Buffer Cache Hit Rate % | Whether the throughput is being served from memory. | A QPS spike that drops cache hit rate is reading cold data and will hammer disk. |
| PostgreSQL QPS Spike vs Ecom Order Rate | Ties query volume to actual revenue events. | QPS spike without an order spike flags bot or scraper traffic. |
| Slow-Query Rate % | The quality of the queries making up the volume. | High QPS plus a high slow-query share means the throughput is expensive, not efficient. |
| PostgreSQL Health Score | The composite this throughput feeds into. | QPS is the load context against which every other health input is judged. |
Reconciling against the source
Where to look in PostgreSQL itself:Reproduce the rate by hand: runWhy our number may legitimately differ from a hand count:SELECT sum(calls) FROM pg_stat_statements;twice a few seconds apart, subtract, and divide by the elapsed seconds. (Requires thepg_stat_statementsextension andshared_preload_librariesconfigured.) Without that extension, runSELECT sum(xact_commit + xact_rollback) FROM pg_stat_database;the same way for the transaction rate. CheckSELECT stats_reset FROM pg_stat_database WHERE datname = current_database();to see when counters last reset; a recent reset makes any rate computed across it meaningless. On a managed service, the console exposes a comparable metric: AWS RDS / Aurora publishes per-database throughput in Performance Insights andCommitThroughputin CloudWatch, Google Cloud SQL publishesdatabase/postgresql/transaction_count, and Azure publishes transaction-rate metrics.
| Reason | Direction | Why |
|---|---|---|
| Counter basis | Either way | If pg_stat_statements is absent, Vortex IQ counts transactions not statements, which reads lower than a statement-level hand count when transactions batch many statements. |
| Sampling interval | Either way | Vortex IQ differences two close samples; a console metric averaged over a 1-minute bucket will smooth out short spikes the live card shows. |
| Stats reset between samples | Vortex IQ suppresses | If counters reset between your two manual reads, your hand maths goes negative or wrong; Vortex IQ discards such samples. |
| Replica vs primary | Either way | QPS is per-instance. A read replica serving reporting traffic has its own rate, separate from the primary. |
| Background work | Console may read higher | Autovacuum, the stats collector and replication generate transactions that some console metrics include and a statement-level count does not. |
Known limitations / FAQs
Is a higher QPS better or worse? Neither, by itself. QPS is throughput, not health. The right reading is always relative: relative to your own baseline, and relative to demand. High QPS with healthy latency and rising orders is a great day. The same number with flat orders or climbing latency is a problem. Always pair this card with a latency card and the order-rate cross-channel card before drawing a conclusion. My QPS reads lower than I expect. Is the card under-counting? Probably you do not havepg_stat_statements installed, so Vortex IQ is counting transactions rather than statements. A workload that runs many statements inside each transaction will show a transaction rate well below its statement rate. Install the extension (add it to shared_preload_libraries, restart, then CREATE EXTENSION pg_stat_statements;) for a statement-accurate figure.
QPS spiked but my orders did not move. What does that mean?
Almost always non-revenue traffic: a scraper, a retry storm from a failing downstream service, a cron that ran amok, or a cold cache forcing the application to re-query data it should have had in memory. Run the top-calls query in pg_stat_statements to find the dominant statement, then look at PostgreSQL QPS Spike vs Ecom Order Rate to confirm the demand side is flat.
Why does QPS briefly read zero or blank after a restart?
The rate is computed from the delta between two cumulative counter samples. A restart resets those counters and pg_postmaster_start_time(), so Vortex IQ suppresses the rate until it has a fresh baseline from two post-restart samples. A momentary blank right after a restart is expected; if it persists, check Instance Uptime.
Does QPS include queries served by my read replicas?
No. QPS is per-instance. Each replica reports its own throughput against its own counters. To see total fleet throughput, sum the primary and replica readings; Vortex IQ keeps them separate so you can tell read traffic from write traffic.
Why is there no alert on this card?
Because there is no universally meaningful threshold for raw throughput: 50 QPS is alarming for a busy OLTP primary and luxurious for a reporting database. The actionable thresholds live on the cards QPS gives context to, latency, error rate and saturation, which fire when high throughput actually starts to hurt. QPS itself is deliberately a context card.