<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Chennarao Vemula</title>
    <description>The latest articles on DEV Community by Chennarao Vemula (@chennarao_vemula_aa375143).</description>
    <link>https://dev.to/chennarao_vemula_aa375143</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4078102%2Fa5c98642-6bc9-49f3-94ae-cd49e4a352e0.png</url>
      <title>DEV Community: Chennarao Vemula</title>
      <link>https://dev.to/chennarao_vemula_aa375143</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/chennarao_vemula_aa375143"/>
    <language>en</language>
    <item>
      <title>Local LLM on a 16GB Mac Mini: Replacing GitHub Copilot with Ollama + Qwen</title>
      <dc:creator>Chennarao Vemula</dc:creator>
      <pubDate>Fri, 14 Aug 2026 18:35:16 +0000</pubDate>
      <link>https://dev.to/chennarao_vemula_aa375143/local-llm-on-a-16gb-mac-mini-replacing-github-copilot-with-ollama-qwen-n47</link>
      <guid>https://dev.to/chennarao_vemula_aa375143/local-llm-on-a-16gb-mac-mini-replacing-github-copilot-with-ollama-qwen-n47</guid>
      <description>&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/6HlT4vkB-38"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;I kept paying a monthly subscription for a cloud coding assistant while a 16GB M4 Mac mini sat on my desk idling most of the day. So I ran the obvious experiment: &lt;strong&gt;can a 16GB Mac mini run a coding assistant entirely offline&lt;/strong&gt; — no code leaving the machine, no subscription — and is it actually usable for real work?&lt;/p&gt;

&lt;p&gt;Short answer: yes, with one hard constraint (RAM) and one soft one (context length). This article is the written version of the video above, with every command, config file, and benchmark number so you can reproduce it.&lt;/p&gt;




&lt;h2&gt;
  
  
  Table of contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Why bother running locally&lt;/li&gt;
&lt;li&gt;The hardware constraint nobody mentions&lt;/li&gt;
&lt;li&gt;Step 1: Install Ollama&lt;/li&gt;
&lt;li&gt;Step 2: Pick a model that fits in 16GB&lt;/li&gt;
&lt;li&gt;Step 3: Run and verify&lt;/li&gt;
&lt;li&gt;Step 4: Wire it into VS Code&lt;/li&gt;
&lt;li&gt;Step 5: Tune Ollama for a 16GB box&lt;/li&gt;
&lt;li&gt;Measuring it on your own machine&lt;/li&gt;
&lt;li&gt;What it does well, what it doesn't&lt;/li&gt;
&lt;li&gt;Should you cancel Copilot?&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Why bother running locally
&lt;/h2&gt;

&lt;p&gt;Three reasons, in the order that actually mattered to me:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Privacy.&lt;/strong&gt; Client code, internal repos, anything under NDA — none of it leaves the machine. This is the one thing a hosted assistant cannot offer you at any price tier.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost.&lt;/strong&gt; A coding assistant subscription is roughly $100–240/yr depending on tier. The Mac mini was already bought.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Offline.&lt;/strong&gt; Flights, bad hotel wifi, coffee shop dead zones. The assistant just works.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The reason &lt;em&gt;not&lt;/em&gt; to: raw capability. The frontier hosted models are better at large multi-file reasoning, and it isn't close. More on that below.&lt;/p&gt;




&lt;h2&gt;
  
  
  The hardware constraint nobody mentions
&lt;/h2&gt;

&lt;p&gt;On Apple Silicon, the GPU and CPU share one pool of unified memory. A model has to fit in that pool &lt;strong&gt;alongside macOS, your browser, VS Code, and whatever containers you're running&lt;/strong&gt;. On a 16GB machine, macOS + a normal dev environment eats 6–8GB before you've loaded anything.&lt;/p&gt;

&lt;p&gt;That leaves you roughly &lt;strong&gt;7–9GB of realistic headroom&lt;/strong&gt; for the model. This single number determines everything else, and it's why "just run the 30B model" advice from people on 64GB machines doesn't transfer.&lt;/p&gt;

&lt;p&gt;By default macOS allows the GPU to use about 75% of total RAM as VRAM. You can check what you're actually working with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# total RAM in bytes&lt;/span&gt;
sysctl hw.memsize

&lt;span class="c"&gt;# current memory pressure — the number that actually matters&lt;/span&gt;
memory_pressure | &lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-5&lt;/span&gt;

&lt;span class="c"&gt;# what's using it&lt;/span&gt;
top &lt;span class="nt"&gt;-o&lt;/span&gt; MEM &lt;span class="nt"&gt;-n&lt;/span&gt; 10 &lt;span class="nt"&gt;-l&lt;/span&gt; 1 | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-20&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 1: Install Ollama
&lt;/h2&gt;

&lt;p&gt;Two options. Homebrew is easier to script and update:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--cask&lt;/span&gt; ollama
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or download the app directly from &lt;a href="https://ollama.com/" rel="noopener noreferrer"&gt;ollama.com&lt;/a&gt;. Either way, verify the daemon is up:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ollama &lt;span class="nt"&gt;--version&lt;/span&gt;
curl &lt;span class="nt"&gt;-s&lt;/span&gt; http://localhost:11434/api/tags | &lt;span class="nb"&gt;head&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If that &lt;code&gt;curl&lt;/code&gt; returns JSON, the local API server is live on port &lt;code&gt;11434&lt;/code&gt;. That endpoint is what VS Code will talk to — it is OpenAI-API-compatible enough for most tooling.&lt;/p&gt;

&lt;p&gt;If it isn't running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# start the server in the foreground to see logs&lt;/span&gt;
ollama serve
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;LM Studio alternative:&lt;/strong&gt; if you'd rather have a GUI with a model browser and a built-in chat window, LM Studio does the same job and also exposes an OpenAI-compatible server (default port &lt;code&gt;1234&lt;/code&gt;). Everything below works with either — swap the &lt;code&gt;apiBase&lt;/code&gt; port.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Step 2: Pick a model that fits in 16GB
&lt;/h2&gt;

&lt;p&gt;This is where most local-LLM writeups go wrong. Here's the actual size on disk (and roughly in memory) for the Qwen coder family:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Model&lt;/th&gt;
&lt;th&gt;Download size&lt;/th&gt;
&lt;th&gt;Fits in 16GB?&lt;/th&gt;
&lt;th&gt;Use it for&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;qwen2.5-coder:1.5b&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;986 MB&lt;/td&gt;
&lt;td&gt;✅ Trivially&lt;/td&gt;
&lt;td&gt;Autocomplete only&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;qwen2.5-coder:3b&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;1.9 GB&lt;/td&gt;
&lt;td&gt;✅ Easily&lt;/td&gt;
&lt;td&gt;Autocomplete, light chat&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;qwen2.5-coder:7b&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;4.7 GB&lt;/td&gt;
&lt;td&gt;✅ &lt;strong&gt;Sweet spot&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Chat + edit + autocomplete&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;qwen2.5-coder:14b&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;9.0 GB&lt;/td&gt;
&lt;td&gt;⚠️ Tight — close other apps&lt;/td&gt;
&lt;td&gt;Best quality you can get&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;qwen2.5-coder:32b&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;20 GB&lt;/td&gt;
&lt;td&gt;❌ No&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;qwen3-coder:30b&lt;/code&gt; (a3b)&lt;/td&gt;
&lt;td&gt;19 GB&lt;/td&gt;
&lt;td&gt;❌ No&lt;/td&gt;
&lt;td&gt;Needs 32GB+&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;The 16GB recommendation: &lt;code&gt;qwen2.5-coder:7b&lt;/code&gt; for chat and edits, &lt;code&gt;qwen2.5-coder:1.5b&lt;/code&gt; for inline autocomplete.&lt;/strong&gt; Running a small dedicated autocomplete model alongside the bigger chat model is the trick that makes the whole thing feel responsive — autocomplete needs to answer in milliseconds, and a 7B can't.&lt;/p&gt;

&lt;p&gt;Pull them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ollama pull qwen2.5-coder:7b
ollama pull qwen2.5-coder:1.5b

&lt;span class="c"&gt;# optional: embeddings for codebase indexing&lt;/span&gt;
ollama pull nomic-embed-text

ollama list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you have the RAM headroom and want to try 14B, pull an explicit quantization rather than the default — &lt;code&gt;q4_K_M&lt;/code&gt; is the best quality-per-gigabyte tradeoff:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ollama pull qwen2.5-coder:14b-instruct-q4_K_M
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 3: Run and verify
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ollama run qwen2.5-coder:7b
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, to see actual timings instead of vibes, use verbose mode:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ollama run &lt;span class="nt"&gt;--verbose&lt;/span&gt; qwen2.5-coder:7b &lt;span class="s2"&gt;"Write a Python function that parses an ISO 8601 duration string into seconds. Include edge cases."&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;--verbose&lt;/code&gt; prints &lt;code&gt;total duration&lt;/code&gt;, &lt;code&gt;prompt eval rate&lt;/code&gt;, and &lt;code&gt;eval rate&lt;/code&gt; (tokens/sec) after every response. That's your benchmark instrument — no extra tooling needed.&lt;/p&gt;

&lt;p&gt;While it's generating, watch memory in another terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ollama ps        &lt;span class="c"&gt;# shows loaded models, size, and CPU/GPU split&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;PROCESSOR&lt;/code&gt; column in &lt;code&gt;ollama ps&lt;/code&gt; should say &lt;code&gt;100% GPU&lt;/code&gt;. If it says anything with &lt;code&gt;CPU&lt;/code&gt;, the model spilled out of unified memory and your tokens/sec just fell off a cliff — drop to a smaller model or quantization.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 4: Wire it into VS Code
&lt;/h2&gt;

&lt;p&gt;Install the &lt;a href="https://marketplace.visualstudio.com/items?itemName=Continue.continue" rel="noopener noreferrer"&gt;Continue&lt;/a&gt; extension, then edit &lt;code&gt;~/.continue/config.yaml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Local Mac Mini Config&lt;/span&gt;
&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;0.0.1&lt;/span&gt;
&lt;span class="na"&gt;schema&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;

&lt;span class="na"&gt;models&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Qwen2.5 Coder 7B&lt;/span&gt;
    &lt;span class="na"&gt;provider&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ollama&lt;/span&gt;
    &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;qwen2.5-coder:7b&lt;/span&gt;
    &lt;span class="na"&gt;apiBase&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http://localhost:11434&lt;/span&gt;
    &lt;span class="na"&gt;roles&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;chat&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;edit&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;apply&lt;/span&gt;
    &lt;span class="na"&gt;defaultCompletionOptions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;contextLength&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8192&lt;/span&gt;
      &lt;span class="na"&gt;maxTokens&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2048&lt;/span&gt;

  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Qwen2.5 Coder 1.5B (autocomplete)&lt;/span&gt;
    &lt;span class="na"&gt;provider&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ollama&lt;/span&gt;
    &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;qwen2.5-coder:1.5b&lt;/span&gt;
    &lt;span class="na"&gt;apiBase&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http://localhost:11434&lt;/span&gt;
    &lt;span class="na"&gt;roles&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;autocomplete&lt;/span&gt;
    &lt;span class="na"&gt;defaultCompletionOptions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;contextLength&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2048&lt;/span&gt;
      &lt;span class="na"&gt;maxTokens&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;256&lt;/span&gt;

  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Nomic Embed&lt;/span&gt;
    &lt;span class="na"&gt;provider&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ollama&lt;/span&gt;
    &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nomic-embed-text&lt;/span&gt;
    &lt;span class="na"&gt;roles&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;embed&lt;/span&gt;

&lt;span class="na"&gt;context&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;provider&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;code&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;provider&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;diff&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;provider&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;terminal&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;provider&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;currentFile&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two things worth calling out:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;model:&lt;/code&gt; must match &lt;code&gt;ollama list&lt;/code&gt; exactly.&lt;/strong&gt; A tag mismatch fails silently with an empty response, which is a miserable 20 minutes of debugging.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;contextLength: 8192&lt;/code&gt;&lt;/strong&gt; is deliberate. Qwen2.5-Coder supports 32K, but on 16GB the KV cache for a 32K context costs you more memory than the model weights saved you. 8K covers a file and its imports, which is what a local assistant is realistically good at anyway.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Restart VS Code, open the Continue panel, and confirm the model dropdown shows your local models. Inline autocomplete should start firing as you type.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 5: Tune Ollama for a 16GB box
&lt;/h2&gt;

&lt;p&gt;Three environment variables do most of the work. Set them where Ollama can see them — if you run the app, use &lt;code&gt;launchctl&lt;/code&gt;; if you run &lt;code&gt;ollama serve&lt;/code&gt; yourself, put them in your shell profile.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# keep the model resident so you don't pay reload cost on every request&lt;/span&gt;
launchctl setenv OLLAMA_KEEP_ALIVE &lt;span class="s2"&gt;"30m"&lt;/span&gt;

&lt;span class="c"&gt;# only one model in memory at a time — critical on 16GB&lt;/span&gt;
launchctl setenv OLLAMA_MAX_LOADED_MODELS &lt;span class="s2"&gt;"1"&lt;/span&gt;

&lt;span class="c"&gt;# don't let concurrent requests multiply your memory footprint&lt;/span&gt;
launchctl setenv OLLAMA_NUM_PARALLEL &lt;span class="s2"&gt;"1"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then restart Ollama for them to take effect.&lt;/p&gt;

&lt;p&gt;The counterintuitive one is &lt;code&gt;OLLAMA_MAX_LOADED_MODELS=1&lt;/code&gt;. It seems to fight the two-model setup from Step 4 — and it does mean a swap when you jump between chat and autocomplete. But on 16GB, having both a 7B and a 1.5B resident &lt;em&gt;plus&lt;/em&gt; a browser open is what pushes you into swap, and swap on a local LLM is catastrophic, not slow. If you have the headroom (nothing else open), set it to &lt;code&gt;2&lt;/code&gt; and enjoy the snappier switching.&lt;/p&gt;

&lt;p&gt;If you want to reclaim memory immediately:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ollama stop qwen2.5-coder:7b
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Measuring it on your own machine
&lt;/h2&gt;

&lt;p&gt;I'm deliberately not handing you a table of my numbers. Throughput on Apple Silicon swings with macOS version, thermal state, and whatever else is resident in unified memory — a benchmark from someone else's Mac mini tells you almost nothing about yours. Here's the two-minute version that gives you real figures:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="k"&gt;for &lt;/span&gt;m &lt;span class="k"&gt;in &lt;/span&gt;qwen2.5-coder:1.5b qwen2.5-coder:3b qwen2.5-coder:7b&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== &lt;/span&gt;&lt;span class="nv"&gt;$m&lt;/span&gt;&lt;span class="s2"&gt; ==="&lt;/span&gt;
  ollama run &lt;span class="nt"&gt;--verbose&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$m&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\\&lt;/span&gt;
    &lt;span class="s2"&gt;"Write a Python function that retries an HTTP request with exponential backoff. Include type hints and docstring."&lt;/span&gt; &lt;span class="se"&gt;\\&lt;/span&gt;
    2&amp;gt;&amp;amp;1 | &lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-8&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The number to read is &lt;strong&gt;&lt;code&gt;eval rate&lt;/code&gt;&lt;/strong&gt; (tokens/sec). &lt;code&gt;prompt eval rate&lt;/code&gt; matters less for interactive coding — it's how fast it ingests your file, and it's rarely the bottleneck at 8K context.&lt;/p&gt;

&lt;p&gt;Run it a few times and take the median; the first run of any model includes load time and will look worse than reality.&lt;/p&gt;

&lt;p&gt;Rules of thumb that held up across my runs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Above ~15 tok/s&lt;/strong&gt; — feels conversational. You read the output as it streams and stay in flow.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;8–15 tok/s&lt;/strong&gt; — usable, but you'll notice the wait on longer generations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Below ~8 tok/s&lt;/strong&gt; — you start context-switching to another window while it thinks, which defeats the entire point of having it inline.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And keep an eye on &lt;code&gt;ollama ps&lt;/code&gt; while it runs — if &lt;code&gt;PROCESSOR&lt;/code&gt; shows any CPU percentage, the model spilled out of unified memory and the numbers you're reading are meaningless. On 16GB that's the single most common reason people conclude "local models are too slow."&lt;/p&gt;




&lt;h2&gt;
  
  
  What it does well, what it doesn't
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Genuinely good at:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Single-function generation and refactors&lt;/li&gt;
&lt;li&gt;Boilerplate — tests, type hints, docstrings, config scaffolding&lt;/li&gt;
&lt;li&gt;"Explain this regex / this stack trace / this git diff"&lt;/li&gt;
&lt;li&gt;Renaming and mechanical edits across a file&lt;/li&gt;
&lt;li&gt;Anything you'd rather not paste into a hosted service&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Falls down on:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Multi-file reasoning. It doesn't hold your architecture in its head.&lt;/li&gt;
&lt;li&gt;Long context. You're on 8K by choice; hosted tools give you hundreds of thousands of tokens.&lt;/li&gt;
&lt;li&gt;Very recent library APIs — the training cutoff bites, and there's no web access.&lt;/li&gt;
&lt;li&gt;Agentic multi-step work. The 7B loses the thread.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The honest framing: a local 7B is roughly a competent junior who has read all the docs, works instantly, never leaks your code, and cannot see past the current file.&lt;/p&gt;




&lt;h2&gt;
  
  
  Should you cancel Copilot?
&lt;/h2&gt;

&lt;p&gt;Depends entirely on your work:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Mostly function-level work on code you'd rather keep private&lt;/strong&gt; → local wins on cost and comfort. Cancel.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Greenfield scaffolding across dozens of files, heavy agentic workflows&lt;/strong&gt; → you'll hit the ceiling in a week. Keep the subscription.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Most people&lt;/strong&gt; → run both. Local for the 80% of routine edits, hosted for the hard 20%. The subscription math still works out if you drop a tier.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I've been running this setup as my default and reaching for the cloud only when the local model visibly struggles. That split has held up.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;The full video walkthrough&lt;/strong&gt; — install, model runs, VS Code hookup, and the live coding tests — is at the top of this post, or here: &lt;a href="https://youtu.be/6HlT4vkB-38" rel="noopener noreferrer"&gt;Goodbye GitHub Copilot? Building a Local AI Lab on a 16GB Mac Mini&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Which model should I benchmark next on 16GB? Drop it in the comments — I'll run it.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>macos</category>
      <category>opensource</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
