FeathersJS Pagination: Server-Side Skip/Limit with params.pagination
Use params.pagination in FeathersJS to compute skip and limit server-side, delivering paginated API responses without manual offset math.
29 Oct 2025, 02:21 UTC

Problem: Large Result Sets in Feathers APIs
When an API returns thousands of records, sending them all at once overwhelms clients and hurts performance. The practical takeaway: use Feathers' built-in pagination via params.pagination to compute skip and limit server-side, delivering only the slice the client needs.
How params.pagination works
Feathers service find() accepts a params object. Inside params.pagination you place page (1-based) and limit. Feathers automatically translates these into the skip and limit clauses for the underlying query, so you never write manual offset math.
Hooks for safe defaults
Before the service method runs, Feathers executes hooks. You can set default pagination values, validate that page and limit are positive integers, or augment the query with additional filters without touching the core service logic.
Worked example
await userService.find({ query: { status: 'active' }, params: { pagination: { page: 2, limit: 20 } } })result.metadata will contain total, page, pageCount, etc.
Trade-off and limitation
Feathers does not persist pagination state across requests; each find() call resets params.pagination. Client applications must keep track of the current page number themselves, otherwise they may unintentionally request the wrong slice.
Additionally, if limit exceeds the number of matching rows, Feathers returns the available records without error. Callers should inspect the total or the length of the returned items array to detect end-of-data, and keep limit reasonable to avoid heavy database loads.
- Define a consistent pagination contract in your API documentation (e.g., page starts at 1, limit max 100).
- Add a before-handler hook that ensures
params.pagination.page>= 1 andparams.pagination.limit<= 100, defaulting to page 1 and limit 20 when omitted. - In client code, store the last page number and increment it after each successful request; disable the next button when result.metadata.total <= result.metadata.page * result.metadata.limit.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.