Connect Open WebUI to llama.cpp: Step-by-Step Setup Guide
Step-by-step guide to connect Open WebUI to llama.cpp for local AI inference. Covers server setup, configuration, Docker Compose, and troubleshooting.
- Start a llama.cpp server with a downloaded GGUF model, then point Open WebUI to its OpenAI-compatible endpoint at http://localhost:8000/v1.
- Llama.cpp runs one model at a time, delivering 5-7% higher throughput than Ollama on identical hardware (Gemma: 100 t/s vs 93 t/s).
- Use Docker Compose for production deployments with auto-restart and easy maintenance.
- Troubleshoot connection issues by testing llama.cpp directly with curl before blaming Open WebUI.
Open WebUI paired with a local llama.cpp server gives you complete control over your models and data without cloud dependencies. This setup runs 5-7% faster than Ollama because llama.cpp compiles to your CPU architecture, and you get a professional web interface without managed overhead.
Why Run llama.cpp Behind Open WebUI?
You choose llama.cpp when you want speed and control. llama.cpp is not a user interface -- it's an inference engine. Open WebUI is not an engine -- it's a web interface. Together they solve each other's problems.
Llama.cpp runs models through its OpenAI-compatible API server, delivering faster token throughput per dollar of hardware. On identical hardware, llama.cpp produces 100 tokens per second with Gemma models while Ollama maxes out at 93 t/s. For Qwen models, you get 69 t/s versus Ollama's 65 t/s. The gap matters when you're running inference all day. Open WebUI wraps this speed in a sleek chat interface with knowledge base support, code execution, and voice chat -- features that llama.cpp's raw API does not provide.
You also get data sovereignty. Your prompts and model outputs never leave your machine. Open WebUI runs locally, llama.cpp runs locally, and only you can access them. This setup costs nothing per query. Managed Open WebUI instances exist, but when you need control and cost predictability, this DIY path wins.
The trade-off: you must manage the infrastructure. You handle model downloads, GPU memory allocation, port conflicts, and version updates. If you prefer someone else managing those headaches, Opsily offers hosted Open WebUI with pre-configured backends.
What You Need: Prerequisites
You need three things: hardware, software, and patience.
Hardware: At minimum, 8 GB RAM and a modern CPU (last 5 years). If you have an NVIDIA GPU with at least 4 GB VRAM, add the CUDA runtime -- models run 5-10x faster. Raspberries Pi and older processors work but will frustrate you with 1-3 tokens per second. Expect a 7B parameter model to consume 7-8 GB of system memory at Q4 quantization.
Software: Install these first.
- Git (for cloning repositories)
- Python 3.10 or higher
- Docker and Docker Compose (optional but recommended for Open WebUI)
- CUDA Toolkit 12.2+ if you have an NVIDIA GPU (optional)
Familiarity: You should know how to open a terminal and run commands. You do not need to understand LLM internals, but basic Linux comfort helps when troubleshooting networking or permissions.
Step 1: Start the llama.cpp Server
First, you run the inference engine. This is where models actually execute.
Clone the llama.cpp repository and build the server.
git clone https://github.com/ggml-org/llama.cpp.git
cd llama.cpp
make
This compiles llama.cpp to your specific CPU. Build time varies from 30 seconds to 5 minutes depending on your machine.
Next, download a GGUF model. GGUF is the quantized format that llama.cpp understands. Mistral 7B is a safe starting point because it runs on any 8GB+ machine and performs well across tasks. Download it from Hugging Face:
wget https://huggingface.co/TheBloke/Mistral-7B-Instruct-v0.1-GGUF/resolve/main/Mistral-7B-Instruct-v0.1.Q4_K_M.gguf
This file is 5.2 GB. Expect 5-15 minutes depending on your connection. Q4_K_M means 4-bit quantization with medium accuracy -- a solid middle ground. If your RAM is tight, use Q3_K_S (3.5 GB). If you want better quality and have the VRAM, use Q5_K_M (6.8 GB).
Now start the server.
./llama-server -m./Mistral-7B-Instruct-v0.1.Q4_K_M.gguf -c 2048 -ngl 33 -e
Break down the flags: -m specifies the model file. -c 2048 sets context length to 2,048 tokens (what you can fit in one conversation). -ngl 33 offloads 33 layers to GPU if available (speeds up inference dramatically if you have VRAM). -e enables embeddings mode for knowledge bases. If you get a "not enough VRAM" error, drop ngl to 20 or 10. If you have no GPU, omit -ngl entirely.
You should see output like:
llama_model_load_internal: model size = 3819.38 MB
main: load time = 1234.56 ms
attention cache size: 0 bytes
server: listening on http://127.0.0.1:8000
The server is now live at http://localhost:8000. You can test it directly:
curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "Mistral-7B-Instruct-v0.1.Q4_K_M",
"messages": [{"role": "user", "content": "What is 2+2?"}],
"temperature": 0.7
}'
If you get a JSON response with a completion, the server is working. Leave this terminal running. This is the backend.
Step 2: Configure Open WebUI to Connect
Now open a new terminal and start Open WebUI. You can run it standalone or in Docker. Docker is cleaner and recommended.
docker run -d -p 3000:8080 \
-e OPENAI_API_BASE_URL=http://host.docker.internal:8000/v1 \
-e OPENAI_API_KEY=not-needed \
--name open-webui \
ghcr.io/open-webui/open-webui:latest
If you are on Linux, use host.docker.internal only if your Docker daemon is on the host. Otherwise use the host's actual IP address (e.g., 192.168.1.100 instead). If you are running Open WebUI on the same machine as llama.cpp without Docker, set the base URL to http://localhost:8000/v1.
Open WebUI now launches at http://localhost:3000. Wait 10-15 seconds for startup.
Once the interface loads, navigate to Settings > Connections. Under "OpenAI API", set:
- Base URL:
http://localhost:8000/v1(or your actual host IP) - API Key: Type anything here. llama.cpp does not validate keys. You can put
dummy-keyornot-needed. - Model: Leave blank for now. Open WebUI will auto-discover models.
Click Save. The interface will ping the llama.cpp server and attempt to load the model list.
Step 3: Verify and Load Your First Model
Refresh the page. Go to the chat interface and look at the model dropdown at the top of the conversation.
You should see your Mistral model listed by filename. Click it to select it. If you see nothing or an error message, llama.cpp is not responding. Check:
- Is the llama.cpp server still running? (Check the terminal where you started it.)
- Is the URL correct? (Typos in Base URL break everything.)
- Are you behind a firewall blocking localhost:8000? (Run
curl http://localhost:8000/v1/modelsto test.)
Assuming the model appears, send your first prompt: "Hello, what is your name?" Hit Enter and watch the tokens appear. If text streams in, you have succeeded. If you see an error like "connection refused", llama.cpp crashed or the URL is wrong. Check the llama.cpp terminal for error messages.
Understanding the Single-Model Limitation
You have now hit the main gotcha: llama.cpp runs one model at a time. Unlike Ollama, which caches multiple models in memory and switches between them, llama.cpp loads one model on startup and serves only that model. You cannot switch from Mistral to Llama-2 mid-conversation without stopping the server, changing the -m flag, and restarting.
This is not a bug. It is by design. Running multiple models simultaneously requires more memory and GPU coordination than most users have.
Three workarounds exist:
-
Run multiple llama.cpp servers on different ports (
:8000,:8001,:8002) with different models, then add each as a separate connection in Open WebUI. This works if you have 32+ GB RAM. -
Use llama-swap, a third-party proxy that automates the server restart process. You add multiple models to llama-swap's config, and it reloads the model on demand before each request. Latency increases by 3-8 seconds per model switch, but it works for small teams.
-
Accept the limitation. Use the fastest quantization of one model (Q4_K_M) for your workload and just leave it running.
For most single-operator setups, option 3 wins on simplicity.
Docker Compose: The Recommended Setup
Managing two terminals is fine for testing. For 24/7 operation, use Docker Compose to orchestrate both services.
Create a file called docker-compose.yml:
version: "3.8"
services:
llama-server:
image: ghcr.io/ggml-org/llama.cpp:full
command: -m /models/Mistral-7B-Instruct-v0.1.Q4_K_M.gguf -c 2048 -ngl 33 -e
ports:
- "8000:8000"
volumes:
-./models:/models
environment:
- LLAMA_CUDA=1
restart: always
open-webui:
image: ghcr.io/open-webui/open-webui:latest
ports:
- "3000:8080"
environment:
- OPENAI_API_BASE_URL=http://llama-server:8000/v1
- OPENAI_API_KEY=not-needed
depends_on:
- llama-server
restart: always
Before running this, download your model into a models/ folder in the same directory as the compose file. Then:
docker-compose up -d
Both services start in the background. View logs with docker-compose logs -f. The stack will restart automatically if either service crashes.
To stop: docker-compose down.
To update: Pull the latest images with docker-compose pull then restart with up -d.
Troubleshooting Common Issues
"Connection refused" in Open WebUI
The Base URL is wrong or llama.cpp is not running. First, test llama.cpp directly:
curl http://localhost:8000/v1/models
If this returns a list of models as JSON, llama.cpp is fine. The problem is in Open WebUI's URL. Check for typos. If you are using Docker, make sure you use http://host.docker.internal:8000/v1 (macOS/Windows) or the host's IP (Linux).
If curl fails, llama.cpp crashed or never started. Restart it and watch for error messages.
Model list is empty
This usually means llama.cpp loaded successfully but Open WebUI cannot read its model list. Check that the API Key field is filled in Open WebUI's Connections settings, even if it is just dummy. Also verify the model file exists and is readable by the llama.cpp process (check file permissions if running outside Docker).
"Out of memory" error
Your model does not fit in RAM. Try a smaller quantization (Q3_K_S instead of Q4_K_M) or a smaller model (Phi-2 7B instead of Mistral 7B). If you have a GPU, ensure CUDA is installed and increase -ngl to offload more layers.
**Tokens appear very slowly (1-2 per second)
You are not using GPU acceleration. Install CUDA if you have an NVIDIA GPU, or use a smaller model. CPU-only inference on consumer hardware is always slow. This is expected.
Port 8000 or 3000 already in use
Something else is listening on that port. Either kill the other process or change the port in the command. For llama.cpp, add -ngl 8000:8001 instead of :8000. For Open WebUI, change -p 3000:8080 to -p 3001:8080.
Frequently Asked Questions
Can I use llama.cpp with Open WebUI for production?
Yes, if "production" means stable long-running service for a small team or internal use. Use Docker Compose as shown above and enable monitoring/auto-restart. For public-facing SaaS, managed hosting like Opsily's Open WebUI offering removes infrastructure management entirely.
How many concurrent users can one llama.cpp server handle?
One at a time. llama.cpp processes requests serially. If two users send prompts simultaneously, the second waits for the first to complete. For teams, run multiple llama.cpp instances behind a load balancer or use a managed service.
Do I need a GPU for this setup?
No. llama.cpp works on CPU alone. With a GPU (NVIDIA 8GB+ VRAM), you get 10x faster inference. Without, expect 2-5 tokens per second on a modern quad-core CPU.
What quantization level should I use?
Start with Q4_K_M (good quality, reasonable file size). If you run out of memory, drop to Q3_K_S. If quality matters more than speed, try Q5_K_M or Q6_K. Anything below Q3 introduces visible artifacts.
Can I switch models without restarting the server?
Not without third-party tools like llama-swap. Raw llama.cpp loads one model at startup and sticks with it. This is by design to minimize memory churn.
Is llama.cpp faster than Ollama?
Yes, marginally. Expect 5-7% higher throughput due to tighter compilation. For most use cases the difference is invisible. Ollama is easier to set up; llama.cpp is faster and more configurable.
What models work with llama.cpp?
Any model with a GGUF version on Hugging Face. This includes Mistral, Llama-2, Qwen, Phi, Gemma, and TinyLlama. Search "model-name GGUF" on Hugging Face to find quantized versions.
The Bottom Line
Llama.cpp behind Open WebUI is the fastest way to run local models with a professional interface. Setup takes 30 minutes. The trade-off is you manage everything yourself: model downloads, GPU config, port conflicts, version updates.
If DIY infrastructure sounds exhausting, managed Open WebUI hosting like Opsily handles the backend while you focus on prompts. Link up to our hosting page to skip the setup entirely and get started in minutes.