LM Studio's Headless and CLI Mode
9 min read · updated August 11, 2026
LM Studio began as a desktop application, which makes “run it on a server” an awkward request until you know that there are now two separate answers to it. Picking the wrong one is how people end up running a full desktop session on a headless box to keep an HTTP server alive.
Two different headless things
The distinction matters because the documentation for one does not apply to the other.
- The desktop app in service mode. The graphical application, installed normally, configured to run its server without a window open. The documentation describes settings for running the LLM server on login and for the last server state being saved and restored on app or service launch. This is the right answer on a workstation you also use interactively: the same install, the same models, no window.
- The daemon. LM Studio’s documentation describes
llmsteras the core of the desktop app packaged to be server-native, without reliance on the GUI, aimed at Linux boxes, cloud servers and GPU rigs, and managed primarily through thelmsCLI. This is the right answer on a machine with no desktop environment at all, where the graphical app is not merely unwanted but unrunnable.
The rest of this page is about the second, because the first is a checkbox. If your target is a headless Linux server, you want the daemon.
lms daemon is not present in your build, you have the older arrangement, and the app-in-service-mode route is the one available to you.Getting it onto the machine
The documented install path is a script, which is the usual trade: a one-liner against a package you have not read. Fetch it and look at it first if the machine matters.
# Linux and macOS curl -fsSL https://lmstudio.ai/install.sh | bash # Windows, in PowerShell irm https://lmstudio.ai/install.ps1 | iex
What you are checking for afterwards is that lms is on your PATH and that it can talk to something. On a machine where the desktop app was installed previously, lms may already exist and may be an older copy; confirm the version rather than assuming.
Bringing up a server with no desktop
- Start the daemon and confirm it is running before doing anything else:
lms daemon up lms daemon status
- Fetch a model. Nothing is preinstalled, and a server with no models answers
/v1/modelswith an empty list rather than an error, which is a confusing way to spend ten minutes:lms get llama-3.1-8b@q4_k_m --gguf lms ls
- Load it explicitly rather than relying on just-in-time loading, so that the first real request does not pay the load:
lms load <model-key> --gpu max --context-length 8192 lms ps
- Start the HTTP server. On a machine you will call from elsewhere, the bind address is the decision that matters:
lms server start --port 1234 --bind 0.0.0.0 lms server status
- Verify from the machine that is going to use it, not from the server itself — a loopback test proves nothing about the firewall:
curl -s http://SERVER_HOST:1234/v1/models
Step four deserves a warning rather than a footnote. There is no authentication on this server. Binding to 0.0.0.0 puts an unauthenticated endpoint that will load models and answer prompts on every interface the machine has. On anything but a trusted private network, keep the bind on loopback and reach it through an SSH tunnel or put a reverse proxy that does authenticate in front of it. The broader trade is in self-hosting versus an API.
Keeping it up across reboots
lms daemon up in an SSH session gets you a server until something restarts. For anything you depend on, the daemon needs to be started by the init system, and the documented settings for restoring the last server state on launch are what make that useful — the port and the loaded model come back rather than needing to be set again.
A systemd unit is the usual mechanism on Linux. The details that actually bite are not the unit syntax: it is that the daemon needs the right user (the one whose home directory holds the models), the right environment, and access to the GPU devices. A unit that runs as root when the models were downloaded as your user will start cleanly and find nothing.
Give it a health check that means something. /v1/models answers quickly and proves the HTTP layer is up; it does not prove a model is loaded, so a check that cares about readiness should compare the response against the model you expect rather than checking for a 200.
Operating it
The commands you will actually use day to day are short. lms ps lists what is in memory and is the first thing to run when latency is wrong — a model that was unloaded is a just-in-time reload on the next request. lms unload --all clears memory, which is how you reclaim VRAM for something else without restarting anything. And lms log stream prints the traffic through the server, including the fully rendered prompt, which is the single most useful diagnostic available and the one people forget exists.
Loading more than one model at a time is possible and is governed by memory rather than by a setting — multiple models loaded in LM Studio covers what happens when the budget runs out. The endpoints themselves are the same ones the desktop app serves, described in LM Studio’s local server.