Bash and Linux

Average response time per endpoint

mediumawk and cut Must-do

Problem statement

A service writes one line per request: method, path, status code and latency in milliseconds. Print each path with its average latency (one decimal place), slowest first. This is the classic awk associative-array question.

requests.log

TEXT
GET /api/users 200 120
GET /api/orders 200 340
POST /api/login 200 95
GET /api/users 200 80
GET /api/orders 500 1020
POST /api/login 401 45
GET /api/users 200 100

Examples

Example 1

Input: Run the command on `requests.log`.

Output: /api/orders 680.0 /api/users 100.0 /api/login 70.0

Explanation: orders: (340 + 1020) / 2, users: (120 + 80 + 100) / 3, login: (95 + 45) / 2.

Hints

Approach

Optimal

For each line, sum[$2] += $4 adds the latency to an array entry keyed by the path, and n[$2]++ counts requests for that path. In the END block, for (p in sum) visits every path and printf "%s %.1f\n" prints it with the average rounded to one decimal. awk iterates arrays in no guaranteed order, so the output is piped to sort -k2,2nr: sort on field 2 only, numerically, in reverse, which puts the slowest endpoint first.

Bash
awk '{ sum[$2] += $4; n[$2]++ } END { for (p in sum) printf "%s %.1f\n", p, sum[p] / n[p] }' requests.log | sort -k2,2nr

Follow-up questions

  • Also print the request count and the maximum latency per path.
  • How would you compute the p95 latency per path? (collect values, sort, pick the index)

Frequently asked questions

sort -rn compares from the start of the line, and the line starts with the path, which is not a number. -k2,2n restricts the key to field 2 and compares it numerically. Always give an explicit key when the number is not the first field.