vLLM is what you run when a model has to serve more than one person. It loads open models from Hugging Face onto one GPU or many and serves them through an OpenAI-compatible API, plus Anthropic's Messages format and gRPC, getting far more requests per second out of the same card than a desktop runner does. The idea that started it, PagedAttention, manages the attention cache in pages the way an operating system manages memory; continuous batching, prefix caching, speculative decoding and a long list of quantization formats came after.
It began in UC Berkeley's Sky Computing Lab in 2023 and is now one of the largest open-source AI projects on GitHub: over 3,500 contributors, 22,000 commits and 106 releases, the latest 0.30.0. It is Apache-2.0, supports more than 200 model architectures, and runs on NVIDIA, AMD and Intel GPUs and x86, ARM and PowerPC CPUs, with plugins for TPUs, Gaudi, Ascend and Apple Silicon. It is also what the other tools on this list reach for when a single-user runner is not enough: LocalAI ships it as a backend.
- Repository: github.com/vllm-project/vllm
- Licence: Apache-2.0 (Apache License 2.0)
- Language: Python. Stars: 92.7K. Forks: 22.7K. Last push: Sep 27, 2026.
- Scan: safe, Sep 27, 2026, commit a9eafde
Who it is for
Teams serving a model to an application or many users, anyone with a data-center or large NVIDIA or AMD GPU who needs throughput, and developers who want a self-hosted OpenAI-compatible endpoint that holds up under load.
Getting started
1. Create an environment and install with uv (Linux, Python 3.10 to 3.13; pip install vllm also works)
uv venv --python 3.12 --seed && source .venv/bin/activate && uv pip install vllm --torch-backend=auto2. Download a model from Hugging Face and serve it on localhost:8000
vllm serve Qwen/Qwen2.5-1.5B-Instruct3. Query it like the OpenAI API
curl http://localhost:8000/v1/chat/completions -H "Content-Type: application/json" -d '{"model":"Qwen/Qwen2.5-1.5B-Instruct","messages":[{"role":"user","content":"Who won the world series in 2020?"}]}'The server accepts requests from anyone who can reach it unless you pass --api-key (or set VLLM_API_KEY). Set one before binding it to anything but localhost.
Safety scan
We cloned vllm-project/vllm at commit a9eafde on Sep 27, 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 secrets, no self-decoding code, no committed binaries and no bare-IP URLs across 2.2 million lines, most of them Python with CUDA, C++ and a new Rust front end.
- Four pattern hits, none in what you install. Three are build scripts fetching toolchains with curl | sh (uv in the main Dockerfile, rustup in the PowerPC build script and tools/build_rust.sh); the fourth is a kernel benchmark redirecting stderr to /dev/null, which the scanner mistook for a socket trick.
- setup.py has a custom build command, which is how a CUDA project compiles its kernels. With VLLM_USE_PRECOMPILED set it downloads prebuilt kernels from vLLM's own wheels.vllm.ai and asks api.github.com for the latest main commit; a normal pip or uv install gets a finished wheel and runs none of it. The 36 installer scripts are CI jobs (28 under .buildkite) and optional kernel installers under tools/, and none uses sudo or pipes to a shell.
- The only lockfile is rust/Cargo.lock: 26 advisories, none critical, two high (an out-of-bounds read in PyO3's list iterators and a denial of service in rustls-webpki's revocation-list parsing), the rest mostly unmaintained-crate notices. The Python dependencies are version ranges in requirements files with no lockfile, so the advisory check had nothing to read there.
- 12 workflows. Three use pull_request_target (bots for automerge labels, new pull requests and CI notifications) and none checks out the pull request; all 7 third-party actions are pinned to a commit. Dependabot, security policy, contributing guide and code of conduct present.
What the scanner counted
| Check | Result |
|---|---|
| Secrets | None found. |
| Suspicious code | 4 pattern hits found and read; every one is listed under the raw findings. |
| Install-time code | 1 setup.py with custom install logic. 1 Cargo build script. 36 installer scripts |
| Committed binaries | None. |
| CI workflows | 12 workflows. 3 use pull_request_target, none check out the pull request head. 0 of 7 third-party actions pinned to a tag rather than a commit. |
| Network hosts | 40 distinct hosts referenced from source; most often github.com, huggingface.co, www.apache.org, arxiv.org. No URLs to bare IP addresses. |
| Known vulnerabilities | 26 advisories across 637 pinned packages: 0 critical, 2 high, 4 moderate, 4 low, 16 unrated. rust/Cargo.lock: 637 packages, 26 advisories. |
| Project hygiene | Has security policy, automated dependency updates, licence file, contributing guide. Missing CodeQL. |
| 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.
Pattern hits (4)
| Where | Rule | Match |
|---|---|---|
| benchmarks/kernels/ir/bench_ir_ops.py:36 | raw-socket-shell (test/example) | os.dup2(_devnull.fileno(), 2) |
| docker/Dockerfile:164 | download-piped-to-shell | && curl -LsSf https://astral.sh/uv/install.sh | sh \ |
| docker/build_vllm_ppc64le.sh:101 | download-piped-to-shell | curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y |
| tools/build_rust.sh:18 | download-piped-to-shell | curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain none |
Installer scripts (36)
- .buildkite/amd-disagg/run-slurm-disagg-test.sh, 339 lines
- .buildkite/lm-eval-harness/run-lm-eval-chartqa-vllm-vlm-baseline.sh, 45 lines
- .buildkite/lm-eval-harness/run-lm-eval-gsm-hf-baseline.sh, 47 lines
- .buildkite/lm-eval-harness/run-lm-eval-gsm-vllm-baseline.sh, 52 lines
- .buildkite/lm-eval-harness/run-lm-eval-mmlupro-vllm-baseline.sh, 48 lines
- .buildkite/performance-benchmarks/scripts/run-performance-benchmarks.sh, 897 lines; talks to github.com, huggingface.co
- .buildkite/scripts/hardware_ci/run-amd-test.sh, 1,817 lines; talks to github.com, huggingface.co
- .buildkite/scripts/hardware_ci/run-cpu-compatibility-test.sh, 67 lines; talks to downloadmirror.intel.com
- .buildkite/scripts/hardware_ci/run-cpu-distributed-smoke-test.sh, 40 lines
- .buildkite/scripts/hardware_ci/run-cpu-test-arm.sh, 121 lines
- .buildkite/scripts/hardware_ci/run-cpu-test-ppc64le.sh, 55 lines
- .buildkite/scripts/hardware_ci/run-cpu-test-s390x.sh, 14 lines
- .buildkite/scripts/hardware_ci/run-cpu-test.sh, 117 lines
- .buildkite/scripts/hardware_ci/run-gh200-test.sh, 30 lines
- .buildkite/scripts/hardware_ci/run-hpu-test.sh, 89 lines; talks to github.com, raw.githubusercontent.com
- .buildkite/scripts/hardware_ci/run-intel-ci-test.sh, 77 lines
- .buildkite/scripts/hardware_ci/run-intel-test.sh, 386 lines
- .buildkite/scripts/hardware_ci/run-npu-test.sh, 163 lines; talks to cache-service-vllm.nginx-pypi-cache.svc.cluster.local, gh-proxy.test.osinfra.cn, github.com
- .buildkite/scripts/hardware_ci/run-tpu-v1-test-part2.sh, 167 lines; talks to github.com
- .buildkite/scripts/hardware_ci/run-tpu-v1-test.sh, 173 lines; talks to github.com
- .buildkite/scripts/hardware_ci/run-xpu-batch-invariance.sh, 244 lines
- .buildkite/scripts/install-kv-connectors.sh, 72 lines
- .buildkite/scripts/install-kv-offload.sh, 19 lines; talks to github.com
- .buildkite/scripts/run-benchmarks.sh, 81 lines; talks to huggingface.co
- .buildkite/scripts/run-multi-node-test.sh, 152 lines
- .buildkite/scripts/run-rust-frontend-cargo-ci.sh, 170 lines; talks to github.com, raw.githubusercontent.com, sh.rustup.rs
- .buildkite/scripts/tool_call/run-bfcl-eval.sh, 254 lines; talks to huggingface.co
- .buildkite/scripts/tpu/run_bm.sh, 94 lines
- tools/ep_kernels/elastic_ep/install_eep_libraries.sh, 80 lines; talks to developer.download.nvidia.com, github.com
- tools/ep_kernels/install_python_libraries.sh, 239 lines; talks to developer.download.nvidia.com, github.com
- tools/install_deepgemm.sh, 129 lines; talks to github.com
- tools/install_gdrcopy.sh, 55 lines; talks to developer.download.nvidia.com
- tools/install_snapshot_runtime.sh, 110 lines; talks to github.com, raw.githubusercontent.com
- tools/install_torchcodec_rocm.sh, 142 lines; talks to github.com
- tools/install_triton_from_source.sh, 42 lines
- tools/setup_deepgemm_pythons.sh, 38 lines
Worst known vulnerabilities (24 of 26)
| Advisory | Severity | Package | Summary |
|---|---|---|---|
| GHSA-36hh-v3qg-5jq4 | high | pyo3@0.28.3 | PyO3 has an Out-of-bounds Read in `nth` / `nth_back` for `PyList` and `PyTuple` iterators |
| GHSA-82j2-j2ch-gfr8 | high | rustls-webpki@0.103.9 | rustls-webpki: Denial of service via panic on malformed CRL BIT STRING |
| GHSA-chgr-c6px-7xpp | moderate | pyo3@0.28.3 | PyO3 has a missing `Sync` bound on `PyCFunction::new_closure` closures |
| GHSA-2mjx-qc3c-rqvc | moderate | rustls@0.23.37 | TLS 1.3 handshake messages incorrectly accepted across encryption level boundaries |
| GHSA-pwjx-qhcg-rvj4 | moderate | rustls-webpki@0.103.9 | webpki: CRLs not considered authoritative by Distribution Point due to faulty matching logic |
| GHSA-7gcf-g7xr-8hxj | moderate | serde_with@3.18.0 | serde_with: KeyValueMap serialization panics on empty sequence or map entries |
| GHSA-cq8v-f236-94qc | low | rand@0.8.5 | Rand is unsound with a custom logger using rand::rng() |
| GHSA-cq8v-f236-94qc | low | rand@0.9.2 | Rand is unsound with a custom logger using rand::rng() |
| GHSA-965h-392x-2mh5 | low | rustls-webpki@0.103.9 | webpki: Name constraints for URI names were incorrectly accepted |
| GHSA-xgp8-3hg3-c2mh | low | rustls-webpki@0.103.9 | webpki: Name constraints were accepted for certificates asserting a wildcard name |
| RUSTSEC-2026-0190 | unknown | anyhow@1.0.102 | Unsoundness in `Error::downcast_mut()` |
| RUSTSEC-2025-0012 | unknown | backoff@0.4.0 | `backoff` is unmaintained. |
| RUSTSEC-2026-0204 | unknown | crossbeam-epoch@0.9.18 | Invalid pointer dereference in `fmt::Pointer` impl for `Atomic` and `Shared` when the underlying pointer is invalid |
| GHSA-q83h-524g-xf6h | unknown | h2@0.4.15 | h2 unbounded empty DATA frames |
| RUSTSEC-2024-0384 | unknown | instant@0.1.13 | `instant` is unmaintained |
| RUSTSEC-2024-0436 | unknown | paste@1.0.15 | paste - no longer maintained |
| RUSTSEC-2026-0173 | unknown | proc-macro-error2@2.0.1 | proc-macro-error2 is unmaintained |
| RUSTSEC-2026-0205 | unknown | scc@2.4.0 | `Array::insert` violates exception safety if compare function panics, leading to potential Double-Free |
| RUSTSEC-2026-0205 | unknown | scc@3.6.9 | `Array::insert` violates exception safety if compare function panics, leading to potential Double-Free |
| RUSTSEC-2026-0249 | unknown | smartstring@1.0.1 | smartstring is unmaintained |
| RUSTSEC-2025-0081 | unknown | unic-char-property@0.9.0 | `unic-char-property` is unmaintained |
| RUSTSEC-2025-0075 | unknown | unic-char-range@0.9.0 | `unic-char-range` is unmaintained |
| RUSTSEC-2025-0080 | unknown | unic-common@0.9.0 | `unic-common` is unmaintained |
| RUSTSEC-2025-0090 | unknown | unic-emoji-char@0.9.0 | `unic-emoji-char` is unmaintained |
Workflows worth a look
- .github/workflows/add_label_automerge.yml: pull_request_target
- .github/workflows/new_pr_bot.yml: pull_request_target
- .github/workflows/notify-ci-authorized.yml: pull_request_target
By the numbers
| Stars | 92.7K |
|---|---|
| Forks | 22.7K |
| Contributors | 3,557 |
| Commits | 22K |
| Open issues | 2,515 |
| Open pull requests | 5,806 |
| Releases | 106 |
| Latest release | v0.30.0 |
| Licence | Apache-2.0 |
| Main language | Python |
| Project age | 3 years |
| Last push | Sep 27, 2026 |
| Tracked files | 7,392 |
| Lines of code | 2.2M |
| Checkout size | 120 MB |
Lines by language: Python 1.7M, JSON 161.1K, Rust 126.3K, CUDA 55K, Markdown 49K, C/C++ header 33.3K.
Questions
Is vLLM free?
Yes. vLLM is Apache-2.0, free for any use including commercial serving, and there is no paid edition of the software. Your costs are the hardware, or the rented cloud GPUs, it runs on. Models are separate downloads from Hugging Face, each under its own licence, and some families such as Llama and Gemma carry use conditions of their own.
vLLM or Ollama?
Ollama is built for one person on one machine: a simple install, quantized GGUF models, and it runs on a laptop. vLLM is built for throughput: many concurrent requests batched on a GPU, full-precision or FP8 models, and parallelism across several GPUs. If you are chatting with a model yourself, use Ollama. If an application or a team sends it traffic, vLLM serves far more requests from the same card.
What hardware does vLLM need?
Linux and a GPU, realistically. It targets NVIDIA cards first, also supports AMD ROCm, Intel GPUs and x86, ARM and PowerPC CPUs, and reaches TPUs, Gaudi and Ascend through plugins. On a Mac it runs through the separate vLLM-Metal project. Plan GPU memory for full weights plus cache: a 7B model in 16-bit precision needs about 15 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.
