6 min read

vLLM: Fast LLM Serving on Your Own GPUs (GitHub, Scanned)

A high-throughput inference server for open models, with an OpenAI-compatible API.

vLLM logo
✅
Scan: safe. Nothing to warn about. The pattern hits are build scripts fetching compilers, and the one lockfile, for the new Rust front end, has no critical advisories; the Python dependencies are ranges the check could not read. Scanned Sep 27, 2026; the full report is below.

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=auto

2. Download a model from Hugging Face and serve it on localhost:8000

vllm serve Qwen/Qwen2.5-1.5B-Instruct

3. 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

CheckResult
SecretsNone found.
Suspicious code4 pattern hits found and read; every one is listed under the raw findings.
Install-time code1 setup.py with custom install logic. 1 Cargo build script. 36 installer scripts
Committed binariesNone.
CI workflows12 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 hosts40 distinct hosts referenced from source; most often github.com, huggingface.co, www.apache.org, arxiv.org. No URLs to bare IP addresses.
Known vulnerabilities26 advisories across 637 pinned packages: 0 critical, 2 high, 4 moderate, 4 low, 16 unrated. rust/Cargo.lock: 637 packages, 26 advisories.
Project hygieneHas security policy, automated dependency updates, licence file, contributing guide. Missing CodeQL.
OpenSSF ScorecardNot 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)
WhereRuleMatch
benchmarks/kernels/ir/bench_ir_ops.py:36raw-socket-shell (test/example)os.dup2(_devnull.fileno(), 2)
docker/Dockerfile:164download-piped-to-shell&& curl -LsSf https://astral.sh/uv/install.sh | sh \
docker/build_vllm_ppc64le.sh:101download-piped-to-shellcurl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
tools/build_rust.sh:18download-piped-to-shellcurl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain none
Installer scripts (36)
Worst known vulnerabilities (24 of 26)
AdvisorySeverityPackageSummary
GHSA-36hh-v3qg-5jq4highpyo3@0.28.3PyO3 has an Out-of-bounds Read in `nth` / `nth_back` for `PyList` and `PyTuple` iterators
GHSA-82j2-j2ch-gfr8highrustls-webpki@0.103.9rustls-webpki: Denial of service via panic on malformed CRL BIT STRING
GHSA-chgr-c6px-7xppmoderatepyo3@0.28.3PyO3 has a missing `Sync` bound on `PyCFunction::new_closure` closures
GHSA-2mjx-qc3c-rqvcmoderaterustls@0.23.37TLS 1.3 handshake messages incorrectly accepted across encryption level boundaries
GHSA-pwjx-qhcg-rvj4moderaterustls-webpki@0.103.9webpki: CRLs not considered authoritative by Distribution Point due to faulty matching logic
GHSA-7gcf-g7xr-8hxjmoderateserde_with@3.18.0serde_with: KeyValueMap serialization panics on empty sequence or map entries
GHSA-cq8v-f236-94qclowrand@0.8.5Rand is unsound with a custom logger using rand::rng()
GHSA-cq8v-f236-94qclowrand@0.9.2Rand is unsound with a custom logger using rand::rng()
GHSA-965h-392x-2mh5lowrustls-webpki@0.103.9webpki: Name constraints for URI names were incorrectly accepted
GHSA-xgp8-3hg3-c2mhlowrustls-webpki@0.103.9webpki: Name constraints were accepted for certificates asserting a wildcard name
RUSTSEC-2026-0190unknownanyhow@1.0.102Unsoundness in `Error::downcast_mut()`
RUSTSEC-2025-0012unknownbackoff@0.4.0`backoff` is unmaintained.
RUSTSEC-2026-0204unknowncrossbeam-epoch@0.9.18Invalid pointer dereference in `fmt::Pointer` impl for `Atomic` and `Shared` when the underlying pointer is invalid
GHSA-q83h-524g-xf6hunknownh2@0.4.15h2 unbounded empty DATA frames
RUSTSEC-2024-0384unknowninstant@0.1.13`instant` is unmaintained
RUSTSEC-2024-0436unknownpaste@1.0.15paste - no longer maintained
RUSTSEC-2026-0173unknownproc-macro-error2@2.0.1proc-macro-error2 is unmaintained
RUSTSEC-2026-0205unknownscc@2.4.0`Array::insert` violates exception safety if compare function panics, leading to potential Double-Free
RUSTSEC-2026-0205unknownscc@3.6.9`Array::insert` violates exception safety if compare function panics, leading to potential Double-Free
RUSTSEC-2026-0249unknownsmartstring@1.0.1smartstring is unmaintained
RUSTSEC-2025-0081unknownunic-char-property@0.9.0`unic-char-property` is unmaintained
RUSTSEC-2025-0075unknownunic-char-range@0.9.0`unic-char-range` is unmaintained
RUSTSEC-2025-0080unknownunic-common@0.9.0`unic-common` is unmaintained
RUSTSEC-2025-0090unknownunic-emoji-char@0.9.0`unic-emoji-char` is unmaintained
Workflows worth a look

By the numbers

Stars92.7K
Forks22.7K
Contributors3,557
Commits22K
Open issues2,515
Open pull requests5,806
Releases106
Latest releasev0.30.0
LicenceApache-2.0
Main languagePython
Project age3 years
Last pushSep 27, 2026
Tracked files7,392
Lines of code2.2M
Checkout size120 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.