It looks like the issue isn’t with Horizon itself, but with how SQL Server connections behave when child processes are spawned.
SQLSTATE[08S01] generally means the SQL Server connection is being dropped or is no longer valid by the time the job runs. This commonly happens when:
A database connection is opened before the worker forks
The new child process tries to reuse the same connection
SQL Server rejects it, causing 08S01 TCP errors
Why it happens
When Horizon auto-scales, it spawns new worker processes. If a database connection was already opened in the parent process (e.g., during bootstrap), the child processes inherit an invalid handle. As soon as they run a query, SQL Server throws the TCP Provider 0x2714 error.
Fixes Force Laravel to refresh DB connections per job
In your job, before running queries:
DB::purge('sqlsrv'); DB::reconnect('sqlsrv');
Disable persistent connections
In config/database.php, for the sqlsrv connection:
'persistent' => false,
Make sure no connection is made before forking
Any code that runs during boot and touches the DB should be avoided or delayed.
Restart workers after config change php artisan horizon:terminate
Why it only happens when new processes start
Parent worker is alive and its DB connection is valid
New workers inherit a connection that SQL Server considers invalid
First query in those workers immediately fails
Once workers reconnect, they continue working normally.