Implementing Server-Side Pagination in CodeIgniter 4 with the Pager Class
Avoid memory exhaustion by implementing server-side pagination in CodeIgniter 4. Learn to integrate the Pager class with Models to fetch limited result sets efficiently.
17 Nov 2025, 13:29 UTC

Loading thousands of database rows into memory to display a simple list can crash PHP processes and degrade user experience. In CodeIgniter 4, the solution is server-side pagination, which fetches only the specific rows required for the current page while performing a separate count query to calculate total pages.
This approach ensures that whether your table has 100 or 100,000 records, the memory footprint of the request remains constant.
Prerequisites
- A functional CodeIgniter 4 installation (v4.0+).
- A database table configured in
app/Config/Database.php. - A Model class that extends
CodeIgniter\Model.
1. Configure the Model for Paginated Data
The CodeIgniter Model includes a built-in paginate() method. This method abstracts the LIMIT and OFFSET SQL logic, automatically calculating the offset based on the current page requested in the URL.
Create or update your model (e.g., app/Models/PostModel.php):
2. Controller Implementation
In the controller, call the paginate() method. This method performs two actions: it executes a COUNT(*) query to determine the total number of records and a second query to fetch only the slice of data for the current page.
paginate(10);
// The model stores the pager instance internally after paginate() is called
return view('posts_list', [
'posts' => $data['posts'],
'pager' => $model->pager
]);
}
}3. Rendering Navigation Links
The pager object passed to the view contains the logic to generate HTML links. Use the links() method to output the pagination controls.
<!-- app/Views/posts_list.php -->
<php foreach ($posts as $post) : ?>
<li><?= esc($post['title']) ?></li>
<php endforeach; ?>
<!-- Render pagination controls -->
<div class="pagination-container">
<?= $pager->links() ?>
</div>4. Customizing URL Parameters
By default, CodeIgniter 4 looks for a query parameter named page (e.g., /posts?page=2). If your routing requires a different parameter, modify app/Config/Pager.php.
| Property | Description |
|---|---|
$pageQueryParam | The key used in the query string to identify the page (default: 'page'). |
$perPage | The fallback number of items per page if not specified in the controller. |
$uriSegment | Used if pagination is handled via URI segments rather than query strings. |
Verification and Diagnostics
To verify that server-side pagination is working and not loading the entire dataset into memory, perform the following checks:
- SQL Inspection: Enable the Debug Toolbar. Check the "Database" tab to ensure the query contains
LIMIT 10 OFFSET Xrather than selecting all rows. - URL Validation: Append
?page=2to your URL. The content should change, and thepager->links()output should highlight the second page. - Count Accuracy: Ensure that any
where()clauses applied to the model before callingpaginate()are reflected in the total count. If you manually override the count, the pagination links will be mathematically incorrect.
Limitations
The paginate() method is specific to CodeIgniter 4. For legacy CodeIgniter 3 applications, this functionality is not available and must be implemented using manual $this->db->limit() and $this->db->offset() calls. Additionally, using very large offsets (deep pagination) can lead to performance degradation in some SQL engines; for extremely large datasets, consider cursor-based pagination.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.