[Frontend] Limit `SO_REUSEPORT` to multi-worker serving (#47529)

Signed-off-by: Bugen Zhao <i@bugenzhao.com>

Bugen Zhao committed Jul 4, 2026 at 09:26 UTC ab3b6d97aa02af45b96607042d75eedefd1e122e
3 files changed +12 -7
vllm/entrypoints/cli/launch.py
+1 -1
@@ -120,7 +120,7 @@ async def run_launch_fastapi(args: argparse.Namespace) -> None:
120 signal.signal(signal.SIGTERM, _interrupt_init)
121
122 # 1. Socket binding
123 - listen_address, sock = setup_server(args)
123 + listen_address, sock = setup_server(args, reuse_port=False)
124
125 # 2. Build and serve the API server
126 engine_args = AsyncEngineArgs.from_cli_args(args)
vllm/entrypoints/cli/serve.py
+1 -1
@@ -281,7 +281,7 @@ def run_multi_api_server(args: argparse.Namespace):
281 signal.signal(signal.SIGTERM, signal_handler)
282 signal.signal(signal.SIGINT, signal_handler)
283
284 - listen_address, sock = setup_server(args)
284 + listen_address, sock = setup_server(args, reuse_port=num_api_servers > 1)
285
286 engine_args = vllm.AsyncEngineArgs.from_cli_args(args)
287 engine_args._api_process_count = num_api_servers
vllm/entrypoints/openai/api_server.py
+10 -5
@@ -508,14 +508,19 @@ async def init_render_app_state(
508 state.server_load_metrics = 0
509
510
511 -def create_server_socket(addr: tuple[str, int]) -> socket.socket:
511 +def create_server_socket(
512 + addr: tuple[str, int],
513 + *,
514 + reuse_port: bool,
515 +) -> socket.socket:
516 family = socket.AF_INET
517 if is_valid_ipv6_address(addr[0]):
518 family = socket.AF_INET6
519
520 sock = socket.socket(family=family, type=socket.SOCK_STREAM)
521 sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
518 - sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
522 + if reuse_port:
523 + sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
524 sock.bind(addr)
525
526 return sock
@@ -546,7 +551,7 @@ def validate_api_server_args(args):
551
552
553 @instrument(span_name="API server setup")
549 -def setup_server(args):
554 +def setup_server(args, *, reuse_port: bool):
555 """Validate API server args and create the server socket."""
556
557 log_version_and_model(logger, VLLM_VERSION, args.model)
@@ -567,7 +572,7 @@ def setup_server(args):
572 sock = create_server_unix_socket(args.uds)
573 else:
574 sock_addr = (args.host or "", args.port)
570 - sock = create_server_socket(sock_addr)
575 + sock = create_server_socket(sock_addr, reuse_port=reuse_port)
576
577 # workaround to avoid footguns where uvicorn drops requests with too
578 # many concurrent requests active
@@ -688,7 +693,7 @@ async def run_server(args, **uvicorn_kwargs) -> None:
693
694 signal.signal(signal.SIGTERM, _interrupt_init)
695
691 - listen_address, sock = setup_server(args)
696 + listen_address, sock = setup_server(args, reuse_port=False)
697 await run_server_worker(listen_address, sock, args, **uvicorn_kwargs)
698
699