Chapter 62: Node.js MySQL Limit

LIMIT and OFFSET in MySQL queries from Node.js.

We will go through everything slowly and step by step, as if I am sitting next to you right now:

  • I open the MySQL client (Workbench / terminal / DBeaver) on one side
  • I open VS Code on the other side
  • We type every SQL line and every line of Node.js code live
  • I explain why we write it this way (security, performance, UX)
  • I show what most beginners do wrong (very common & dangerous mistakes)
  • I show what intermediate developers often forget (leads to bad APIs)
  • I show what real production code looks like in 2025–2026

Goal of this lesson

Learn how to implement pagination (LIMIT + OFFSET) correctly and safely in Node.js + MySQL.

At the end, you will be able to build a production-ready paginated list endpoint that:

  • Returns only 10–50 rows at a time
  • Lets the frontend ask for page 1, page 2, page 3…
  • Shows total count & total pages
  • Is safe from SQL injection
  • Is performant even with 1 million rows
  • Gives good API UX (hasNext, hasPrev, etc.)

Step 1 – Quick reminder: What LIMIT and OFFSET actually do

SQL
  • LIMIT n = maximum number of rows to return
  • OFFSET m = how many rows to skip from the beginning

Very important facts

  • OFFSET starts from 0 (not 1)
  • OFFSET can be very slow when large (e.g. OFFSET 1000000) — we’ll discuss solutions later
  • MySQL does not guarantee order without ORDER BY → always add ORDER BY

Step 2 – Project setup (minimal but complete)

If you don’t have the project yet:

Bash

tsconfig.json

JSON

package.json scripts

JSON

src/config/database.ts (connection pool – must-have)

TypeScript

Step 3 – Test data (run once in MySQL)

SQL

Step 4 – First paginated endpoint (basic version)

src/controllers/task.controller.ts

TypeScript

Route

TypeScript

Test URLs

  • http://localhost:5000/api/tasks?page=1&limit=5
  • http://localhost:5000/api/tasks?page=2&limit=5
  • http://localhost:5000/api/tasks?page=3&limit=10

Very important security notes

Wrong & dangerous (SQL injection possible)

TypeScript

Correct & safe

TypeScript

Why parameters are mandatory

MySQL treats :limit as a value, not code → impossible to inject malicious SQL.

Step 5 – Dynamic ORDER BY + WHERE + pagination (real API)

src/controllers/task.controller.ts

TypeScript

Example URLs

  • /api/tasks?page=1&limit=10&completed=true&sortBy=priority&sortOrder=asc
  • /api/tasks?page=2&limit=20&priority=high

Security & performance notes

  • Named placeholders → safe
  • Whitelisted sort columns → safe dynamic ORDER BY
  • LIMIT / OFFSET parameterized → safe
  • COUNT(*) separate query → accurate total (fast with index)
  • WHERE 1=1 → makes adding AND conditions safe & clean

Step 6 – Summary – ORDER BY + LIMIT best practices in Node.js + MySQL 2025–2026

Best Practice Why it matters Code pattern example
Always use ORDER BY Predictable order – MySQL doesn’t guarantee anything ORDER BY created_at DESC
Use named placeholders for LIMIT/OFFSET Security + readability LIMIT :limit OFFSET :offset
Whitelist dynamic sort columns Prevents SQL injection in ORDER BY if (allowedColumns.includes(sortBy))
Use pagination metadata Good API UX (totalPages, hasNext, hasPrev) Math.ceil(total / limit)
Add indexes on ORDER BY / WHERE columns 10×–1000× faster queries CREATE INDEX idx_created_at ON tasks(created_at)
Use connection pool Performance + safety mysql2.createPool()
Separate COUNT query Accurate total count SELECT COUNT(*) as total FROM tasks
Log slow queries in production Find performance killers MySQL slow query log + Node.js logging

Which part would you like to go much deeper into next?

  • Login + JWT authentication with MySQL
  • Full task CRUD (create/read/update/delete + ownership)
  • Add search, filtering, sorting, pagination all together
  • Replace raw SQL with Prisma (most popular choice today)
  • Replace raw SQL with Drizzle ORM (type-safe SQL)
  • Add Docker + docker-compose with real MySQL container

Just tell me what you want to build or understand next — I’ll continue with complete, secure, production-ready code and explanations. 😊

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *