Repository navigation
Description
Description
The OpenCode Desktop app (ai.opencode.desktop v1.14.29) downloads 25–145 MB from raw.githubusercontent.com every ~10 minutes, 24/7, while only writing a 1.9 MB local file (~/.cache/opencode/models.json). On a residential connection this is roughly 21 GB/day, ~630 GB/month of effectively wasted egress — mine, GitHub Pages/Fastly's, and my ISP's.
The pattern starts when the Desktop app is launched and stops when it is killed. Closing the app (no other config changes) made the rhythm vanish from my gateway chart within ~10 minutes.
I noticed this because the periodic load was visible as a clean 10-minute sine wave on my router's WAN throughput chart for the last few days. I traced it through packet captures and process inspection.
Evidence
1. Identified process and live connection
While the rhythm was active, lsof -nP -i 4 showed (PID + username redacted):
OpenCode <pid> <user> TCP 10.x.x.x:62092 -> 185.199.108.133:443 (ESTABLISHED)
The destination IP is in GitHub's documented Fastly range 185.199.108–111.x, which serves both GitHub Pages and raw.githubusercontent.com. DNS confirms raw.githubusercontent.com resolves to exactly that IP set.
2. Per-burst pcap (gateway WAN, 40-sec window)
Top conversations during one captured burst (post-NAT WAN view):
Local <-> Remote Bytes IN Time slice
192.168.1.1 <-> 185.199.110.154 25 MB t+30 -> t+40 sec
192.168.1.1 <-> 185.199.108.153 7 MB t+25 -> t+28 sec
Bytes/sec timeline showed the line idle (~10 KB/s) for ~25 sec, then sustained ~2.5 MB/s (≈20 Mbps) for 10+ seconds to those IPs. Pure download, ~309 Kbps reciprocal upload (TCP ACKs only). No other host on my LAN had any conversation with 185.199.108–111.x during the window — definitively the OpenCode Desktop process.
3. Per-cycle volume (gateway 5-min site WAN counters)
Bucket (UTC) WAN-RX MB
12:55 170.7
13:00 10.6 <- trough
13:05 145.0 <- peak
13:10 35.6
13:15 143.3
13:20 18.9
13:25 138.0
13:30 20.3
14:05 135.9
14:10 18.1
14:15 147.4
14:20 21.1
14:25 134.0
... (continues for 24+ hours unchanged)
Period: ~10 min. Peak buckets average ~140 MB. Trough buckets ~25 MB.
4. Disk artifact
Inside ~/.cache/opencode, the only file modified during the active period was:
~/.cache/opencode/models.json 1.9 MB
size = 1,884,486 bytes
mtime = May 6 16:12 local
birthtime = Apr 11 (when OpenCode was first launched)
All other ~6,991 files in the 84 MB cache directory had old mtimes (one-time downloads of LSP servers, language tooling, etc.). Only models.json is being refreshed periodically.
models.json contains the registry of 117 LLM provider entries (Anthropic, OpenAI, Alibaba, AWS Bedrock, Azure, Perplexity, Scaleway, Siliconflow, etc., each with id / env / npm / api / name / doc / models fields) — the upstream appears to be the models.dev registry, also maintained by anomalyco (anomalyco/models.dev).
This is worth highlighting because anomalyco controls both ends of this loop — both the producer (models.dev) and the consumer (opencode). The fix can land on either side or both.
5. models.dev already has cache-revalidation built in, but OpenCode is bypassing its own CDN
https://models.dev/api.json is Cloudflare-fronted and returns proper headers:
HTTP/2 200
content-type: application/json
cf-cache-status: HIT
cache-control: public, max-age=0, must-revalidate
etag: "8bfd6079fcad9656d242d5d1ee8be061"
That ETag + must-revalidate pair is exactly the contract designed for If-None-Match → 304 Not Modified flows. A client that sends a conditional request gets a few-hundred-byte revalidation response when nothing has changed, instead of the full 1.9 MB body.
But OpenCode is not hitting models.dev — the pcap and DNS lookup show it hitting raw.githubusercontent.com directly (Fastly IPs 185.199.108–111.x). That bypasses anomalyco's own Cloudflare-fronted CDN entirely and goes to GitHub's raw-file endpoint, which:
- is more expensive for GitHub/Fastly (no aggressive Cloudflare-side caching of mirrored content),
- still supports
If-None-Matchif the client sends it (raw.githubusercontent.com does returnETag), but apparently OpenCode isn't sending it, - and is generally discouraged for high-volume polling — there are GitHub docs cautioning against using raw URLs for production traffic at all.
6. The damning ratio
- Downloaded per cycle (peak): ~145 MB
- Persisted on disk: 1.9 MB
That's a ~76× amplification between bytes-on-the-wire and bytes-actually-kept. Plausible mechanisms:
- The app fetches per-provider blobs for all 117 providers and consolidates client-side into a single 1.9 MB digest, discarding the per-provider payloads.
- The app re-downloads the same content with no cache validation, getting
200 OKevery time instead of304 Not Modified. - The poll interval (10 min) is far more aggressive than the data could possibly need (the registry changes maybe once a day at most).
7. A/B confirmation
Closing the Desktop app (no config changes) caused the rhythm to vanish from the gateway chart within ~10 minutes. (Screenshots of the before/after gateway chart can be supplied on request.)
Why this matters
- Users: ~21 GB/day on residential connections — invisible bandwidth waste, and on metered/throttled connections (or struggling ISPs, or those using SQM that is forced to deprioritize this churn) it actively degrades other traffic.
- Project: GitHub Pages / Fastly egress is being burned on cache-miss responses that could trivially be
304 Not Modified. - GitHub: they are paying Fastly egress for this. Multiplied across the user base, it is non-trivial.
Suggested fixes (in rough order)
- Switch the fetch URL from
raw.githubusercontent.com/anomalyco/models.dev/...tohttps://models.dev/api.json(or whichever endpoint already exists on the Cloudflare-fronted host). That site is yours, has the right cache headers, and is the documented public API for the registry. - Honor HTTP cache validators. Send
If-Modified-Since/If-None-Matchon the periodic refresh; treat304as success. Withmodels.dev's ETag this would eliminate >99% of the bytes — and even on the currentraw.githubusercontent.compath it would help substantially. - Lengthen the poll interval. 10 minutes for a registry that changes daily-at-most is wildly aggressive. Hourly or daily would be plenty for the UX of "model list is fresh".
- Make the interval configurable in
opencode.json(something like"modelsRegistry": { "refreshInterval": "1h" }or"never"). Currently the config docs only document a startup-timeautoupdateflag with no equivalent for this background poll — the behavior is not documented at all. - Don't refetch unchanged per-provider blobs. If the consolidated registry's hash hasn't changed, skip per-provider fetches.
- Document the behavior in the config docs so users at least know it exists.
Plugins
None.
OpenCode version
Desktop bundle ai.opencode.desktop v1.14.29 (embedded CLI also 1.14.29). Standalone CLI installed via mise is v1.14.39 — I have not verified whether the same loop exists there.
Steps to reproduce
- Install OpenCode Desktop on macOS (
/Applications/OpenCode.app,ai.opencode.desktopv1.14.29). - Open it and leave it running. No other interaction needed.
- Observe WAN throughput on a network monitor (e.g. UniFi).
A near-perfect 10-minute periodic envelope appears, peaking at ~4 Mbps averaged across 5-min buckets (≈20 Mbps line-rate during the actual ~10-second burst), continuing 24 hours per day for as long as the app is running.
Screenshot and/or share link
Screenshots of the WAN throughput chart showing the periodic envelope (and the same chart flattening after I quit the app) can be attached on request — they come from a gateway dashboard with some private info I haven't yet cropped out.
A 40-sec gateway WAN pcap during one full burst is also available on request.
Operating System
macOS 26.3.1 (Tahoe), Apple Silicon
Terminal
Ghostty (incidental — the bug is in the Desktop app, not a terminal session)
Activity
github-actions commentedon May 6, 2026
This issue doesn't fully meet our contributing guidelines.
What needs to be fixed:
Please edit this issue to address the above within 2 hours, or it will be automatically closed.
If you believe this was flagged incorrectly, please let a maintainer know.
github-actions commentedon Jul 8, 2026
To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.