# LM Studio vs Ollama: Which Local LLM App to Choose

> LM Studio vs Ollama: licenses, MLX on Mac, OpenAI and Anthropic APIs, Claude Code and Codex, headless mode, an M4 Max benchmark, and which to pick.
> Author: Roman Belov · Published: 2026-10-19 · Source: https://futurecraft.pro/blog/lm-studio-vs-ollama/

LM Studio is a desktop app with a graphical interface for running language models on your own computer. It finds and downloads models from Hugging Face, runs them on llama.cpp (GGUF) and MLX (Apple Silicon), serves an OpenAI-compatible and Anthropic-compatible API on port 1234, and has a CLI called `lms`. The app is closed source but free, including for work, and the CLI and SDKs are MIT-licensed. Ollama is an open-source MIT program whose main interface is a CLI, with a server on port 11434.

As of October 19, 2026, the current versions are LM Studio 0.4.26 from October 13 and Ollama v0.40.7 from October 18. At the level of "download a model and start a local API," they do the same job. So other things decide: the license, whether you need a GUI, how the program runs on a server with no screen, and how coding agents connect to it. The old argument "only LM Studio has MLX on Mac" is out of date: since version 0.40.0, Ollama runs supported models on MLX by itself.

This article compares LM Studio and Ollama on license, engines, API, headless mode, MCP and support for Claude Code, Codex and OpenCode, and says which one fits which task. The [Ollama guide](https://futurecraft.pro/blog/ollama-guide/) covers installing Ollama, the Modelfile and its settings, so this article doesn't repeat them. Speed and memory come from a benchmark of one model in four "app × format" combinations on a Mac with an Apple M4 Max.

## LM Studio vs Ollama: the short answer

- You want a GUI with a model catalog, chat and manual choice of quants: LM Studio.
- You want a background server for scripts, Docker, headless Linux or an open license: Ollama.
- Coding agents work with both, since both expose Anthropic `/v1/messages` and OpenAI `/v1/responses`. The model and the context matter more.
- On a Mac both have MLX, so "GGUF vs MLX" isn't the same question as which app to pick.

| Task | Pick | Why |
|---|---|---|
| First steps with local models on a Mac or Windows | LM Studio | Search, download, settings and chat in one window |
| Backend for your own code and scripts | Ollama | Background service, `/api` and `/v1`, Python and JavaScript libraries |
| Linux server, CI, Docker | Ollama | Official `ollama/ollama` image and a systemd service from the installer. LM Studio has the llmster daemon for this |
| An open license is mandatory | Ollama | MIT for the whole repository. LM Studio opens only the CLI, SDKs and mlx-engine |
| Claude Code, Codex, OpenCode | Either | Ollama sets them up with `ollama launch`; LM Studio needs manual setup per its docs |
| Comparing quants and formats of one model | LM Studio | GGUF and MLX from Hugging Face in one catalog, you pick the file by hand |
| MCP servers in a chat with a local model | LM Studio | The app works as an MCP host. With Ollama, MCP is set up on the client side |

## What LM Studio and Ollama are

### LM Studio

LM Studio runs on macOS 14 and later (Apple Silicon only, Intel Macs aren't supported), on Windows x64 and ARM, and on Linux x64 and ARM64, where it ships as an AppImage ([system requirements](https://lmstudio.ai/docs/app/system-requirements)). The docs recommend 16 GB of memory or more. The app has Hugging Face model search and download, a chat, model load settings (context, GPU layer offload) and a developer tab with the local server.

The `lms` CLI installs with the app, and the llmster daemon runs without a GUI. Version 0.4.26 from October 13, 2026 updated llama.cpp, added CUDA 13 on Windows ARM, and added the `/v1/decisions` and `/v1/systemone` endpoints ([changelog](https://lmstudio.ai/changelog/lmstudio)).

Bionic, from the same lmstudio.ai site, is a separate agent app for open models with its own changelog. It isn't part of this comparison.

### Ollama

Ollama is the [ollama/ollama](https://github.com/ollama/ollama) repository under the MIT license. The main interface is a CLI (`ollama pull`, `ollama run`, `ollama ps`), and by default the server listens on `127.0.0.1:11434`. On macOS and Windows there's an app with a chat window and settings. Models come from the ollama.com library or get imported from GGUF and safetensors through a Modelfile.

Releases come often: v0.40.0 shipped on September 25, 2026, and by October 18 it was already v0.40.7. Any version number in a comparison goes stale fast, so the date is the better reference.

## LM Studio vs Ollama comparison table

| | LM Studio 0.4.26 | Ollama v0.40.7 |
|---|---|---|
| License | Proprietary app, free for home and work. `lms`, SDKs, `mlx-engine` under MIT, no license stated for llmster | MIT, whole repository open |
| Interface | Full GUI: Hugging Face catalog, chat, load settings. Plus the `lms` CLI | CLI as the main interface, app with a simple chat for macOS and Windows |
| Platforms | macOS 14+ (Apple Silicon), Windows x64/ARM, Linux x64/ARM64 (AppImage) | macOS, Windows, Linux, Docker |
| Engines | llama.cpp (GGUF), MLX (Apple Silicon) | llama.cpp (GGUF), MLX by default for supported architectures on Apple Silicon |
| Model source | GGUF and MLX from Hugging Face | ollama.com library, GGUF and safetensors import |
| OpenAI-compatible API | `/v1/models`, `chat/completions`, `responses`, `completions`, `embeddings` | `/v1/models`, `chat/completions`, `responses` (stateless), `completions`, `embeddings` |
| Anthropic API | `POST /v1/messages` | `POST /v1/messages` |
| Native API | `/api/v1/chat` with conversation state, MCP, model management | `/api/*`: generate, chat, pull, create, ps and more |
| Port | 1234 | 11434 |
| Authentication | Off by default, Require Authentication with tokens | Local requests need no key |
| Headless | llmster daemon, `lms daemon up`, systemd | `ollama serve`, systemd service, Docker image |
| Parallel requests | On llama.cpp, up to 4 by default. Not yet on MLX | `OLLAMA_NUM_PARALLEL`, 1 by default |
| Coding agents | Manual setup of Claude Code, Codex, OpenCode per the docs | `ollama launch claude`, `codex`, `opencode` and others |
| MCP | MCP host in the app (`mcp.json`) | No MCP host of its own, MCP is set up in the client |
| Cloud | LM Link for running on another device of yours, Enterprise | ollama.com cloud models, disabled with `OLLAMA_NO_CLOUD=1` |

## LM Studio and Ollama licenses for work use

Ollama is MIT-licensed. You can read, change, embed and redistribute the code as long as you keep the license notice.

LM Studio works differently. The app itself is proprietary: the `lmstudio-ai` organization on GitHub has no source for it, and the `lmstudio-bug-tracker` repository is only an issue tracker. Since [July 8, 2025](https://lmstudio.ai/blog/free-for-work), the app is free at home and at work: you no longer fill out a form or get a separate commercial license.

The [Terms](https://lmstudio.ai/terms), dated August 23, 2026, set the conditions. The license is non-exclusive and non-transferable, for use "for Your personal and / or internal business purposes." You may not:

- modify the app or create derivative works;
- decompile or reverse engineer it, except where the law explicitly allows it;
- use it as a service bureau, application service provider or SaaS for third parties.

Running LM Studio on a work laptop and connecting your own agent to it is allowed. Reselling access to it as a service isn't. Teams get a paid Enterprise plan: SSO, restrictions on which models and MCP servers are available, and private collaboration.

The open parts of LM Studio live in the [lmstudio-ai](https://github.com/lmstudio-ai) organization under MIT:

| Repository | What it is |
|---|---|
| `lms` | CLI |
| `lmstudio-js` | TypeScript SDK `@lmstudio/sdk` |
| `lmstudio-python` | Python SDK, `pip install lmstudio` |
| `mlx-engine` | MLX engine for Apple Silicon |

Neither the [headless mode](https://lmstudio.ai/docs/developer/core/headless_llmster) page nor the Terms state a license for the llmster headless daemon, so there's no basis for calling it open. Models in both apps carry their own licenses, set by each model's author. This is a description of the terms, not legal advice: for a company, the current version of the Terms is what counts.

## Engines and MLX on Mac

Both apps run GGUF through llama.cpp and MLX models on Apple Silicon. The difference is who picks the engine.

In LM Studio you pick the format at download time: a model in the catalog has GGUF and MLX variants, and the downloaded file decides the engine. LM Studio implements MLX support with its own open-source [mlx-engine](https://github.com/lmstudio-ai/mlx-engine).

Ollama picks for you. It [announced](https://ollama.com/blog/mlx) an MLX preview on March 30, 2026, requiring more than 32 GB of unified memory and supporting the NVFP4 format. Since [v0.40.0](https://github.com/ollama/ollama/releases/tag/v0.40.0), models whose architectures the MLX runtime supports run on MLX by default on Apple Silicon.

On Ollama 0.40.14 with an M4 Max, the `qwen3.8:27b` tag pulls an MLX build: safetensors weights, nvfp4 quantization, runner `mlx`. The GGUF Q4_K_M of the same model needs an explicit tag:

```bash
ollama pull qwen3.8:27b            # on Apple Silicon: MLX, nvfp4
ollama pull qwen3.8:27b-q4_K_M     # GGUF for llama.cpp
ollama ps                          # RUNNER column: which engine is in use
```

For the MLX build with a 32768 context, `ollama ps` showed 100% GPU and RUNNER `mlx`, and its memory figure grew from 18 GB right after loading to 25 GB after the long-prompt runs. Framing the choice as "GGUF in Ollama vs MLX in LM Studio" is wrong: each app has both formats.

"4-bit" covers several different schemes:

| Scheme | Where | How it works |
|---|---|---|
| Q4_K_M | GGUF, llama.cpp in both apps | llama.cpp K-quantization |
| nvfp4 | MLX builds in the Ollama library | 4-bit floating point, groups of 16 weights, e4m3 scale |
| MLX 4bit (affine) | MLX models in the LM Studio catalog | 4-bit integer, groups of 64 weights, scale and bias per group |

The MLX scheme parameters are in the [`mlx.core.quantize` docs](https://ml-explore.github.io/mlx/build/html/python/_autosummary/mlx.core.quantize.html). The `config.json` of `lmstudio-community/Qwen3.8-27B-MLX-4bit` says `bits: 4`, `group_size: 64`, `mode: affine`. So a comparison of "MLX in Ollama vs MLX in LM Studio" changes the app and the quantization at once.

Parallel requests depend on the engine too. In LM Studio they work only on llama.cpp, up to four at a time by default, and for MLX the docs say "coming soon" ([parallel requests](https://lmstudio.ai/docs/app/advanced/parallel-requests)). In Ollama, `OLLAMA_NUM_PARALLEL` sets the number of parallel requests per model, 1 by default.

The LM Studio changelog mentions one more Mac engine starting with 0.4.25: Splash (M3 chips and newer, macOS 26.4+). The docs don't describe it, so it isn't part of the comparison.

## Installation and first run

### LM Studio

You download the installer from [lmstudio.ai](https://lmstudio.ai/download); on macOS the app is also in Homebrew as the `lm-studio` cask. The `lms` CLI lives inside the app and doesn't work until you've launched the app at least once. Before that it replies "No running LM Studio or Bionic app, and no valid installation was found." After the first launch, the `~/.lmstudio` directory appears and the CLI starts working. `lms bootstrap` adds it to `PATH` by appending a line to your shell profile.

```bash
brew install --cask lm-studio
open -a "LM Studio"                # the first launch is required
"/Applications/LM Studio.app/Contents/Resources/app/.webpack/lms" bootstrap   # lms on PATH
lms get https://huggingface.co/lmstudio-community/Qwen3.8-27B-MLX-4bit --mlx -y
lms ls                             # keys of downloaded models
lms load <model-key> --context-length 32768
lms ps
```

By default, models live in `~/.lmstudio/models/` in a "publisher/model/file" layout. In testing, `lms get` exited before the model finished downloading, while the app kept fetching `.part` files. Before `lms load`, check with `lms ls` or the downloads tab that the file is complete.

### Ollama

The [Ollama guide](https://futurecraft.pro/blog/ollama-guide/) covers installing Ollama on every platform. For this comparison, two commands are enough:

```bash
ollama run qwen3.8:27b --verbose   # downloads the model and shows speed
ollama ps                          # memory, context, processor, runner
```

### The same model in both apps

The apps have no shared model store. Ollama keeps weights in `~/.ollama/models/blobs` under hash names, LM Studio in its own directory. You can plug a GGUF file into LM Studio without a second copy: `lms import` has `--hard-link` and `--symbolic-link` flags ([docs](https://lmstudio.ai/docs/cli/local-models/import)).

```bash
ollama show --modelfile qwen3.8:27b-q4_K_M | grep '^FROM'   # path to the blob file
lms import --hard-link <path-to-blob>
```

The flag is mandatory. Without it, `lms import` moves the file by default, and the model disappears from Ollama. A hard link works only within one volume. This approach wasn't tested for MLX builds: Ollama keeps them in its blob store, and LM Studio expects a model folder in Hugging Face layout. For the benchmark, the MLX model for LM Studio was downloaded separately.

## Server and API

### OpenAI-compatible API

Both servers accept requests in the OpenAI format, so a client switches by changing `base_url`:

```bash
curl http://localhost:1234/v1/models     # LM Studio
curl http://localhost:11434/v1/models    # Ollama
```

```python
from openai import OpenAI

client = OpenAI(base_url="http://localhost:1234/v1", api_key="lm-studio")
# for Ollama: base_url="http://localhost:11434/v1", api_key="ollama"
resp = client.chat.completions.create(
    model="<model-key>",
    messages=[{"role": "user", "content": "Hello"}],
)
print(resp.choices[0].message.content)
```

With authentication off, the server doesn't check the key, but the SDK still requires one. The endpoint lists almost match: `/v1/models`, `/v1/chat/completions`, `/v1/completions`, `/v1/embeddings`, `/v1/responses` ([LM Studio](https://lmstudio.ai/docs/developer/openai-compat), [Ollama](https://docs.ollama.com/openai)). Ollama supports `/v1/responses` only in stateless form, without `previous_response_id`.

### Anthropic-compatible `/v1/messages`

Both servers accept the Anthropic Messages API format on `POST /v1/messages`, which is what Claude Code uses. Ollama added the endpoint in [v0.14.0](https://github.com/ollama/ollama/releases/tag/v0.14.0). For LM Studio the exact version isn't documented, but the changelog mentions the endpoint from 0.4.22 of August 28, 2026 onward. With authentication on, LM Studio accepts the token in both `x-api-key` and `Authorization: Bearer` ([docs](https://lmstudio.ai/docs/developer/anthropic-compat)).

### Native APIs

LM Studio's is `POST /api/v1/chat`: stateful conversations through `previous_response_id`, MCP server calls and model management. Ollama's is `/api/*` with `generate`, `chat`, `pull`, `create`, `ps` and speed metrics in the response. The native APIs aren't compatible with each other, so portable code targets `/v1`.

Both programs can load a model on the first request. In LM Studio this is JIT loading (the Just in Time Model Loading setting): a model you haven't loaded with `lms load` comes up on request and, by default, unloads after 60 minutes idle ([TTL and auto-evict](https://lmstudio.ai/docs/developer/core/ttl-and-auto-evict)). You change the TTL with `lms load --ttl` or a `ttl` field in the request. Ollama unloads a model after 5 minutes by default; `OLLAMA_KEEP_ALIVE` or `keep_alive` in the request changes that.

### Authentication and security

Ollama listens only on `127.0.0.1`, and the local API works without a key. `OLLAMA_HOST=0.0.0.0:11434` opens the server to the network, and then anyone who can reach the port can run, download and delete models. To expose Ollama, put it behind a reverse proxy with authentication, a VPN or an SSH tunnel.

LM Studio also has authentication off by default ([authentication](https://lmstudio.ai/docs/developer/core/authentication)). You turn it on with the Require Authentication switch in Server Settings and create tokens with chosen permissions in Manage Tokens. Access from other devices is a separate switch, Serve on Local Network ([server settings](https://lmstudio.ai/docs/developer/core/server/settings)). So LM Studio has built-in auth, while Ollama gets it from an external proxy.

## Headless mode and CI

On a server with no screen, LM Studio runs through llmster. The docs describe Linux:

```bash
curl -fsSL https://lmstudio.ai/install.sh | bash
lms daemon up
lms get <model>
lms load <model-key>
lms server start --port 1234
curl http://localhost:1234/v1/models
```

For autostart, the docs suggest a `oneshot` systemd unit that calls `lms daemon up`, loads the model and starts the server. The install script wasn't run while preparing this article, and llmster has no stated license.

On Linux, Ollama's `install.sh` creates an `ollama` user and a systemd service by itself, and there's an official `ollama/ollama` Docker image for CPU, NVIDIA and AMD. Docker Desktop on macOS has no GPU acceleration, so models run on the CPU there. For CI and containers, Ollama's path is shorter and fully open.

## Coding agents: Claude Code, Codex, OpenCode

### Claude Code

```bash
# LM Studio (per docs/integrations/claude-code)
lms server start --port 1234
export ANTHROPIC_BASE_URL=http://localhost:1234
export ANTHROPIC_AUTH_TOKEN=lmstudio
export CLAUDE_CODE_ATTRIBUTION_HEADER=0
claude --model <model-key>

# Ollama
ollama launch claude --model qwen3.8:27b
# or manually
export ANTHROPIC_AUTH_TOKEN=ollama
export ANTHROPIC_API_KEY=""
export ANTHROPIC_BASE_URL=http://localhost:11434
claude --model qwen3.8:27b
```

If authentication is on in LM Studio, put the token you created in `ANTHROPIC_AUTH_TOKEN`. The context recommendations differ: [LM Studio](https://lmstudio.ai/docs/integrations/claude-code) suggests a model and settings "with more than ~25k context length," and [Ollama](https://docs.ollama.com/integrations/claude-code) at least 64k. An agent's system prompt with tool descriptions easily takes tens of thousands of tokens, so aim for 64k if the model and your memory allow it.

Anthropic [doesn't support](https://code.claude.com/docs/en/llm-gateway) Claude Code with non-Claude models through any gateway. A local model in place of Opus 5.5 or Sonnet 5.5 is at your own risk.

### Codex

Codex works with LM Studio through the OpenAI-compatible `POST /v1/responses`, as the [LM Studio docs](https://lmstudio.ai/docs/developer/openai-compat) state directly. The Codex CLI has an `--oss` flag for local servers and a `--local-provider` option with the values `lmstudio` and `ollama`:

```bash
codex --oss --local-provider lmstudio -m <model-key>
codex --oss --local-provider ollama -m qwen3.8:27b
ollama launch codex                 # Ollama sets up the profile itself
```

For Codex, the [Ollama docs](https://docs.ollama.com/integrations/codex) also require a context of 64k or more. [Claude Code vs Codex](https://futurecraft.pro/blog/claude-code-vs-codex/) covers how the two differ as agents.

### OpenCode

Per the [OpenCode docs](https://opencode.ai/docs/providers/), LM Studio has built-in discovery of local models at `http://127.0.0.1:1234/v1`. Ollama connects with `ollama launch opencode` or through a provider config. The config, tool-call checks and results with local models are in the [OpenCode guide](https://futurecraft.pro/blog/opencode-guide/).

The server matters less to the agent than the model does. In the tests from the Ollama and OpenCode guides, 7-8B models either printed tool calls as text or edited things they shouldn't have. A model that's good at code in a chat won't necessarily hold up in an agent loop, and that doesn't depend on whether LM Studio or Ollama runs it. The [AI coding tools ranking](https://futurecraft.pro/blog/best-ai-coding-tools/) shows where a local stack sits among paid tools.

## MCP and integrations

Since version 0.3.17, LM Studio works as an MCP host: the model in the app's chat calls tools from MCP servers ([docs](https://lmstudio.ai/docs/app/mcp)). You describe servers in `mcp.json` using Cursor's notation (Program tab, Install, Edit mcp.json), and both local and remote servers are supported. The docs warn that an MCP server can run arbitrary code, read local files and make network requests. Don't install servers from untrusted sources. [MCP Servers Explained](https://futurecraft.pro/blog/mcp-servers-explained/) covers what MCP is and how servers work.

Ollama has no MCP host of its own. You connect MCP servers in the client that talks to Ollama: Claude Code, Codex, OpenCode. The Ollama docs include a sample Python MCP server for Ollama's web search; you plug it into a client, and Ollama itself doesn't call tools.

Both have SDKs for your own code. LM Studio has `@lmstudio/sdk` for TypeScript and `lmstudio` for Python; Ollama has `ollama` libraries for Python and JavaScript. If you need a local model next to cloud ones, either server works as a provider behind a [LiteLLM](https://futurecraft.pro/blog/litellm-guide/) gateway, and the [OpenRouter guide](https://futurecraft.pro/blog/openrouter-guide/) covers the cloud alternative with one bill for hundreds of models. Hardware, formats and quantization for running models locally in general are in the [local LLM guide](https://futurecraft.pro/blog/local-llm-guide/).

## Benchmark on an M4 Max with 36 GB

**Verified:** November 7, 2026, Mac with an Apple M4 Max (14-core CPU, 32-core GPU) and 36 GB of unified memory, macOS 27.2, on AC power. Ollama 0.40.14 from Homebrew and LM Studio 0.4.28 from a Homebrew cask with llama.cpp 2.71.0 and MLX 1.14.0 engines: newer versions than on the article's date. Heavy apps were closed before the run; Claude and system processes stayed open, about 17 GB of memory without a model. Swap was at 7 GB of 8 at the start, left over from earlier runs.

One model, Qwen3.8 27B, in four cells:

| Cell | App | Format and engine | Weights source | Speculative decoding (MTP) |
|---|---|---|---|---|
| A | Ollama | MLX, nvfp4 | `qwen3.8:27b` (default on Apple Silicon) | On by default |
| B | Ollama | GGUF Q4_K_M, llama.cpp | `qwen3.8:27b-q4_K_M` | Not in the llama.cpp runner |
| C | LM Studio | MLX 4bit (affine, group 64) | `lmstudio-community/Qwen3.8-27B-MLX-4bit` | Off via a load flag |
| D | LM Studio | GGUF Q4_K_M, llama.cpp | Same file as B, via `lms import --hard-link` | Off via a load flag |

Conditions in every cell: 32768 context, temperature 0, up to 400 output tokens. Two prompts: a short one (about 55 tokens) and a long one (about 8.9K tokens; in LM Studio it's ~40 tokens longer because of the chat template). 5 runs per prompt; the table shows the median, with min and max in parentheses. Each run had a unique prefix so the server couldn't serve the prompt from cache. All models were unloaded between cells, and the growth of `Pageouts + Swapouts` in `vm_stat` during the run showed whether the system went into swap.

The metrics came from different places. In Ollama, requests went to `POST /api/generate` with streaming and `think: false`, and generation speed came from the server's `eval_count` and `eval_duration` fields. In LM Studio, requests went to the OpenAI-compatible `POST /v1/chat/completions` with streaming, the model was loaded with `lms load <key> -c 32768 --no-speculative-draft-mtp`, and generation speed was the time between the first and last streamed token. TTFT is time to first token.

Ollama has no such flag: the MLX runner turns on MTP (multi-token prediction) for `qwen3.8:27b` by itself. The server log shows this with `speculative decode stats` lines, while the llama.cpp runner in the same log prints `no implementations specified for speculative decoding`. Of the four main cells, MTP ran only in A.

Qwen3.8's thinking wouldn't turn off in LM Studio through the API. `reasoning_effort: "none"`, `reasoning: {effort: "none"}`, `chat_template_kwargs: {enable_thinking: false}` and `/no_think` in the system prompt all had no effect: on a "Say ok" request the model still generated 22 reasoning tokens. In Ollama, thinking was off. Reasoning tokens are generated too and count toward decode, so generation speed is comparable across the apps, but output token counts and TTFT aren't. Ollama reports prompt processing speed itself, while for LM Studio you can only estimate it from TTFT. So prefill isn't in the table, and the conclusions below rest on decode.

### Results

| Cell | Generation, short prompt, tok/s | Generation, long prompt, tok/s | TTFT, long prompt, s | Model load, s | Swap during run |
|---|---|---|---|---|---|
| A. Ollama, MLX nvfp4 | 32.4 (30.4-35.5) | 19.4 (14.2-19.7) | 85.7 | ~7 | ≈ 11 GB |
| B. Ollama, GGUF Q4_K_M | 10.6 (9.6-10.7) | 10.1 (9.3-10.2) | 77.2 | ~8 | ≈ 0.8 GB |
| C. LM Studio, MLX 4bit | 20.3 (19.2-21.7) | 14.1 (7.9-14.4) | 68.6 | 8.6 | ≈ 0.4 GB |
| D. LM Studio, GGUF Q4_K_M | 12.4 (11.9-12.5) | 10.2 (10.1-10.2) | 73.9 | 12.8 | ≈ 3.9 GB |
| C + MTP. LM Studio, MLX 4bit, `--speculative-draft-mtp` | 21.1 (20.0-21.6) | 13.4 (1 run) | not measured | not measured | not measured |

The C + MTP row is a follow-up run of cell C with MTP on: 5 runs of the short prompt and one run of the long prompt, after which the follow-up was stopped. TTFT is in the table for reference only: thinking didn't turn off in LM Studio, so it isn't comparable between the apps.

Each app reports memory its own way, so the process footprint sits next to their numbers:

| Cell | What the app shows | Process footprint |
|---|---|---|
| A | `ollama ps`: 18 GB after loading, 25 GB after long runs | runner 17 GB after a short request |
| B | `ollama ps`: 17 GB | runner 3.5 GB plus the 16.8 GB weights file and the 0.9 GB vision projector via mmap |
| C | `lms ps`: model 16.08 GB | LM Studio process 20 GB |
| D | `lms ps`: model 16.81 GB | LM Studio process 10 GB |

How to read the tables:

- B and D are the cleanest app comparison: the same GGUF file, the same llama.cpp engine. The difference between them comes from each app's llama.cpp build and its defaults.
- A and C differ in three things at once: the engine inside the app, the quantization and MTP. nvfp4 and MLX 4bit (affine) are different 4-bit schemes with different group sizes and number formats, and MTP is on by default in A and off in C. The C + MTP row removes only the third difference.
- A vs B and C vs D show what MLX gives over GGUF within one app.
- In the GGUF cells the process is smaller than the file: llama.cpp maps the weights from the file into memory (mmap), and those pages don't count toward the process footprint. MLX keeps the weights inside the process.

### What the benchmark showed

On the same GGUF file, the apps are almost even: 10.6 and 12.4 tok/s on the short prompt, 10.1 and 10.2 on the long one. The app barely affects GGUF speed, so the license, the GUI and the integrations decide.

MLX beats GGUF in both apps: 3.1 times in Ollama (32.4 vs 10.6 tok/s, with MTP in the MLX cell) and 1.6 times in LM Studio (20.3 vs 12.4) on the short prompt. On a Mac, pick the format first; the app comes second.

The gap between the MLX cells is large: 32.4 tok/s for nvfp4 in Ollama vs 20.3 for affine 4bit in LM Studio. And 32.4 is above the upper bound set by memory bandwidth: about 23 tok/s for an 18 GB file at [410 GB/s](https://support.apple.com/en-us/121553) on this M4 Max configuration. That estimate assumes one token per read of the weights, and MTP accepts more per read. Per the Ollama server log for the cell A run, the median acceptance was 0.67 and `avg_accepted` was 1.29: that's how many tokens, on average, get accepted per iteration on top of the main one.

MTP doesn't explain the whole gap. The follow-up run of cell C with `--speculative-draft-mtp` gave 21.1 tok/s (20.0-21.6) on the short prompt vs 20.3 without it, so on this machine MTP added almost nothing in LM Studio. The long prompt with MTP ran once (13.4 tok/s), and then the follow-up was stopped. The A vs C difference adds up from the nvfp4 scheme, Ollama's MLX runner and MTP, and this benchmark can't separate their effects. It doesn't show that Ollama is faster, and comparing MLX in Ollama and LM Studio without the MTP caveat is wrong: Ollama turns it on by default for supported models, and LM Studio sets it at load time.

With 36 GB, both MLX cells hit the memory limit on the long prompt: a spread of 14.2-19.7 tok/s in A and 7.9-14.4 in C. During the A run about 11 GB went to swap, and `ollama ps` grew from 18 to 25 GB. The GGUF cells stay steady on the long prompt, 10.1 and 10.2 tok/s with a narrow spread. For a 27B model on 36 GB, memory headroom matters more than the format.

The hard link works: after `lms import --hard-link`, the GGUF file has two links and no extra 16.8 GB on disk. Parallelism in LM Studio 0.4.28 defaults to 4 (the PARALLEL column in `lms ps`); parallel requests weren't part of the benchmark.

The benchmark is tied to these versions, one model and one 36 GB machine with apps open. On a Mac with 64 GB or more, a different model architecture or Windows with NVIDIA, the picture may differ; that wasn't tested. Parallel requests, speed at a 64K context and agents running these models weren't tested either.

## When to choose LM Studio and when Ollama

**LM Studio** if:

- you're just starting and want to pick models in an interface, with file sizes and load settings in view;
- you need to compare quants and formats of one model: GGUF at different bit widths and MLX sit in one catalog;
- you want a chat with MCP tools right in the app;
- your company needs SSO and central control over models and MCP: that's LM Studio Enterprise.

**Ollama** if:

- you need a background server for your code, scripts and agents that starts with the system;
- the server runs on headless Linux, in Docker or in CI;
- company policy requires an open license for the whole stack;
- you want agents set up with one `ollama launch` command;
- you sometimes need a large cloud model through the same API: Ollama has cloud models, and local mode doesn't depend on them.

**Both together** is a workable setup. LM Studio is handy for finding a model and picking a quant, Ollama for keeping it running as a background server. The ports differ (1234 and 11434), and a GGUF file plugs from Ollama into LM Studio through a hard link. The one constraint is memory: models loaded in both servers take it at the same time.

## Limitations and gotchas

### `lms import` moves the file by default

Without `--copy`, `--hard-link` or `--symbolic-link`, the command moves the file into LM Studio's directory. For an Ollama blob file, that breaks the model in Ollama. The flags are mutually exclusive, so you can pass only one.

### The LM Studio CLI depends on the app

`lms` doesn't work until the app's first launch, and `lms get` can exit before the download finishes. In scripts, check `lms ls` after `lms get`, and on a server install llmster instead of the GUI app.

### Two copies of models and Ollama backups

You can share a GGUF file through a hard link, but each app needs its own download of an MLX model. In the benchmark, the Qwen3.8 27B GGUF linked into LM Studio with `--hard-link` took no extra 16.8 GB, while the MLX 4bit build of the same model took another 16.1 GB in LM Studio next to Ollama's ~18 GB nvfp4 build. Since [v0.40.2](https://github.com/ollama/ollama/releases/tag/v0.40.2), Ollama upgrades old models in the background on first run and keeps the original as a backup, so disk use temporarily doubles. A script in the release notes deletes the backups.

### Both servers share memory

A model loaded in LM Studio through JIT stays in memory for up to 60 minutes idle; in Ollama, 5 minutes. On 36 GB, the 27B MLX build that grows to 25 GB in Ollama leaves no room for the same model in the second server. Before switching, unload the model (`lms unload`, `ollama stop <model>`) or shorten the TTL.

### MLX in Ollama isn't for every model

MLX turns on only for architectures that Ollama's MLX runtime supports; the rest run on llama.cpp. The preview required more than 32 GB of unified memory. `ollama ps` shows which engine is actually running; the tag name doesn't tell you.

### No parallelism on MLX in LM Studio

Continuous batching in LM Studio works only on llama.cpp. For MLX the docs say "coming soon," so an MLX model can't yet process requests from several clients in parallel.

### Qwen3.8 thinking can't be turned off through the LM Studio API

In LM Studio 0.4.28, neither `reasoning_effort: "none"`, nor `chat_template_kwargs: {enable_thinking: false}`, nor `/no_think` in the system prompt turned off reasoning in Qwen3.8 27B: the model spends tokens thinking even on a short request. That makes responses longer and delays the first visible token, and compared with Ollama, where `think: false` works, only generation speed lines up.

### Default context differs

Ollama picks the context from the amount of VRAM (32768 on 36 GB), while LM Studio takes it from the model's load settings. For a fair comparison and for agents, set the context explicitly in both.

### Versions change every week

From September 25 to October 18, 2026, Ollama shipped eight 0.40.x versions, and LM Studio shipped three since early September. Default behavior changes between them, so any numbers, including the benchmark in this article, are tied to a version and a date.

## Where to start

1. Decide on the main job: a GUI and model picking means LM Studio, a background server and an open license mean Ollama.
2. Install the app you picked. For LM Studio, launch the app once, then run `lms bootstrap`. For Ollama, check `curl http://localhost:11434/api/version`.
3. Pick a format: on Apple Silicon, try the MLX and GGUF builds of one model and compare speed on your own tasks.
4. Check where the model runs: `ollama ps` (RUNNER, PROCESSOR, CONTEXT) or `lms ps`.
5. Connect your code through `/v1` with the OpenAI SDK, and an agent through `/v1/messages` or `/v1/responses`, with a context of 64k or more.
6. Before opening the server to the network, turn on Require Authentication in LM Studio or put a proxy with authentication in front of Ollama.
