Skip to content

feat: add express-postgres N+1 example with slow/fast endpoints - #11

Merged
Truta446 merged 5 commits into
Truta446:mainfrom
TarekHassan1:main
Aug 12, 2026
Merged

Truta446 merged 5 commits into
Truta446:mainfrom
TarekHassan1:main

Conversation

@TarekHassan1

Copy link
Copy Markdown
Contributor

What this changes

Adds a runnable examples/express-postgres/ directory that demonstrates the N+1 detection library against a real Express + PostgreSQL stack. Includes docker-compose.yml, a seed script, two endpoints (/orders/slow with the N+1 bug and /orders/fast with the fix), and a README.

Why this way

The existing examples/demo.mjs uses a fake client. This gives users a real, copy-paste-runnable example with an actual database so they can see the warning fire live against real queries.

How it was verified

  • docker compose up -d → node seed.mjs → node server.mjs ran successfully locally
  • curl localhost:3000/orders/slow triggers the expected N+1 warning (10× SELECT * FROM order_items WHERE order_id = ?)
  • curl localhost:3000/orders/fast returns clean with no warning

Truta446 added a commit that referenced this pull request Aug 12, 2026
A real stack rather than a fake client: docker-compose, a seed that clears the
threshold, /orders/slow written as a loop and /orders/fast batched, and a test
using expectNoNPlusOne.

Verified by running it end to end. Both endpoints behave as described — /slow
reports 10x on the line that caused it, /fast reports nothing — and the three
tests pass.

Two fixes on top, both of which meant the test file could not run at all: the
imports were one directory level short (correct from the example root, wrong
from test/), and the client was never closed so the process hung after the
assertions passed.

Closes #5
@Truta446
Truta446 merged commit 5011675 into Truta446:main Aug 12, 2026
@Truta446

Copy link
Copy Markdown
Owner

Merged — thank you, this is a good example and it does what the issue asked for.

I ran it end to end rather than reading the diff, and both endpoints behave exactly as you described:

nplusone 1 finding in GET /orders/slow — 11 queries, 17ms

  N+1 query  10× SELECT * FROM order_items WHERE order_id = ?
     at server.mjs:26:38
     8.0ms spent here

/orders/fast reports nothing. The seed volume is right too — 10 orders clears the threshold of 5 with room to spare, which is the detail most people get wrong here.

Two fixes on top, both in the test file. It could not run as submitted:

The imports were ../../dist/, which is correct from examples/express-postgres/ — and that is why server.mjs worked — but the test lives one level deeper in test/, so it resolved to examples/dist/ and failed with ERR_MODULE_NOT_FOUND. Now ../../../dist/.

The client was never closed, so after the assertions passed the process hung on an open handle. Added a closing test with a comment saying why, since it looks like a pointless test until you hit it.

I mention this only because the PR description says the test was run — worth double-checking that step next time, since a path that is wrong by one level fails in a way that looks like the library is broken rather than the example.

One thing I decided not to change, in case you want to weigh in: the compose file publishes on port 5433, which collided with another Postgres I had running. Not wrong — 5433 is the conventional "second Postgres" port — but for an example that people run casually, something in the 55000s would collide with less. Happy either way.

The package-lock.json stays. It makes the example reproducible, which matters more here than the diff size.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants