The N+1 Query Storm — JavaScript Bug Hunt

Inspired by the outage pattern behind a thousand postmortems: a page renders 50 posts, and the ORM quietly fires 51 queries.

  • Language: JavaScript
  • Layer: Database
  • Difficulty: Medium
  • Concepts: ORM, Performance
  • Modelled on: Every ORM
  • Visible tests: authors resolve correctly and in order; one page load is one query
  • Reward: 50 XP for a complete fix

Briefing

Inspired by the outage pattern behind a thousand postmortems: a page renders 50 posts, and the ORM quietly fires 51 queries. Works fine in staging with 5 rows; melts the primary at scale.

The mock data layer counts queries. Load every author in one batched query.

Bug report

BUG-N+1 · Priority: High · Reported by: DBA (again)

loadAuthors(posts) must resolve each post's author using AT MOST one query (db.findUsersByIds). Returned shape: [{ postId, authorName }] in post order.

Observed: one db.findUserById call per post — 51 queries per page render.

Logs

[db] SELECT * FROM users WHERE id = ? (x51 in 40ms)
[alert] primary saturated during feed render

The code as shipped

src/orm/authors.js (editable)

var db = require("./db");

// Resolves the author of every post.
exports.loadAuthors = function (posts) {
  var out = [];
  for (var i = 0; i < posts.length; i++) {
    var user = db.findUserById(posts[i].authorId);
    out.push({ postId: posts[i].id, authorName: user.name });
  }
  return out;
};

Read-only context: src/orm/db.js.

Open the hunt to edit the files, run the visible tests and submit against the hidden ones. More JavaScript bug hunts.