Top 10 CPU-Heavy Nodes

An easy SQL interview practice problem on DataDriven. Write the query and run it against a real database, with instant feedback.

Domain
SQL
Difficulty
easy
Seniority
L3
Asked in
Asana

Problem

Our infrastructure metrics table tracks CPU usage per node. Show the ten nodes consuming the most CPU, with their node ID, hostname, and CPU percentage, sorted from highest utilization to lowest.

The ten hungriest nodes.

Tables

infra_nodes

Columns: node_id INTEGER, hostname TEXT, region TEXT, node_type TEXT, cpu_pct REAL, mem_pct REAL, status TEXT

infra_nodes: 10 of 200 rows
node_idhostnameregionnode_typecpu_pctmem_pctstatus
1037web-02us-west-2memory1319stopped
1074api-01eu-west-1storage2638draining
1111api-02sa-east-1gpu3957offline
1148db-primaryeu-central-1general5276Running
1185db-replicaus-east-1compute6595STOPPED
1222cache-01us-west-2memory7814running
1259worker-01eu-west-1StorageNULLNULLstopped
1296worker-02ap-south-1gpu452draining
1333gpu-node-01eu-central-1general1771offline
1370WEB-03us-east-1compute3090Running

Expected output

First 5 of 10 rows
node_idhostnamecpu_pct
1851Api-0399
2702WEB-0398
3553gpu-node-0197
4404worker-0296
1555api-0295

Worked solution and explanation

What this really is

This is a top-ten cut over a snapshot dressed up as a capacity question. infra_nodes already holds one row per node, keyed by node_id, so there is nothing to total or average: the whole job is ordering cpu_pct from the top and stopping at ten. Anyone gets the sort. What separates candidates is noticing that the hostname is not the node: 12 hostnames are shared by 200 nodes, and every reading from 99 down to 95 belongs to two different nodes. Group or deduplicate on hostname and you return one row per name, drop half of the real top ten, and report figures no single node ever showed.

Step 1: Confirm the grain is one row per node

node_id is unique across all 200 rows, and cpu_pct is the node's own reading. No GROUP BY, no AVG: project node_id, hostname and cpu_pct straight off the table.

Step 2: Sort the reading from the top

ORDER BY cpu_pct DESC puts the busiest node first. Without it, LIMIT 10 keeps whatever ten rows the scan reads first, and on this table those start at 13, 26 and 39 percent.

Step 3: Cut at ten after the sort

LIMIT 10 applies to the sorted rows, so it keeps the 99 to 95 band: two nodes at each reading. The eleventh row sits at 94, so the cut never splits a tie and no tiebreaker is needed to decide who makes the list.

The solution

Sort `cpu_pct` from the top, keep ten
SELECT node_id, hostname, cpu_pct
FROM infra_nodes
ORDER BY cpu_pct DESC
LIMIT 10
Collapsing by hostname
GROUP BY hostname with MAX(cpu_pct) returns at most 12 rows, one per name. 'Api-03' appears once at 99 even though two different nodes report 99, so the second node at every reading from 99 to 95 vanishes and lower nodes get pulled into the list.
One row per node
Reading the rows as they are keeps both nodes at 99, both at 98 and so on, each with its own node_id. The hostname is a label riding along, never the key.

Common follow-up questions