Multiple DB Connections in Laravel

A long, long time ago (2013), I answered on this SO question about using 2 database connections.

For some reason, over a decade later, this page still ranks. Let's do an update!

Here is how to run more than one database connection.

This article is about using databases with different data, not necessary for load balancing (or connection pooling) between databases. However Laravel does have the ability to split read vs write queries amongst connections out of the box now.

Laravel's documentation on multiple connections, is light - let's fill these out a bit.

Defining Connections

Inside of your datbase configuration file - config/database.php - you can define more than one database connection of any type. In fact, you can define as many connections as you'd like.

If your application has to pull data from 2 MySQL databases, you can define them both separately:

<?php

return array(
    
    'default' => 'mysql',
    
    'connections' => array(
    
        # Our primary database connection
        'mysql' => [
            'driver' => 'mysql',
            'url' => env('DATABASE_URL'),
            'host' => env('DB_HOST', '127.0.0.1'),
            'port' => env('DB_PORT', '3306'),
            'database' => env('DB_DATABASE', 'forge'),
            'username' => env('DB_USERNAME', 'forge'),
            'password' => env('DB_PASSWORD', ''),
            'unix_socket' => env('DB_SOCKET', ''),
            'charset' => 'utf8mb4',
            'collation' => 'utf8mb4_unicode_ci',
            'prefix' => '',
            'prefix_indexes' => true,
            'strict' => true,
            'engine' => null,
            'options' => extension_loaded('pdo_mysql') ? array_filter([
                PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
            ]) : [],
        ],
    
        # Our secondary database connection
        'mysql2' => [
            'driver' => 'mysql',
            'url' => env('DATABASE_URL'),
            'host' => env('DB_HOST', '127.0.0.1'),
            'port' => env('DB_PORT', '3306'),
            'database' => env('DB_DATABASE', 'forge'),
            'username' => env('DB_USERNAME', 'forge'),
            'password' => env('DB_PASSWORD', ''),
            'unix_socket' => env('DB_SOCKET', ''),
            'charset' => 'utf8mb4',
            'collation' => 'utf8mb4_unicode_ci',
            'prefix' => '',
            'prefix_indexes' => true,
            'strict' => true,
            'engine' => null,
            'options' => extension_loaded('pdo_mysql') ? array_filter([
                PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
            ]) : [],
        ],
    ],
    ),
);

We have our default connection still set to mysql. This means that, unless we specify otherwise, the application will use thet mysql connection.

Specify a Connection

Now that we have a 2nd database connection setup - how do we use it in code?

It turns out there's a few ways!

Schema

Within the Schema Builder, you can use the Schema facade with any connection. To specify which connection to use, simply run the connection() method:

Schema::connection('mysql2')->create('some_table', function($table)
{
    $table->increments('id'):
});

Query

Similar to Schema Builder, you can define a connection on the Query Builder:

$users = DB::connection('mysql2')->select(...);

Eloquent

You can also define which connection to use in your Eloquent models as well!

One way is to set the $connection variable in your model:

<?php

class SomeModel extends Eloquent {

    protected $connection = 'mysql2';

}

You can also define the connection at runtime via the setConnection method.

<?php

class SomeController extends BaseController {

    public function someMethod()
    {
        $someModel = new SomeModel;
        
        $someModel->setConnection('mysql2');
        
        $something = $someModel->find(1);
        
        return $something;
    }

}

Lastly, you can call a model::on() statically:

function handle()
{
    Subscription::on('mysql2')
        ->where('stripe_id', 'sub_xyz')
        ->get();
}

Dynamic Connection

If you need to handle connections dynamically, say with a multi-tenant database setup (bless your heart), you're likely looking at using some Service Provider logic to dynamically set which database connection is used (perhaps as the default).

It might be useful to hook into Laravel's Container Events to set a connection when it's resolving the db service:

// Perhaps within app/Providers/AppServiceProvider.php

use Illuminate\Database\DatabaseManager;
use Illuminate\Contracts\Foundation\Application;

$this->app->resolving('db', function(DatabaseManager $dbManager, Application $app) {
    $dbManager->setDefaultConnection('some-connection');
});

Similarly, you can either use (or look for clues) in multi-tenancy setups via https://tenancyforlaravel.com/ and it's GitHub repo.

A Note

Be careful about attempting to build relationships with tables across databases! It is possible to do, but it can come with some caveats and depends on what database and/or database settings you have.