Skip to main content
When working with large datasets, pagination is essential for performance and user experience. Esix provides a built-in paginate helper as well as the lower-level skip and limit methods.

paginate()

paginate(page, perPage) returns the requested page of results along with all the metadata you need to render a paginator. Pages are 1-indexed.
const result = await Post.where('published', true)
  .orderBy('publishedAt', 'desc')
  .paginate(1, 20)
{
  data: [/* 20 Post records */],
  total: 137,
  page: 1,
  perPage: 20,
  lastPage: 7
}
The same method is available as a static helper on the model:
const { data, total, lastPage } = await Post.paginate(1, 20)
{
  data: [/* 20 Post records */],
  total: 137,
  lastPage: 7
}
paginate validates its arguments and throws if page or perPage is not a positive integer.

Manual Pagination with skip and limit

When you need finer control, you can use skip to offset results and limit to control page size directly:
const page = 2
const perPage = 10
const offset = (page - 1) * perPage

const products = await Product.where('category', 'electronics')
  .skip(offset)
  .limit(perPage)
  .get()
idnamecategoryprice
60119e8a9f1b2c4d8e7f3a21Bluetooth Speakerelectronics59.00
60119e8a9f1b2c4d8e7f3a22Smart Bulbelectronics14.99
60119e8a9f1b2c4d8e7f3a23USB-C Hubelectronics34.50

Pagination with Sorting

When paginating, it’s important to use consistent sorting to ensure stable results across pages:
const getBlogPosts = async (page: number = 1, perPage: number = 10) => {
  return await BlogPost.where('status', 'published')
    .orderBy('createdAt', 'desc')
    .paginate(page, perPage)
}
This guide covers the pagination capabilities available in Esix. For more information about query methods, see the Retrieving Models guide.