SGLang is an inference server for running open models at scale. It loads language, vision-language and diffusion models from Hugging Face and serves them through an OpenAI-compatible API, using RadixAttention to reuse cached prompt prefixes between requests, plus continuous batching, speculative decoding, quantization and parallelism across many GPUs and machines. It is tuned for agent workloads with long shared prompts and for the generation step of reinforcement-learning training.
It is hosted by LMSYS, the group that started Chatbot Arena, and has about 38,000 stars and over 2,100 contributors, at v0.5.22. Hardware support is broad: NVIDIA from RTX cards to GB300, AMD Instinct, Google TPUs, Intel GPUs and Xeon CPUs, Huawei Ascend, and Apple Silicon. It is Apache-2.0.
Like vLLM, it is built for serving many requests rather than one person's chat. If you only want a model on your laptop, Ollama or LM Studio is simpler; if you are serving an application, SGLang and vLLM are the two to compare.
- Repository: github.com/sgl-project/sglang
- Licence: Apache-2.0 (Apache License 2.0)
- Language: Python. Stars: 38.2K. Forks: 9,898. Last push: Oct 26, 2026.
- Scan: safe, Oct 26, 2026, commit af21e2b
Who it is for
Teams serving open models to applications or many users, researchers running RL training that needs fast generation, and anyone with data-center GPUs who wants the most throughput from them.
Getting started
1. Install with uv in an activated Python environment (or docker pull lmsysorg/sglang:latest)
uv pip install --prerelease=allow sglang2. Download a model from Hugging Face and serve it
sglang serve --model-path Qwen/Qwen3-8B3. Query it like the OpenAI API (port 30000 by default)
curl http://localhost:30000/v1/chat/completions -H "Content-Type: application/json" -d '{"model":"Qwen/Qwen3-8B","messages":[{"role":"user","content":"Hello"}]}'The Cookbook at cookbook.sglang.io gives a tested launch command for each model and GPU. Pass --api-key before exposing the server beyond localhost.
Safety scan
We cloned sgl-project/sglang at commit af21e2b on Oct 26, 2026 and ran the checks described on the GitHub Tools page: credential patterns, decode-and-execute code, install-time scripts, committed binaries, risky CI workflows, every host the code talks to, known vulnerabilities in pinned dependencies, and project hygiene. A person read every hit. This is what we found.
- No self-decoding code and no bare-IP URLs across 3.6 million lines, mostly Python with Rust. The one secret hit is a test private key in sgl-model-gateway/tests/security/mtls_test.rs.
- Of the 14 pattern hits, ten are Dockerfiles and CI scripts installing uv or Rust with their official curl | sh installers, one is a CI log-analysis script installing opencode the same way, and two are os.dup2 calls in mindspore_runner.py that redirect a worker's output to a log file, which the scanner mistook for a socket trick.
- python/setup.py has a custom build command that compiles the Rust extensions with cargo; it fetches nothing else. The one committed binary is a precompiled AMD GPU kernel (.co) for gfx950 chips, part of the attention kernels.
- 49 advisories, 2 critical: one in the zip crate (rust/sglang-radix-tree) and one in gRPC-Go (the Go bindings and their example server). The Python dependencies are ranges with no lockfile, so the check had nothing to read there.
- 123 workflows. Nine are listed under pull_request_target; those that actually run on it post status or apply labels, and the Cambricon MLU test is gated by maintainer labels and hands the commit to an isolated external runner without checking it out. Only 4 of 125 third-party actions are pinned to a commit. CodeQL and code of conduct present; no security policy.
What the scanner counted
| Check | Result |
|---|---|
| Secrets | 1 candidate found and read; see the notes above. |
| Suspicious code | 14 pattern hits found and read; every one is listed under the raw findings. |
| Install-time code | 1 setup.py with custom install logic. 3 Cargo build scripts. 14 installer scripts (one edits your shell profile; one can call sudo) |
| Committed binaries | 1 executable or compiled object committed; listed under the raw findings. |
| CI workflows | 123 workflows. 9 use pull_request_target, none check out the pull request head. 121 of 125 third-party actions pinned to a tag rather than a commit. |
| Network hosts | 40 distinct hosts referenced from source; most often github.com, www.apache.org, huggingface.co, raw.githubusercontent.com. No URLs to bare IP addresses. |
| Known vulnerabilities | 49 advisories across 767 pinned packages: 2 critical, 9 high, 5 moderate, 2 low, 31 unrated. rust/Cargo.lock: 543 packages, 15 advisories; rust/sglang-radix-tree/Cargo.lock: 97 packages, 3 advisories; sgl-model-gateway/bindings/golang/examples/oai_server/go.mod: 15 packages, 23 advisories; sgl-model-gateway/bindings/golang/go.mod: 6 packages, 21 advisories; sgl-router/Cargo.lock: 504 packages, 9 advisories; sgl-router/tests/e2e/k8s_integration/requirements.txt: 2 packages, 1 advisories; sgl-router/tests/e2e/requirements.txt: 3 packages, 1 advisories. |
| Project hygiene | Has CodeQL, licence file. Missing security policy, automated dependency updates, contributing guide. |
| OpenSSF Scorecard | Not scored: the project is not in Scorecard's weekly index. |
The raw findings
Every hit the scanner wrote out, with a link to the exact line at the scanned commit. Secrets candidates are redacted.
Secret candidates (1, redacted)
| Where | Rule | Match |
|---|---|---|
| sgl-model-gateway/tests/security/mtls_test.rs:454 | private-key | -----B…--- (27 chars) |
Pattern hits (14)
| Where | Rule | Match |
|---|---|---|
| .devcontainer/Dockerfile:30 | download-piped-to-shell | RUN curl -LsSf https://astral.sh/uv/install.sh | sh |
| .devcontainer/Dockerfile:33 | download-piped-to-shell | RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y |
| docker/Dockerfile:369 | download-piped-to-shell | curl --proto '=https' --tlsv1.2 --retry 3 --retry-delay 2 -sSf https://sh.rustup.rs | sh -s -- -y \ |
| docker/arm64.Dockerfile:27 | download-piped-to-shell | RUN curl -LsSf https://astral.sh/uv/install.sh | sh && \ |
| docker/gateway.Dockerfile:25 | download-piped-to-shell | RUN curl -LsSf https://astral.sh/uv/install.sh | sh |
| docker/gateway.Dockerfile:46 | download-piped-to-shell | RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y \ |
| docker/rocm-gfx1151.Dockerfile:67 | download-piped-to-shell | RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal \ |
| docker/rocm.Dockerfile:735 | download-piped-to-shell | RUN curl --proto '=https' --tlsv1.2 --retry 5 --retry-delay 3 --retry-all-errors -sSf https://sh.rustup.rs | sh -s -- -y \ |
| docker/xeon.Dockerfile:29 | download-piped-to-shell | RUN curl -LsSf https://astral.sh/uv/install.sh | sh && \ |
| docker/xpu.Dockerfile:68 | download-piped-to-shell | RUN curl -LsSf https://astral.sh/uv/install.sh | sh |
| python/sglang/srt/model_executor/mindspore_runner.py:60 | raw-socket-shell | os.dup2(scheduler_f.fileno(), 1) |
| python/sglang/srt/model_executor/mindspore_runner.py:61 | raw-socket-shell | os.dup2(scheduler_f.fileno(), 2) |
| scripts/ci/slurm/analyze_logs_with_modal.py:157 | download-piped-to-shell | "curl -fsSL https://opencode.ai/install | bash", |
| scripts/ci/slurm/launch_gb200.sh:81 | download-piped-to-shell | curl -LsSf https://astral.sh/uv/install.sh | sh |
Installer scripts (14)
- .agents/skills/llm-torch-profiler-analysis/scripts/run_llm_single_model_matrix_host.sh, 275 lines
- .agents/skills/llm-torch-profiler-analysis/scripts/run_sglang_torch_profile_host.sh, 242 lines
- .agents/skills/llm-torch-profiler-analysis/scripts/run_trtllm_pytorch_profile_host.sh, 408 lines
- .agents/skills/llm-torch-profiler-analysis/scripts/run_vllm_torch_profile_host.sh, 344 lines
- 3rdparty/amd/profiling/install_rpd.sh, 11 lines; talks to github.com
- scripts/ci/npu/precise-test/run_tests_with_coverage.sh, 297 lines
- scripts/ci/ppu/run_selftests.sh, 28 lines
- scripts/ci/ppu/run_test.sh, 248 lines
- scripts/ci/utils/install_protoc.sh, 54 lines; talks to github.com
- scripts/ci/utils/install_rust_protoc.sh, 25 lines, uses sudo
- scripts/ci/utils/install_rustup.sh, 145 lines; talks to sh.rustup.rs
- scripts/code_sync/install_github_cli.sh, 19 lines; talks to cli.github.com
- sgl-model-gateway/e2e_test/k8s_integration/setup.sh, 109 lines
- sgl-model-gateway/scripts/setup-sccache.sh, 85 lines, uses sudo, edits your shell profile
Committed binaries (1)
python/sglang/kernels/ops/attention/dsv4/asm/gfx950/mla_v4/mla_a8w8_qh64_qseqlen1_gqaratio64_nm.co: ELF, 130 KB
Worst known vulnerabilities (24 of 49)
| Advisory | Severity | Package | Summary |
|---|---|---|---|
| GHSA-4684-h2q9-2vcp | critical | zip@0.6.6 | ZipStreamReader::extract() and ZipArchive::extract() apply Unix permissions through symlinks without confining the targe… |
| GHSA-p77j-4mvh-x3m3 | critical | google.golang.org/grpc@1.77.0 | gRPC-Go has an authorization bypass via missing leading slash in :path |
| GHSA-3g6h-r5qx-f6hq | high | quinn-proto@0.11.16 | Peer minimum ACK delay can panic quinn-proto when ACK_FREQUENCY transmission is enabled |
| GHSA-qfwj-vfxf-92j2 | high | quinn-proto@0.11.16 | Stream reassembly memory-exhaustion guard in quinn-proto can be bypassed |
| GHSA-vv5m-jxxh-4627 | high | zip@0.6.6 | Insecure Preservation of SUID/SGID Bits during ZIP Extraction Leading to Potential Privilege Escalation |
| GHSA-259r-337f-4rfw | high | github.com/klauspost/compress@1.17.9 | Compress/s2: Integer Overflow or Wraparound and Out-of-bounds Write in compress |
| GHSA-2v4p-qf9q-27wj | high | google.golang.org/grpc@1.77.0 | gRPC-Go xDS servers: Denial of Service (DoS) via crash due to missing `:authority` and `Host` headers |
| GHSA-hrxh-6v49-42gf | high | google.golang.org/grpc@1.77.0 | gRPC-Go: xDS RBAC and HTTP/2 Vulnerabilities |
| GHSA-vp52-pcj8-j9qc | high | google.golang.org/grpc@1.77.0 | gRPC-Go: Heap Memory Exhaustion (OOM) via HTTP/2 DATA Frame Fragmentation |
| GHSA-3g6h-r5qx-f6hq | high | quinn-proto@0.11.17 | Peer minimum ACK delay can panic quinn-proto when ACK_FREQUENCY transmission is enabled |
| GHSA-ppcp-v39w-8jq2 | high | quinn-proto@0.11.17 | Outgoing datagram buffer accounting can panic the sender in quinn-proto |
| GHSA-2mjx-qc3c-rqvc | moderate | rustls@0.23.43 | Rustls: TLS 1.3 handshake messages incorrectly accepted across encryption level boundaries |
| GHSA-c8m5-c952-6cm4 | moderate | rustls@0.23.43 | `Debug` impls for client session values expose TLS secrets |
| GHSA-5cv4-jp36-h3mw | moderate | golang.org/x/net@0.46.1-0.20251013234738-63d1a5100f82 | Go Net HTML parser is vulnerable to denial of service |
| GHSA-qc2q-p7wx-3px3 | moderate | google.golang.org/grpc@1.77.0 | gRPC-Go: xDS RBAC HTTP Filter bypass via mixed-case Header Matching and gRFC A41 validation evasion |
| GHSA-6w46-j5rx-g56g | moderate | pytest@8.3.3 | pytest has vulnerable tmpdir handling |
| GHSA-h2v8-394m-p7vv | low | rustls@0.23.43 | Brotli certificate decompression can allocate up to 1 GiB before authentication |
| GHSA-w44r-93j7-qv28 | low | rustls@0.23.43 | Unauthenticated ServerHello can downgrade later connections to classical key exchange |
| GHSA-q83h-524g-xf6h | unknown | h2@0.4.15 | h2 unbounded empty DATA frames |
| RUSTSEC-2025-0119 | unknown | number_prefix@0.4.0 | number_prefix crate is unmaintained |
| RUSTSEC-2024-0436 | unknown | paste@1.0.15 | paste - no longer maintained |
| GHSA-465w-v9q3-7j98 | unknown | quinn-proto@0.11.16 | Remote peer can panic quinn-proto with zero-length STREAM frames during unordered reads |
| GHSA-hmxj-32vh-65vr | unknown | quinn-proto@0.11.16 | Unbounded growth of pending connection ID retirements in quinn-proto |
| GHSA-2hv7-gw8g-gpq5 | unknown | quinn-proto@0.11.16 | Zero-length DATAGRAM frames bypass the receive buffer limit in quinn-proto |
Workflows worth a look
- .github/workflows/cancel-pr-workflows-on-close.yml: pull_request_target
- .github/workflows/labeler.yml: pull_request_target
- .github/workflows/pr-check-comment.yml: pull_request_target
- .github/workflows/pr-gate.yml: pull_request_target
- .github/workflows/pr-states.yml: pull_request_target
- .github/workflows/pr-test-extra.yml: pull_request_target
- .github/workflows/pr-test-mlu.yml: pull_request_target
- .github/workflows/pr-test.yml: pull_request_target
- .github/workflows/pr-title.yml: pull_request_target
By the numbers
| Stars | 38.2K |
|---|---|
| Forks | 9,898 |
| Contributors | 2,132 |
| Commits | 21K |
| Open issues | 966 |
| Open pull requests | 5,231 |
| Releases | 63 |
| Latest release | v0.5.22 |
| Licence | Apache-2.0 |
| Main language | Python |
| Project age | 2 years |
| Last push | Oct 26, 2026 |
| Tracked files | 11,385 |
| Lines of code | 3.6M |
| Checkout size | 154 MB |
Lines by language: Python 2.7M, Rust 306.4K, Markdown 179.9K, JSON 137K, JavaScript 118.1K, YAML 34.2K.
Questions
Is SGLang free?
Yes. SGLang is Apache-2.0, free for any use including commercial serving, with no paid edition. Your costs are the hardware or rented GPUs. Models are separate downloads, each under its own licence.
SGLang or vLLM?
Both are fast, open-source servers with OpenAI-compatible APIs and overlapping features, and the lead on benchmarks changes from release to release. SGLang's RadixAttention prefix cache helps most when many requests share long prompts, as in agents and multi-turn chat. Test both with your own model and traffic; switching is mostly a change of launch command.
What hardware does SGLang need?
Realistically Linux and a GPU: NVIDIA first, with AMD Instinct, Intel GPUs, Google TPUs and Huawei Ascend also supported, plus Xeon CPUs and Apple Silicon. Plan GPU memory for the full weights plus cache; an 8B model in 16-bit precision needs about 16 GB for its weights alone.
This post is part of GitHub Tools, where every repository is cloned and scanned before it is written up. The scan is a snapshot of one commit on one day; the repository has moved on since, so check it before you install.
