Abdulhamed Zaghoul
Laravel Abdulhamed Zaghoul Dec 05, 2025 155 views 1 comments

Query Builder vs Eloquent in Laravel

Use Eloquent when code readability matters Use Query Builder when performance or SQL complexity matters. Most senior developers use both — depending on the task

When you first start working with Laravel, you quickly discover that there are two completely different ways to interact with your database:

  • - Query Builder
    - Eloquent ORM

  • Both can fetch, update, and delete data
    Both live inside the Laravel core.
    But they feel very different — like two different “languages” for the same database
    .

    This article explains the real differences, the tricky parts, and the best use cases for each one — without the confusing, textbook-style explanations.

    Let’s get into it.

    **What Is Query Builder?

    You tell the database exactly what to do:

    • - What table to read

    • - What columns to fetch

    • - What joins to apply

    • - What filters to run

    Example:

    $users = DB::table('users')->where('active', 1)->get();

    You get raw data (stdClass), not models.

    ** When Query Builder shines:

    • - Large datasets

    • - Heavy analytics

    • - Multi-table joins

    • - When performance is the #1 priority

    • - When you don’t need relationships or model features

    It’s fast, strict, and predictable.

    **What Is Eloquent?

    Eloquent is an ORM: Object Relational Mapper.
    It lets you treat database rows as PHP objects.

    Each table = one model
    Each row = one object

    Example:

    $users = User::where('active', 1)->get();

    You don’t think in SQL —
    you think in objects, relationships, and methods.

    **Eloquent shines when:

    • - You have relationships between tables

    • - You want clean, readable code

    • - Your data has logic

    • - You want accessors, mutators, events, soft deletes

    • - You’re building CRUD or API endpoints

    It’s more “human-friendly,” but has overhead.

    *** JOINs: The Biggest Difference

    This is where most developers feel the gap between both approaches.

    ** Query Builder JOIN

    You write the join manually:

    $orders = DB::table('orders') ->join('users', 'orders.user_id', '=', 'users.id') ->select('orders.*', 'users.name') ->get();

    Feels very SQL-like.
    You control everything.

    **Eloquent JOIN (yes, it exists)

    $orders = Order::join('users', 'orders.user_id', '=', 'users.id') ->select('orders.*', 'users.name') ->get();

    Works, but defeats the point of Eloquent.

    ** The REAL Eloquent Way: Relationships

    User model:

    public function orders() { return $this->hasMany(Order::class); }

    Fetch:

    $users = User::with('orders')->get();

    Way cleaner.
    Zero SQL in your code.
    Less noise.

    But… slower for huge datasets.

    *** Return Types: A Very Important Difference

    **Query Builder returns:

    • raw objects (stdClass)

    • arrays (if you use ->get()->toArray())

    You get basic data.

    **Eloquent returns:

    • full model objects

    • with accessors

    • with casts

    • with events

    • with hidden fields

    • with loaded relationships

    You get intelligent data, not raw rows.

    *** Inserts, Updates, Deletes

    **Query Builder

    DB::table('users')->insert([...]); DB::table('users')->where('id', 1)->update([...]); DB::table('users')->delete(1);

    **Eloquent

    $user = new User(); $user->name = 'John'; $user->save(); $user = User::find(1); $user->name = 'New'; $user->save(); User::destroy(1);

    Clean, expressive, object-oriented.

    *** Performance (Honest Comparison)

    This is the truth:

    ** Query Builder

    • - Faster

    • - Lower RAM usage

    • - You fetch exactly what you need

    • - No model overhead

    **Eloquent

    • - Slightly slower

    • - Wraps rows into models

    • - Loads relationships

    • - Auto-handles mutators/casts

    For normal apps, Eloquent is perfect.
    For heavy data processing, Query Builder wins easily.

    *** Relationships vs Joins — The Heart of the Difference

    Query Builder → You join manually

    Eloquent → You define relationships once

    Example:
    Get all users with their posts.

    **Query Builder:

    DB::table('users') ->join('posts', 'users.id', '=', 'posts.user_id') ->get();

    **Eloquent:

    User::with('posts')->get();

    Big difference in readability.

    *** Hidden Differences Nobody Mentions

    # 1. Timestamps

    Eloquent auto-updates created_at and updated_at.

    Query Builder does nothing automatically.

    # 2. Accessors & Mutators

    Eloquent:

    public function getFullNameAttribute() { return $this->first_name . ' ' . $this->last_name; }

    Query Builder?
    You must compute it manually every time.

    # 3. Casting (important!)

    Eloquent:

    protected $casts = [ 'is_active' => 'boolean', 'settings' => 'array', ];

    Query Builder:
    You get raw DB strings.

    # 4. Model Events

    Eloquent:

    protected static function booted() { static::created(function ($user) { Log::info('New user created'); }); }

    Query Builder:
    No events at all.

    # 5. Soft Deletes

    -Eloquent:

    use SoftDeletes;

    -Query Builder:
    You must filter deleted rows manually.

    *** When Should You Use Which?

    **Use Eloquent if:

    • - Your table has relationships

    • - Your logic is object-oriented

    • - You want readable, clean code

    • - Your app isn’t heavy on SQL performance

    • - You want automatic casting/events/scopes

    **Use Query Builder if:

    • - Performance is key

    • - You're doing reporting or analytics

    • - You need many joins

    • - You’re working with hundreds of thousands of rows

    • - You don’t need model features

    *** Final Side-by-Side Example

    Goal:
    Get all active users with their orders, newest order first, selecting only needed columns.

    **Query Builder:

    $users = DB::table('users') ->join('orders', 'users.id', '=', 'orders.user_id') ->where('users.status', 'active') ->select( 'users.id', 'users.name', 'orders.total', 'orders.created_at' ) ->orderBy('orders.created_at', 'desc') ->get();

    **Eloquent:

    User model:

    public function orders() { return $this->hasMany(Order::class); }

    Query:

    $users = User::where('status', 'active') ->with(['orders' => function ($q) { $q->select('id', 'user_id', 'total', 'created_at'); }]) ->get();

    Cleaner, more readable — but slightly heavier.

    Keywords:
    laravel laravel eloquent eloquent orm query builder laravel query builder eloquent vs query builder laravel performance laravel joins eloquent relationship php framework database queries laravel laravel tutorial laravel best practices orm vs query builder laravel beginners laravel guide laravel tips eloquent examples query builder examples

    Comments (1)

    Emad
    Dec 05, 2025

    Very Good -- it is very useful

    Leave a Comment

    Configuration

    COLORS