Reader Stacks

How to Set Up Multiple Database Connections in Laravel

Defining a second connection in config/database.php and pointing specific models or queries at it is all it takes to work with more than one database.

Working with more than one database — a legacy system, a reporting replica, a separate tenant database — is a matter of defining an additional connection in configuration and pointing specific models or queries at it, without needing a package for the basic case.

Defining a second connection

// config/database.php
'connections' => [
    'mysql' => [
        // default connection, as usual
    ],

    'legacy' => [
        'driver' => 'mysql',
        'host' => env('LEGACY_DB_HOST', '127.0.0.1'),
        'database' => env('LEGACY_DB_DATABASE'),
        'username' => env('LEGACY_DB_USERNAME'),
        'password' => env('LEGACY_DB_PASSWORD'),
        'charset' => 'utf8mb4',
        'collation' => 'utf8mb4_unicode_ci',
    ],
],
// .env
LEGACY_DB_HOST=127.0.0.1
LEGACY_DB_DATABASE=legacy_system
LEGACY_DB_USERNAME=legacy_user
LEGACY_DB_PASSWORD=secret

Using the second connection in a query builder call

$customers = DB::connection('legacy')->table('customers')->get();

Using it on an Eloquent model

class LegacyCustomer extends Model
{
    protected $connection = 'legacy';
    protected $table = 'customers';
}

$customers = LegacyCustomer::where('active', 1)->get();

Setting $connection on the model means every query through that model automatically targets the specified connection — no need to specify it again at each call site.

Running migrations against a specific connection

php artisan migrate --database=legacy
// in the migration itself, if it needs to target a non-default connection
public function up()
{
    Schema::connection('legacy')->table('customers', function (Blueprint $table) {
        $table->timestamp('synced_at')->nullable();
    });
}

Switching connections dynamically at runtime

config(['database.connections.tenant.database' => $tenant->database_name]);
DB::purge('tenant');

$orders = DB::connection('tenant')->table('orders')->get();

This runtime-switching pattern is the basis of a common multi-tenancy approach — each tenant gets its own physical database, and the app points the tenant connection at the correct one based on the current request. DB::purge() is necessary here because Laravel caches an already-resolved connection instance; without purging it, config changes made after that first resolution wouldn't take effect.

Querying across two connections in one request

Eloquent doesn't support a true cross-database join between separate connections — the common approach is running two separate queries (one per connection) and joining the results in PHP, or, if both databases genuinely live on the same MySQL server, using a fully-qualified database.table reference in a raw query instead.