Gemma4All logoGemma4All
Gemma 4HardwareMemory

How Much Memory Does Gemma 4 Actually Need? The Full Formula

The complete math behind our Gemma 4 hardware checker: weight size from parameters, why usable memory isn't total memory, the comfortable/tight thresholds, and where the model is honestly incomplete.

By Gemma4All EditorialUpdated July 28, 202610 min read

Our Can You Run Gemma 4? checker takes two inputs — your device type and how much memory it has — and hands back a verdict: comfortable, tight, or won't fit. That verdict isn't a guess. It comes from a small, fixed formula, applied the same way every time, using only the numbers Google publishes.

This article opens the box. Every number below comes from one of two places: Google's official Gemma 4 documentation (the weight table) or the checker's own source file, gemma-engine.ts (the usable-memory and verdict logic). Where something is an estimate rather than a measured value, it's labeled as one. The last section is the part we think matters most: what this model doesn't account for.

Step 1: Where the Weight-Size Number Comes From

A model's parameters are just numbers — weights — and each one is stored using some number of bits. Multiply parameter count by bits-per-parameter, and you get (roughly) the size of the weight file:

weight size ≈ parameter count × bits per parameter ÷ 8 (bits per byte)

That's the theory. In practice, Google publishes the real, measured numbers directly rather than making you compute them, because a couple of Gemma 4's design choices make the naive math wrong. The clearest example is Per-Layer Embeddings (PLE): instead of one shared embedding table for the whole model, Gemma 4's smaller models give every decoder layer its own embedding lookup table. Those tables are large in storage terms but cheap to compute with — which is why the E4B model (4 billion effective parameters) actually needs more memory to load than a naive "4B × 4 bits" calculation predicts. "Effective" describes compute cost, not file size.

So rather than re-derive the math per model, our checker's data table — gemma-engine.ts, mirroring Google's published figures — hardcodes the real weight sizes for all five models across all three quant levels:

ModelQ4_0 (4-bit)SFP8 (8-bit)BF16 (16-bit)
Gemma 4 E2B2.5 GB4 GB8 GB
Gemma 4 E4B5 GB7.5 GB15 GB
Gemma 4 12B6.7 GB13.4 GB26.7 GB
Gemma 4 26B A4B15.6 GB25 GB48 GB
Gemma 4 31B17.4 GB30.4 GB58.3 GB

These are the same figures used in our hardware requirements guide — this article is about the logic layered on top of them, not the table itself.

One nuance worth flagging here since it resurfaces in the quantization guide: these are weight-loading minimums, not real GGUF download sizes. The official QAT GGUF checkpoints (covered in our QAT guide) run somewhat larger than these numbers — for example the E2B QAT GGUF is 4.3 GB, not 2.5 GB. GGUF files carry tokenizer data, metadata, and — per the Hugging Face GGUF format docs — often keep certain tensors (embeddings, output projections) at higher precision than the rest of the model even in a "4-bit" quant. The weights-only number above is the loading floor; a real downloaded file is usually a bit above it.

Step 2: Usable Memory Isn't Total Memory

Here's the part every "how much RAM do I need" question skips: the memory number on the box isn't the memory number you get to spend on model weights. Something is always claimed by the operating system, the driver, or — on CPU — by the runtime itself.

Our checker applies exactly one rule per device type, no exceptions:

Mac (unified memory):  usable = total − 5 GB
NVIDIA GPU (VRAM):     usable = total − 1 GB
CPU only (system RAM): usable = total ÷ 2

This is the entire function, from gemma-engine.ts:

export function usableMemory(device: DeviceType, totalGb: number): number {
  if (device === "mac") return totalGb - 5;
  if (device === "gpu") return totalGb - 1;
  return totalGb / 2; // cpu: RAM ÷ 2 rule
}

Why three different rules?

  • Mac (−5 GB flat). macOS and background processes reserve roughly 5 GB of the shared unified memory pool before your model gets a byte. This is a flat subtraction regardless of whether the Mac has 16 GB or 128 GB — a deliberately simple, conservative estimate rather than a precisely measured one.
  • GPU (−1 GB flat). The NVIDIA driver and OS reserve roughly 1 GB of VRAM. Much smaller than the Mac reservation, because VRAM is a dedicated pool the OS mostly leaves alone — it isn't also running your desktop environment out of the same memory.
  • CPU (÷2). This one isn't modeling "OS overhead" at all — it's a much blunter rule of thumb: one copy of memory for the loaded weights, and roughly one more copy's worth for the runtime's working memory (activation buffers, KV cache, and general overhead) during inference. Halving the total is a coarse way of leaving room for both without trying to estimate the runtime's actual footprint.

None of these three numbers are things we measured ourselves on real hardware — they're standing estimates, applied uniformly. That's a deliberate simplicity trade-off, and it's revisited in the limitations section below.

Step 3: From Usable Memory to a Verdict

Once you have a usable-memory number, the checker walks the weight table and picks the best quant that fits — "best" meaning highest quality, not smallest. Here's the actual logic:

export function getVerdict(usable: number, weights: Record<QuantKey, number>): Verdict {
  if (usable <= 0) return { status: "none", quant: null, sizeGb: null };

  const comfortableCeiling = usable * 0.8;

  for (const q of QUANT_ORDER) {              // bf16 → sfp8 → q4_0
    if (weights[q] <= comfortableCeiling) {
      return { status: "comfortable", quant: q, sizeGb: weights[q] };
    }
  }
  for (const q of QUANT_ORDER) {
    if (weights[q] <= usable) {
      return { status: "tight", quant: q, sizeGb: weights[q] };
    }
  }
  return { status: "none", quant: null, sizeGb: null };
}

In plain language:

  1. Compute a comfortable ceiling at 80% of usable memory.
  2. Walk quants from highest quality to lowest (BF16 → SFP8 → Q4_0). The first one whose weight size fits under that 80% ceiling wins — that's your comfortable verdict, at the best quality your memory affords, not just the smallest one that fits.
  3. If nothing fits under 80%, walk the list again against the full 100% of usable memory. The first fit here is tight — it'll load and run, but there's little headroom left for anything else.
  4. If nothing fits even at 100%, the model gets a won't fit verdict for that device.

Two design choices are worth calling out explicitly:

Why 80%, not 100%? That reserved 20% is the checker's stand-in for everything Step 2's flat subtraction doesn't cover: the KV cache that grows as your conversation gets longer, and normal multitasking (a browser, an IDE, background apps). It isn't derived from a measurement of any specific context length — it's a fixed safety margin, chosen to be conservative rather than precise. A verdict of "tight" is the checker's way of telling you that margin is gone.

Why highest-quality-first, not smallest-first? Because the practical question isn't "what's the smallest thing that fits" — it's "what's the best thing I can run." A machine with room to spare for the BF16 weights gets recommended BF16, even though Q4_0 would also technically fit. Bigger/better wins whenever there's a genuine choice.

What "KV Cache" Actually Means, Briefly

Both Step 2's CPU rule and Step 3's 80% ceiling are proxies for the same underlying cost: the KV cache. Every token in a conversation — what you typed and what the model generated — gets converted into key and value vectors that the model caches so it doesn't have to recompute them for every subsequent token (Hugging Face's cache documentation covers the mechanism in detail). That cache grows with context length: a two-sentence prompt costs almost nothing extra; pushing toward Gemma 4's full 128K or 256K context window (see the model card for per-model context limits) can add multiple gigabytes on top of the base weight size.

This is exactly why the checker doesn't try to model KV cache directly by context length — doing it properly would mean asking users a question they can't easily answer ("how many tokens of context do you plan to use, on average, across your sessions?") and building a per-model, per-context formula neither Google's docs nor our own measurements can currently ground with real numbers. The 80%-ceiling / half-of-RAM rules are the checker's honest substitute: a fixed buffer, applied uniformly, rather than a precise-looking number we can't actually back up.

The Model's Known Limitations

This is the part we'd rather state plainly than gloss over, because a calculator that pretends to be more precise than it is isn't actually more trustworthy — it's just better at hiding its assumptions.

  • Context length isn't modeled explicitly. The 20% comfortable-margin and the CPU ÷2 rule are flat proxies for KV cache growth, not a function of your actual context window usage. A "comfortable" verdict assumes typical usage, not someone deliberately filling the full 256K window every session — that scenario could tip a "comfortable" verdict into "tight" in practice.
  • The Mac and GPU overhead numbers are flat constants. −5 GB for macOS applies the same way to a 16 GB MacBook Air and a 128 GB Mac Studio, and −1 GB applies the same way to every NVIDIA card regardless of driver version or what else is running on the GPU. Real overhead varies with OS version, background load, and display configuration; these are round, conservative stand-ins, not per-device measurements.
  • The CPU ÷2 rule doesn't distinguish runtimes. llama.cpp, Ollama, and other backends don't all have identical memory overhead, and none of that variation is captured — it's one rule for "CPU only," full stop.
  • No batch size, no concurrent requests. The formula assumes a single user, one conversation at a time. Running multiple simultaneous sessions or batched inference changes the memory math in ways this model doesn't touch.
  • The phone tab uses a completely separate, simpler model. The phone checker (E2B/E4B only) isn't derived from usableMemory() / getVerdict() at all — it uses hand-set thresholds (E2B: comfortable at 8 GB+, tight at 6 GB; E4B: comfortable at 12 GB+, tight at 8 GB) based on what actually runs through Google's AI Edge Gallery app in practice, rather than the same 80%/100% math used for Mac/GPU/CPU. If you're curious why the two systems look different, that's why — see our phone guide for the mobile-specific numbers.
  • We haven't run controlled benchmarks ourselves. Every number in this article is either Google's published weight-loading figure or a documented rule from our own checker code — not something we measured on physical hardware. Where community reports (Reddit threads, forum posts) suggest slightly different real-world VRAM usage, we haven't independently verified them, and we've avoided stating them as fact.

None of this means the verdict is wrong — it means "comfortable" is a reasonably conservative estimate for typical use, not a guarantee for every workload. If you're right on a boundary (a "tight" verdict, or "comfortable" with a long-context use case in mind), treat the checker as a strong starting point and expect to verify with a shorter test session before committing to a workflow.

Try It Yourself

The formula above is exactly what runs behind the scenes. Plug in your own hardware:

👉 Can You Run Gemma 4? — hardware checker

Or keep reading: the quantization decision guide covers what to actually do with the quant level the checker recommends — including when to reach for the official QAT build instead of a plain Q4_0.

References

G4A

Written by Gemma4All Editorial

Gemma4All is written and maintained by an independent developer who runs local models on their own hardware daily. No content farm, no ghostwriters — learn who's behind the site and how we calculate our numbers.

Keep reading