Laravel Paginate usage with DB::raw query

Stefan Bogdanescu

Founder & Senior Architect · 2026-06-29

Laravel Company

Laravel Pagination with DB::raw() Queries: A Developer's Guide

When working with complex database queries that involve raw expressions or calculated fields—often achieved using DB::raw()—applying standard pagination methods like paginate() can seem tricky. You are dealing with a result set generated directly by the Query Builder, rather than a clean Eloquent Model collection.

This post will walk you through exactly how to successfully use paginate() when your initial data retrieval relies on intricate joins and calculated columns defined via DB::raw().

The Challenge: Raw Results vs. Eloquent Models

The core issue lies in the difference between fetching data via an Eloquent model (which handles relationships, casting, and automatic querying) and fetching raw results using DB::select() or DB::raw().

When you execute a query using DB::select(DB::raw(...)), Laravel returns a simple PHP array of results. Standard Eloquent methods like paginate() are designed to work directly on Eloquent Collections, which contain objects that map cleanly to your defined models. Therefore, applying pagination requires understanding how the underlying Query Builder handles result sets.

Solution 1: Direct Pagination on the Raw Result

The most direct way to paginate a set of results generated by DB::select() is to apply the paginate() method directly to the resulting collection object. This works because Laravel’s Query Builder methods are designed to handle this transition smoothly.

Let's take your provided query:

$query = DB::select(DB::raw(" 
    select a.user_id, a.user_email, a.user_account_status, a.created_at, 
           b.s_account_limit AS account_limit,
           c.consumed_limit,
           ((b.s_account_limit*1024) - c.consumed_limit) AS remaining_limit 
    FROM upload_limits as b, users as a 
    JOIN user_upload_limits as c 
    WHERE (a.user_id=c.user_id) AND a.user_type='Simple'
"));

// Applying paginate() to the result set
$paginatedResults = $query->paginate(15); 

Explanation:

In this scenario, $query holds the raw array of data retrieved from the database. When you call $query->paginate(15), Laravel intelligently wraps this raw result into a Paginator object, providing you with the necessary links, current page, and total count metadata, all while maintaining the integrity of your calculated columns derived from DB::raw().

This approach is perfectly valid for complex reports or data dumps where you don't necessarily need to map every row back to an Eloquent model immediately. This flexibility shows the power of Laravel’s underlying structure, which is a key feature of modern development built around frameworks like Laravel.

Solution 2: The Eloquent Best Practice (Recommended)

While Solution 1 works, the preferred method in a typical Laravel application is to leverage Eloquent Models and relationships whenever possible. This offers superior maintainability, readability, and leverages Laravel’s powerful ORM features.

Instead of forcing complex calculations into DB::raw(), consider restructuring your data using Eloquent models with appropriate relationships. If you were fetching users who meet certain criteria, you would typically start with the model:

// Example structure assuming you have User and UploadLimit models
$users = App\Models\User::where('user_type', 'Simple')
    ->with('uploadLimit') // Assuming a relationship exists
    ->paginate(15);

If the calculation must happen in the database, it is often cleaner to define these complex calculations as Database Columns or use Eloquent Accessors/Mutators, rather than relying solely on DB::raw() within a generic select(). This keeps your application logic separate from complex SQL structure, adhering to the principles of clean architecture that Laravel encourages.

Conclusion

To summarize, you absolutely can use paginate() with queries involving DB::raw(). The key is understanding that you are applying pagination to the result set returned by the Query Builder, not necessarily an Eloquent Model collection. For simple data retrieval or complex reporting, Solution 1 provides a direct path. However, for application-level data management, leaning into Eloquent Models and leveraging relationships will provide a more robust, scalable, and maintainable solution, as demonstrated in best practices within the Laravel ecosystem.