Laravel artisan serve default port: 8000
Laravel artisan serve uses TCP port 8000 by default. php artisan serve tries the next port. When the server process exits with an error and neither --port nor SERVER_PORT sets the port, the serve command adds one to the port and starts again, up to a --tries limit that defaults to 10 (8.x and 13.x source).
Key facts
| Port | Protocol | Role | Category |
|---|---|---|---|
| 8000 | TCP | php artisan serve development server | Backend |
What happens when the port is busy
php artisan serve tries the next port. When the server process exits with an error and neither --port nor SERVER_PORT sets the port, the serve command adds one to the port and starts again, up to a --tries limit that defaults to 10 (8.x and 13.x source). With an explicit port there is no retry and the start fails. The app can therefore end up on 8001 or higher, so confirm which port is listening before you point a browser, proxy, or webhook at 8000.
Change the port
php artisan serve --port=8001An explicit --port also switches off the automatic retry, so a busy port fails instead of moving on.
php artisan serve --host=0.0.0.0 --port=8001--host=0.0.0.0 makes the server reachable from other devices on your network. Leave it off when only your own browser needs the app.
SERVER_PORT=8001 php artisan serveSERVER_PORT is read as the default for --port, so it also switches off the automatic retry. Laravel added it in 5.8.24.
Environment variable: SERVER_PORT. Sets the default value of the --port option of php artisan serve (added in Laravel 5.8.24). Laravel Reverb has its own variable, REVERB_SERVER_PORT, so SERVER_PORT does not move a Reverb server.
Bind address
Binds to 127.0.0.1 by default (the default of the host option in the framework’s ServeCommand source, 8.x and 13.x), so only your own Mac can reach it. Pass --host=0.0.0.0 to open it to your network. Laravel Reverb is different: its documentation says it starts at 0.0.0.0:8080, which is accessible from all network interfaces.
What else uses this port
TCP port 8000 is also the default for Django runserver.
The dataset is the 12 tools on the ports index.
Find and free this port
These commands find the process that holds TCP port 8000 and stop it. They come from the Port in use command generator. PID_NUMBER stands for the process ID you read from the first command: replace it before you run the others.
lsof -nP -iTCP:8000 -sTCP:LISTEN
ps -p PID_NUMBER -o pid,ppid,user,command
kill -TERM PID_NUMBERss -ltnp 'sport = :8000'
ps -p PID_NUMBER -o pid,ppid,user,command
kill -TERM PID_NUMBERGet-NetTCPConnection -LocalPort 8000 -State Listen -ErrorAction SilentlyContinue | Select-Object LocalAddress, LocalPort, State, OwningProcess
Get-CimInstance -ClassName Win32_Process -Filter "ProcessId = PID_NUMBER" | Select-Object ProcessId, ParentProcessId, Name, CommandLine
Stop-Process -Id PID_NUMBERRead the output of the second command before you stop anything, because the owner may be a container or another person’s process. Then run the first command again to confirm the port is free.
Next free ports
Counting up from 8000, the next three ports that no tool in this dataset uses as a default are 8001, 8002, and 8003. They are suggestions only: another program on your machine may hold any of them, so run the find command above before you choose one.
In Rig
Rig detects Laravel projects through Composer and artisan, runs the artisan sidecars (queue, horizon, schedule, and reverb) as Rig processes, and tails storage/logs/laravel.log into the log pane. Rig does not serve Valet sites. When a port is already held, who_owns_port returns the owning PID, command, and working directory plus the first free port in the 50 above it, and start_project can kill the owner (resolve_port=kill), switch the project to a free port (resolve_port=suggest), or return a portConflict that names the owner and a suggested port.
Collisions in practice
Port 8000 is shared by more than one tool in a Laravel project. php artisan serve and Laravel Octane both default to it, and Reverb takes 8080 on every network interface, so a project that uses all three needs a port plan before the first start. The automatic retry in artisan serve hides the clash and moves it: a busy 8000 becomes 8001 without you asking, while a webhook tunnel, a proxy target, or an OAuth redirect URI still points at 8000 and reaches whatever else owns that port. Pass --port whenever something else depends on the number.
Frequently asked questions
Does php artisan serve move to another port when 8000 is busy?
It can. In the framework source (8.x and 13.x) the serve command retries on the next port each time the server process exits with an error, up to a --tries limit that defaults to 10, but only when neither --port nor SERVER_PORT sets the port. With an explicit port it stops and the start fails. Because the app may end up on 8001 or higher, confirm which port is listening before you point a browser, proxy, or webhook at 8000.
Do php artisan serve and Laravel Octane use the same port?
Both default to 8000, so starting both for one project collides. The Octane documentation says it starts on port 8000 by default and takes --host and --port options. Give one of them a different port with --port.
How do I open php artisan serve to other devices on my network?
Pass --host=0.0.0.0, for example php artisan serve --host=0.0.0.0 --port=8000. The default host is 127.0.0.1, which only your own machine can reach. Anyone on the same network can then request the app, so use it on a network you trust.
Sources
- Laravel 10.x installation: php artisan serve starts a server at http://localhost:8000
- Laravel 4.2 quickstart: the server listens on port 8000, change it with --port
- Laravel blog, v5.8.24 release notes: ServeCommand port from SERVER_PORT
- Laravel API reference (10.x): ServeCommand and canTryAnotherPort
- laravel/framework source (8.x branch): ServeCommand host, port, and tries defaults and retry logic
- laravel/framework commit 6a18e73: respect explicit port
- Laravel Octane: default port 8000, --host, and --port
- Laravel Reverb: default 0.0.0.0:8080 and REVERB_SERVER_PORT
Busy ports in Rig
When a start fails because a port is taken, Rig shows which process owns it when it can, and lets you reclaim the port or choose another. You do not need Rig to use this page.