Filament 3.0 Table Pagination: Default paginate() vs simplePaginate()
0 reputation · 06 May 2020, 04:36 UTC
0 reputation · 06 May 2020, 04:36 UTC
Determine which Eloquent pagination method the Filament 3.0 Table component invokes by default, and assess the impact on memory usage and hosting costs for low‑traffic sites.
The Table component’s query builder appears to call Eloquent’s paginate(), which performs a COUNT(*) and loads the full result set for the current page. The per‑page limit is hard‑coded to 10 unless overridden via setPerPageOptions(). The documentation does not clarify whether simplePaginate() is ever employed, leaving uncertainty about query efficiency on very large tables.
paginate() or simplePaginate() by default for all queries?simplePaginate() without altering the table class?30775 reputation · 06 May 2020, 14:49 UTC
By default, Filament 3.0 Table components invoke Eloquent's paginate(), not simplePaginate(). The table's record-resolution logic (in the InteractsWithTableRecords concern used by the HasTable trait) calls $query->paginate($this->getTableRecordsPerPage()), which executes a COUNT(*) query before fetching the current page. This applies to Filament 3.x; verify against your installed version, since internals can shift between minor releases.
There is no global configuration flag or hook to change the pagination method. The only route is overriding the record-fetching method per Table class (Resource, Page, or Widget):
protected function getTableRecords(): \Illuminate\Contracts\Pagination\Paginator
{
return $this->getTableQuery()->simplePaginate($this->getTableRecordsPerPage());
}
The per-page default of 10 is separately adjustable via ->defaultPaginationPageOption(25) or ->paginationPageOptions([10, 25, 50]), but that does not change the pagination method.
paginate() "loads the full result set" is incorrect—it loads one page plus runs a count.COUNT(*) query is the real difference. On indexed tables up to a few million rows it is typically tens of milliseconds; on unindexed or heavily joined queries it can reach hundreds of milliseconds.simplePaginate() fetches limit + 1 rows and skips the count, but it returns no total or last page. Filament's default pagination UI (numbered pages, total count, "last" link) depends on a LengthAwarePaginator, so switching degrades the UI to previous/next unless you build custom controls.
vendor/filament/tables/src/ for the paginate( call in the record-resolution concern.DB::enableQueryLog(), render the table, and confirm a COUNT(*) precedes the limited SELECT.EXPLAIN SELECT COUNT(*) FROM your_table; to decide whether the count is actually your bottleneck.For low-traffic sites, keep the default. If the count query is genuinely expensive (complex joins, GROUP BY, 5M+ unindexed rows), prefer a cached count or covering index over simplePaginate(), which sacrifices the pagination UX.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.