logo

Eager loading can query the wrong database

A subtle trap when using multiple connections

Joel Clermont
Joel Clermont
2026-02-16

If you're working with multiple database connections in Laravel, there's a subtle trap waiting for you when eager loading relationships.

Let's say you have an Order model that lives on an external database, and a Customer model on your default mysql connection:

class Order extends Model
{
    protected $connection = 'external';

    public function customer(): BelongsTo
    {
        return $this->belongsTo(Customer::class);
    }
}
class Customer extends Model
{
    // No $connection property, just uses the default
}

You might expect Order::with('customer')->get() to query the external database for orders and the mysql database for customers. But that's not what happens. Instead, Laravel tries to find the customers table on the external connection, and it fails.

To understand why, look at the newRelatedInstance() method in Laravel's HasRelationships trait:

protected function newRelatedInstance($class)
{
    return tap(new $class, function ($instance) {
        if (! $instance->getConnectionName()) {
            $instance->setConnection($this->connection);
        }
    });
}

Every relationship method calls this to create a fresh instance of the related model. It checks whether the related model has a connection set. If getConnectionName() returns null, meaning no explicit $connection property, it inherits the parent model's connection.

The fix is simple: explicitly set the $connection property on the related model, even if it's the default.

class Customer extends Model
{
    protected $connection = 'mysql';
}

Now getConnectionName() returns 'mysql' instead of null, the inheritance check is skipped, and the query runs on the correct database.

It's a small change, but it highlights an important distinction. In Laravel, "no connection" and "the default connection" are not always the same thing. When you're working with multiple connections and eager loading, that difference matters.

Here to help,

Joel

P.S. Bugs like this are easy to miss in your own code. A second set of eyes can help. Learn more about our code review service.

Toss a coin in the jar if you found this helpful.
Want a tip like this in your inbox every weekday? Sign up below 👇🏼
email
No spam. Only real-world advice.