Updated June 2026. Tested on Laravel 13 and PHP 8.4.
A reader once asked me whether Laravel can send read queries to one database and write queries to another. This is a common setup when you replicate a primary database out to one or more read replicas, so that heavy SELECT traffic does not load the database that handles your writes. Laravel supports it directly, with no extra package.
Add read and write to the connection
Inside your mysql connection in config/database.php, add a read array and a write array. Anything you put in them overrides the shared settings below for that kind of query.
If the two servers share the same username and password, you only need to vary the host.
'mysql' => [
'driver' => 'mysql',
'read' => [
'host' => ['192.168.1.1'],
],
'write' => [
'host' => ['192.168.1.2'],
],
'sticky' => true,
'database' => env('DB_DATABASE', 'techalyst'),
'username' => env('DB_USERNAME', 'techalyst'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
],
Now every SELECT goes to 192.168.1.1 and every INSERT, UPDATE and DELETE goes to 192.168.1.2, while everything else, the database name, the credentials, the charset, is shared.
If the two servers use different credentials, put them inside the read and write arrays instead.
'read' => [
'host' => ['192.168.1.1'],
'username' => 'reader',
'password' => 'reader-password',
],
'write' => [
'host' => ['192.168.1.2'],
'username' => 'writer',
'password' => 'writer-password',
],
Do not skip the sticky option
The sticky option matters more than it looks. Replication has a small lag. Without sticky, you could write a row to the write database and then, a moment later in the same request, read from the replica before the change has caught up, and not see your own write.
With sticky set to true, once a write happens during a request, any reads for the rest of that request go to the write connection too. So a user always sees the change they just made. Leave it on unless you have a specific reason not to.
You do not change your code
The neat part is that your application code does not change. You keep writing normal Eloquent and query builder calls. Laravel looks at whether each query reads or writes and picks the right connection for you.
$products = Product::where('is_active', true)->get(); // goes to the read host
$product->update(['is_active' => false]); // goes to the write host
That is read and write splitting in Laravel: two arrays in the config, sticky turned on, and no changes to your queries. Questions welcome in the comments.
All comments ()
No comments yet
Be the first to leave a comment on this post.