Sequelize
NodeJS
database
query optimization
JavaScript

Specifying specific fields with Sequelize NodeJS instead of

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Introduction

Selecting only needed columns in Sequelize improves query performance, reduces payload size, and avoids exposing sensitive fields. This is the ORM equivalent of replacing SELECT * with explicit column lists. In production APIs, explicit attribute selection should be the default approach.

Basic attributes Usage

Use the attributes option in findAll, findOne, and related queries.

javascript
1const users = await User.findAll({
2  attributes: ["id", "email", "createdAt"]
3});
4
5console.log(users.map(u => u.toJSON()));

This returns only selected fields from the model table.

Exclude Sensitive Fields

When models have many columns, exclusion can be more maintainable.

javascript
const users = await User.findAll({
  attributes: { exclude: ["passwordHash", "resetToken"] }
});

Use exclusion carefully. For security critical endpoints, explicit allow lists are safer than broad excludes.

Alias Computed Columns

You can include computed expressions and aliases with Sequelize.fn or Sequelize.col.

javascript
1const { fn, col } = require("sequelize");
2
3const rows = await Order.findAll({
4  attributes: [
5    "customerId",
6    [fn("COUNT", col("id")), "orderCount"]
7  ],
8  group: ["customerId"]
9});

Alias names are useful for API response readability.

Attributes In Associations

When including related models, specify attributes for each include to prevent overfetching.

javascript
1const posts = await Post.findAll({
2  attributes: ["id", "title", "createdAt"],
3  include: [
4    {
5      model: User,
6      attributes: ["id", "displayName"]
7    }
8  ]
9});

Without per include control, responses can become large and slower to serialize.

Raw Mode And Lean Responses

If you only need plain objects, use raw: true to skip model instance overhead.

javascript
1const rows = await User.findAll({
2  attributes: ["id", "email"],
3  raw: true
4});
5
6console.log(rows[0]);

This can reduce CPU usage in high throughput read endpoints.

Pagination With Field Selection

Field selection pairs well with pagination for scalable API responses.

javascript
1const page = 1;
2const pageSize = 20;
3
4const users = await User.findAll({
5  attributes: ["id", "email", "createdAt"],
6  order: [["createdAt", "DESC"]],
7  offset: (page - 1) * pageSize,
8  limit: pageSize
9});

Avoid large unbounded queries, even when only a few columns are selected.

Type Safety And API Contracts

If your project uses TypeScript, define DTO shapes that match selected attributes. This prevents accidental property access that is not fetched by query.

Also align serializer logic with selected fields so API output remains predictable after query changes.

Debugging And SQL Verification

Enable logging to verify generated SQL contains only intended columns.

javascript
const sequelize = new Sequelize(process.env.DSN, { logging: console.log });

Regular SQL inspection helps catch accidental regressions to broad selects.

Security Focused Field Selection

Field selection is also a security boundary. If a model includes internal flags, tokens, or audit metadata, returning all fields by default can leak sensitive information through APIs or logs.

A good pattern is defining reusable attribute sets per endpoint type, for example public profile fields, admin fields, and internal diagnostics fields. Reuse these sets in query builders so permissions and output shape remain consistent.

javascript
const USER_PUBLIC_FIELDS = ["id", "displayName", "avatarUrl"];
const users = await User.findAll({ attributes: USER_PUBLIC_FIELDS });

Centralized field lists reduce accidental exposure when models evolve.

Query Plan Awareness

Even with selected fields, missing indexes can still hurt performance. Use database query plans to validate that predicates and ordering use indexes effectively. Field reduction helps payload size, but it is only one part of overall query optimization.

Common Pitfalls

  • Using exclusion lists where explicit allow lists are safer.
  • Forgetting to restrict attributes on included associations.
  • Accessing fields in code that were not selected in query.
  • Assuming raw: true returns model instance methods.
  • Ignoring pagination and fetching huge datasets.

Summary

  • Use Sequelize attributes to replace broad SELECT * behavior.
  • Prefer explicit field lists for performance and security.
  • Apply attribute selection to includes, not only root model.
  • Combine with pagination and optional raw mode for lean responses.
  • Verify generated SQL and align selected fields with API contracts.

Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.