Laravel's default single-database setup covers most applications, but connecting to a second (or third) database — a legacy system, a separate reporting database, a multi-tenant setup — is a matter of naming an additional connection and explicitly referencing it where needed.
The default single connection setup
// .env
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_DATABASE=myapp
DB_USERNAME=root
DB_PASSWORD=
// config/database.php
'default' => env('DB_CONNECTION', 'mysql'),
Adding a second named connection
// config/database.php
'connections' => [
'mysql' => [
// default connection config, using DB_* env vars
],
'legacy' => [
'driver' => 'mysql',
'host' => env('LEGACY_DB_HOST'),
'database' => env('LEGACY_DB_DATABASE'),
'username' => env('LEGACY_DB_USERNAME'),
'password' => env('LEGACY_DB_PASSWORD'),
],
],
// .env
LEGACY_DB_HOST=legacy-server.internal
LEGACY_DB_DATABASE=old_system
LEGACY_DB_USERNAME=readonly_user
LEGACY_DB_PASSWORD=secret
Adding a second array entry under connections is all the configuration needs — the new connection stays entirely unused until something explicitly references it by name, so simply defining it here has no effect on the application's normal, default-connection behavior.
Using a named connection with the query builder
$legacyUsers = DB::connection('legacy')->table('users')->get();
Using a named connection on an Eloquent model
class LegacyUser extends Model
{
protected $connection = 'legacy';
protected $table = 'users';
}
$users = LegacyUser::all(); // automatically queries via the 'legacy' connection
Setting $connection directly on the model class means every query built through that model automatically uses the named connection — no need to remember to call DB::connection() manually every time this specific model is queried.
Switching connections dynamically at runtime
$user = new LegacyUser();
$user->setConnection('legacy_readonly');
$results = $user->all();
setConnection() overrides a model's connection for a specific instance — genuinely useful for something like routing a specific report query to a read-replica connection while the rest of the application's queries continue using the primary connection.
Running queries across two connections in the same request
$currentUsers = User::all(); // default connection
$legacyUsers = LegacyUser::all(); // 'legacy' connection
$combined = $currentUsers->merge($legacyUsers);
Each connection maintains its own separate database handle — querying both in the same request works without any special handling, though it's worth remembering that a database transaction started on one connection has no effect on the other; they can't participate in the same atomic transaction together.
A practical multi-database use case: separate read and write connections
'mysql' => [
'read' => [
'host' => [env('DB_READ_HOST')],
],
'write' => [
'host' => [env('DB_WRITE_HOST')],
],
'driver' => 'mysql',
// shared config below
],
This specific split-host configuration is a built-in Laravel pattern for read/write database replication — reads automatically route to the read replica while writes go to the primary, all still referenced through the single mysql connection name, without needing the explicit named-second-connection approach shown above for this particular use case.