156%
of the primary’s CPU, demanded at peak
500 order summaries a second × 40 ms of database CPU = 20 CPU-seconds a second, plus 5 for everything else. A 16-vCPU box supplies 16.
Why 156% isn’t “a bit slow”
For one queue, latency ≈ service time ÷ idle fraction. A 5 ms query takes 10 ms at 50%, 50 ms at 90%. Past 100%, the queue grows until clients time out.
Everything lands on the one box that takes every write
Display-ready SQL, per-row functions, cascading triggers and the 11 am finance report all burn the primary’s cores. The app pods sit idle.
Compute next to the data?
Bad: Formatting rows in SQL
20 rows you return anyway: no bytes saved, scarce CPU spent.
Good: Work that shrinks data
Summing a million rows returns one number. Keep that in SQL.
Detect it: unrelated queries slow down too
Sessions run on CPU with no wait event. One statement eats 71% of database time. A 1 ms login lookup waits 18 ms for a core.
Give the database only what it’s good at
- Format and apply per-row rules in the app
- Send reports to a replica or a warehouse
- Precompute hot aggregates; queue side effects
- Scale the database last, not first
So move everything out of SQL? Summing a million payments in the app ships 100 MB.
The line
Keep work that shrinks data, plus constraints and atomic checks. Move work on rows you return anyway.
Remember
The database is the one tier you can’t scale by adding boxes. Spend its CPU on finding, joining, aggregating and committing; move everything else out.