← All guides

llama.cpp Flags Explained (2026): --no-mmap Is Now -lm none

Most llama.cpp guides copy a command line from a forum post and never say what the flags do. That worked until 2026, when the flag set changed underneath everyone. --no-mmap and --mlock are gone, -ngl defaults to auto instead of 0, and -fa decides for itself. Here is what every flag that matters actually does, which ones buy speed, which ones only buy memory, and which commands on the internet now fail outright.

Bottom Line (2026)

  • Three flags changed underneath everyone in 2026. --no-mmap, --mlock and --direct-io were folded into -lm, --load-mode (PR #20834, merged 2026-07-23), kept as deprecated aliases, then removed outright in PR #28334 on 2026-09-09. Any build from b10875 onward rejects them with error: invalid argument.
  • Pasted an error? Go straight to every error: invalid argument and its fix. It covers --no-mmap, --mlock, -cd, -cnv, --ngl, --ctx-shift and the llama-bench -mmp flag.
  • -ngl now defaults to auto. The advice to always pass -ngl 99 is a workaround for a default that no longer exists.
  • Separate the memory flags from the speed flags. This is the distinction almost nobody writes down, and it is why people set KV cache quantization expecting a speed-up and measure a slow-down.
  • Only two flags reliably buy you speed on a machine that already fits the model: -fa and -ub. Everything else buys you the ability to run the model at all.
  • A current build may shrink your context without telling you. -fit defaults to on and lowers unset arguments, -c first, until the model fits. Pass -fit off when you benchmark. Checked against the v0.9.0 README on 2026-11-04.
  • Do not copy a --n-cpu-moe value. Sweep it. See llama.cpp MoE Offload Flags Explained for the method.

The Flag Table

Flag spellings and defaults below are quoted from the llama-server README, first on 2026-09-15 and re-checked on 2026-11-04 against the v0.9.0 release. Every default in the September table still holds. Six flags are new since then; they are marked new. Check your own build with llama-server --help; this project moves fast.

FlagWhat it doesDefaultBuys you
-ngl, --gpu-layers, --n-gpu-layers NMax layers stored in VRAM. Takes a number, auto, or allautoFit
-lm, --load-mode MODEHow the model is loaded: auto, none, mmap, mlock, mmap+mlock, dioautoFit
-fa, --flash-attn [on|off|auto]Flash AttentionautoSpeed
-fit, --fit [on|off] newAdjusts arguments you did not set so the model fits in device memoryonFit, silently
-fitc, --fit-ctx N newSmallest context --fit may pick4096Fit
-fitt, --fit-target MiB,... newMemory margin per device that --fit keeps free1024Fit
-lzm, --lazy-mode MODE newReads large tensors, such as per-layer embeddings, from disk on demand: on, auto, off. Needs mmapauto (on above 4 GiB)Fit
--cpu-moe, -cmoeKeeps all MoE weights in CPU RAMoffFit
--n-cpu-moe N, -ncmoeKeeps MoE weights of the first N layers in CPU RAMoffFit
-ncffn, --n-cpu-ffn N newThe dense-model twin of --n-cpu-moe: keeps the FFN weights of the first N layers in CPU RAMoffFit
--moe-cache-mib N newGPU cache, in MiB, for the experts you kept in CPU RAM. Split across GPUs like -ts0 (off)Speed for MoE offload
-c, --ctx-size NPrompt context size. 0 reads it from the model0Fit
-b, --batch-size NLogical max batch size2048Little
-ub, --ubatch-size NPhysical max batch size — sizes the compute buffers512Speed / fit
-dt, --defrag-thold NKV cache defragmentation threshold. Marked DEPRECATED in the README—Nothing. Delete it
--cache-type-k TYPEKV cache type for K: f32, f16, bf16, q8_0, q4_0, q4_1, iq4_nl, q5_0, q5_1f16Fit
--cache-type-v TYPEKV cache type for Vf16Fit
-kvo/-nkvo, --kv-offload/--no-kv-offloadWhether the KV cache lives on the GPUenabledFit
--swa-fullUse a full-size sliding-window-attention cachefalseFit
-np, --parallel NNumber of server slots (concurrent requests)-1 (auto)Throughput
-sm, --split-mode {none,layer,row,tensor}How a model splits across several GPUslayerFit
-ts, --tensor-split N0,N1,...Fraction of the model sent to each GPUevenFit
-ot, --override-tensor <pattern>=<type>Per-tensor buffer placementoffFit
-dev, --device <dev1,dev2>Which devices to offload toallControl
-t, --threads NCPU threads used during generation-1 (auto)Speed on CPU
--numa TYPENUMA optimizations on multi-socket machinesoffSpeed on CPU
-n, --predict NTokens to predict. -1 is unlimited-1—
--jinja / --no-jinjaJinja chat template engineenabledCorrectness

Memory Flags and Speed Flags Are Not the Same Thing

This is the distinction that makes the table usable.

A memory flag changes whether the model runs at all. -ngl, -c, --cache-type-k, --cache-type-v, --n-cpu-moe, -ts and --swa-full all trade something away so the weights and the cache fit in the memory you own. Most of them make generation slower. You accept that, because the alternative is not running.

A speed flag changes tokens per second on a model that already fits. There are far fewer of these than the internet implies. -fa on is the reliable one. -ub helps prompt processing when you raise it and helps VRAM fit when you lower it. -t matters when the CPU is doing real work, which now includes every MoE offload setup.

The practical consequence: quantizing your KV cache will not speed anything up. --cache-type-k q8_0 is a memory feature. It frees VRAM so you can raise -c, and it adds conversion work on every token. If f16 fits, f16 is faster. People try it as a performance tweak, measure a regression, and conclude llama.cpp is unpredictable. It is not; the flag was never a speed flag.

The 2026 Breaking Change: --no-mmap and --mlock Are Gone

If you have hit error: invalid argument on a command that worked last year, this is almost certainly why.

llama.cpp collapsed four separate loading flags into one. -lm, --load-mode MODE now takes:

ModeBehaviour
autommap, unless a device does not support it. The default
noneNo special loading mode. This is the old --no-mmap
mmapMemory-map the model
mlockForce the system to keep the model in RAM rather than swapping it
mmap+mlockBoth
dioUse DirectIO where available

The migration table is short:

Old flagWrite this instead
--no-mmap-lm none
--mlock-lm mlock
--mmap-lm mmap
--direct-io-lm dio

The honest caveat nobody publishes with the migration table. The new enum treats mlock as always implying mmap, so the old --no-mmap --mlock combination has no replacement. That combination mattered specifically to MoE offload users: it loaded weights into ordinary heap buffers while stopping the kernel swapping out the CPU-resident expert tensors. Issue #26110, opened 2026-07-25 and still open at the time of writing, reports the consequence — -lm none lets CPU-resident weights get swapped out under load, with throughput falling from roughly 25-27 tok/s to 7.55 tok/s, while -lm mlock double-buffers the model and invites the OOM killer.

If you run a large MoE with --n-cpu-moe on a machine that is tight on RAM, test both modes and watch swap. There is currently no setting that gives you what the old pair gave you.

Every error: invalid argument and Its Fix

All of these come from one line in llama.cpp’s argument parser. The parser keeps a separate flag list for each binary. If a word on your command line is not in the list for the binary you ran, it stops with error: invalid argument: <word>. So the error means one of three things. The flag was removed, the flag belongs to a different binary, or the flag is misspelled.

You seeCauseFixChanged in
error: invalid argument: --no-mmapFlag removed-lm nonePR #28334, b10875
error: invalid argument: --mlockFlag removed-lm mlockPR #28334, b10875
error: invalid argument: --mmapFlag removed. mmap is already the defaultDelete it, or -lm mmapPR #28334, b10875
error: invalid argument: --direct-ioFlag removed-lm dioPR #28334, b10875
error: invalid parameter for argument: -mmpllama-bench dropped -mmp and -dio-lm none or -lm mmapPR #28334, b10875
error: invalid argument: -cd--ctx-size-draft removedDelete it. No replacementPR #22838, b9109
error: invalid argument: -cnvLegacy flag. Not in the new llama-cliRun llama-completionPR #17824, b7348
error: invalid argument: --nglMisspelled long form-ngl 99 or --n-gpu-layers 99Never valid
error: invalid argument: --ctx-shiftMisspelled--context-shiftNever valid
error: unknown value for --flash-attn-fa now needs a value-fa onPR #15434, b6325
error: invalid argument: 1A value after a flag that takes noneDelete the valueNot a change

Release numbers are the first tagged build that carries the change. Run llama-server --version to see yours.

error: invalid argument: —no-mmap (and —mlock, —mmap, —direct-io)

The four loading flags are gone. PR #20834 merged -lm, --load-mode on 2026-07-23 and kept the old names as deprecated aliases. The first release with it is b10105. PR #28334 then deleted the aliases on 2026-09-09. Its author wrote that it had been “a decent amount of time since we deprecated” them. The first release without them is b10875.

The fix is a one-word swap:

# before (fails on b10875 and later)
llama-server -m model.gguf --no-mmap -ngl 99

# after
llama-server -m model.gguf -lm none -ngl 99

The silent version of this error. Docker and systemd setups often pass flags as environment variables. LLAMA_ARG_MMAP, LLAMA_ARG_NO_MMAP and LLAMA_ARG_MLOCK belonged to the removed flags. The parser reads an environment variable only when a current flag declares it, so these three are now ignored with no warning. Your server starts, and it loads the model with the default mmap mode. Replace them with LLAMA_ARG_LOAD_MODE=none or LLAMA_ARG_LOAD_MODE=mlock.

If you used --no-mmap --mlock together, read the caveat in the section above. That pair has no exact replacement.

error: invalid parameter for argument: -mmp

This is the llama-bench version of the same change. llama-bench has its own parser and its own error text. PR #28334 removed -mmp, --mmap and -dio, --direct-io from it too. Use -lm none where you had -mmp 0, and -lm mmap where you had -mmp 1. The -lm option in llama-bench accepts a comma-separated list, so you can still compare modes in one run.

error: invalid argument: -cd

-cd was --ctx-size-draft: the context size for the draft model in speculative decoding. It was a real llama-server flag. PR #22838 reworked speculative decoding for parallel drafting and deleted it on 2026-05-11. The first release without it is b9109. The current argument list has no draft context size flag, so delete it from your command line.

Older draft flags fail with a different message, because llama.cpp kept stubs for them. --draft, --draft-n, --draft-max and --draft-min now print the argument has been removed. use --spec-draft-n-max or --spec-ngram-mod-n-max (or the -n-min pair). The message names the replacement, so follow it.

error: invalid argument: -cnv (and -i, -if, -gan)

You are running the new llama-cli. PR #17824 rebuilt llama-cli on top of llama-server on 2025-12-10 (first release b7348). The old program still exists, renamed llama-completion. Conversation mode (-cnv, -no-cnv), interactive mode (-i, -if) and group attention (-gan, -gaw) are registered only for llama-completion in the current parser.

# old tutorial command
llama-cli -m model.gguf -cnv
# same behaviour today
llama-completion -m model.gguf -cnv

The new llama-cli is a chat program by default, so most people can drop -cnv and keep llama-cli.

error: invalid argument: —ngl

The short flag has one dash: -ngl. The long forms are --gpu-layers and --n-gpu-layers. A maintainer gave exactly this answer in issue #23739. As of 2026, -ngl defaults to auto, so you can often delete it.

error: invalid argument: —ctx-shift

The flag is spelled --context-shift, and its opposite is --no-context-shift. Both are valid for llama-server and llama-cli. --ctx-shift is not in the parser.

error: unknown value for —flash-attn

-fa used to be an on/off switch with no value. PR #15434 changed it on 2025-08-30 to take on, off or auto (first release b6325). An old command with a bare -fa now hands the next word to -fa as its value. Write -fa on, or delete the flag, because the default is auto.

error: invalid argument: 1 (or any number)

The parser read a value as if it were a flag name. The flag before it takes no value. --jinja 1 fails this way, because --jinja is a switch: write --jinja or --no-jinja. Look at the word just before the one in the error.

The rule for anything not listed here

Run the binary with --help and search for the flag. Do not check it against a tutorial or against another binary’s README. A flag that works in llama-server can be invalid in llama-cli, llama-completion or llama-bench, because each binary registers its own list.

The Flags Added Since September: -fit, --lazy-mode, --moe-cache-mib

Three of the six new flags change what a copied command does, so they get their own section. All quotes are from the README on 2026-11-04.

-fit, --fit [on|off] — “whether to adjust unset arguments to fit in device memory”, default on. This is the one to know about. On a current build the server looks at your device memory and lowers arguments you did not set, context first, until the model fits. It does not error and it does not ask. So a model that “runs fine” may be running at 4,096 tokens of context, the --fit-ctx floor, instead of the 128K you assumed. Two consequences:

  • When you benchmark, pass -fit off. Otherwise two machines with the same command line can run different contexts and different batch sizes, and your numbers will not compare.
  • When the model does not fit even at the floor, you still get the old out-of-memory failure. -fit lowers settings; it does not offload for you.

-fitt, --fit-target sets the margin --fit keeps free per device, in MiB, default 1024. -fitc, --fit-ctx sets the smallest context it may choose, default 4096. Search Console shows people already typing --fit off into Google; this is the flag they are looking for.

-lzm, --lazy-mode MODE — “on-demand reading of certain tensors, for example per-layer embeddings”, default auto, which the README defines as “on, but only for tensors larger than 4 GiB”. The README says it “requires mmap”, so it cannot work under -lm none. The target is models with huge per-layer embedding tables, Gemma-style, where a 4 GiB table would otherwise sit in RAM for the whole session.

--moe-cache-mib N — “GPU cache size in MiB for the MoE experts kept in the CPU”, default 0, disabled. It is the partner of --n-cpu-moe: the experts you pushed to system RAM get a GPU-side cache, so the hot ones stop crossing the bus every token. With several GPUs it is “split among them like the layers”. This is the only new flag that buys speed, and only for MoE offload setups. Start it at a few thousand MiB and sweep, the same way you swept --n-cpu-moe.

-ncffn, --n-cpu-ffn N — the dense-model twin of --n-cpu-moe: “keep the dense FFN weights of the first N layers in the CPU”. Use it on a dense model that is a few GB over your VRAM. The README says plainly: “for MoE expert weights use —n-cpu-moe”.

The v0.9.0 release itself, tagged 2026-11-04, added an OCP FP8 E4M3 tensor type and a new ftype, LLAMA_FTYPE_MOSTLY_F8_E4M3. That is a file format, not a flag: nothing in this table changed for it.

The Flags Worth Setting By Hand

Everything defaults sensibly now. These are the ones still worth a deliberate value.

  • -c, --ctx-size — the default reads the model’s trained context, which on a modern model can be enormous and will reserve VRAM to match. Set it to the context you actually use. This is the single most common cause of “it used to fit.”
  • -fa on — leaving it on auto is fine, but pin it on when you are benchmarking, so a build-to-build change in the auto heuristic does not silently move your numbers.
  • -ub — lower it to 256 when you are a few hundred megabytes short of fitting. Raise it when prompt processing is your bottleneck and VRAM is not.
  • --n-cpu-moe N — for MoE models only, and only after a sweep.
  • -np, --parallel — raise it only if you genuinely serve concurrent requests. Each slot reserves its own KV cache, so raising it on a single-user machine costs VRAM and returns nothing.
  • -fit off — for any run whose number you intend to compare with another run.

How to Find Your Own Numbers

The values in every guide, including this one, came off somebody else’s machine. Quant, RAM speed, context length, GPU and CPU all move them. The method transfers; the numbers do not.

  1. Start from defaults. Set -c to the context you need and pass -fit off, so the server does not move your settings between runs.
  2. Change one flag. Measure tokens per second on a fixed prompt.
  3. Watch VRAM while you do it. The cliff where VRAM spills into driver-managed system memory is sharp, and on many systems it produces no error message at all — just a collapse in speed.
  4. When speed collapses, back off one step and stop.

Which card you own decides how many of these flags you ever need — most of the memory flags exist to work around VRAM you do not have.

Sources

See Also

Read next

llama.cpp --n-cpu-moe Explained: 35B MoE on a 12GB GPU
--n-cpu-moe keeps MoE expert weights in system RAM so a 35B MoE runs on a 12GB card. How to pick N for your VRAM, the other flags, and community tok/s.
Check KV Cache Size in llama.cpp and Ollama: Read the Log
The exact log lines that show how much KV cache llama.cpp and Ollama allocated, read from their source in September 2026. Why llama-server can shrink your context without a visible line, why its default is 4 slots, and how sliding-window models show two caches.
Why Local LLMs Are Slow Even When They Fit
A local LLM can fit in RAM or VRAM and still feel slow. Diagnose prefill, decode, KV cache, context length, runtime, quantization, and CPU fallback.
llama.cpp KV Cache Quantization (2026): Start With q8_0
llama.cpp KV cache quantization: q8_0 uses 53% of the f16 memory, q4_0 uses 28%. The -ctk and -ctv flags, OLLAMA_KV_CACHE_TYPE, the flash attention rule, and when f16 is faster.