Skip to content

[OpenCode Go] GLM-5.2 prompt cache randomly drops to ~500 tokens on opencode-go (opencode.ai/zen/go) #33998

Closed as not planned

Description

@LittleNightmare

Description

Summary

GLM-5.2 via opencode-go gateway (opencode.ai/zen/go/v1/chat/completions) experiences intermittent prompt cache drops to ~500 cached_tokens, even when the system prompt is completely stable (verified byte-identical across 36 API calls). This happens with gaps as short as 2 minutes — well within the gateway's ~5 min TTL. DeepSeek V4 Flash on the same gateway does NOT exhibit this issue.

Environment

  • OpenCode: latest
  • Model: glm-5.2 via opencode-go (opencode.ai/zen/go)
  • OS: Windows 11
  • Terminal: Windows Terminal / Git Bash
  • OPENCODE_EXPERIMENTAL_CACHE_STABILIZATION=1 (enabled)
  • opencode.jsonc: static routing headers set for glm-5.2 model (x-session-id, conversation_id, session_id)

Evidence

System prompt stability (verified via request body logging)

All 36 GLM-5.2 API calls in a single session had an IDENTICAL system prompt of 80,085 characters. Zero changes after initialization. The prefix should be perfectly cacheable.

Cache drops observed

Time (UTC) Gap since last call Duration Status
13:39:22 (init) 2251ms baseline
13:44:23 3.9 min 1276ms -
13:47:59 1.6 min 1184ms -
13:50:07 2.1 min 990ms cached_tokens ~500
13:52:14 2.0 min 1409ms -
13:56:13 3.1 min 1021ms -
14:16:12 18.4 min 2600ms definite cache eviction

The drop at 13:50:07 occurred after only 2.1 minutes of idle time — the system prompt was unchanged, the tools were unchanged (63 tools, identical across all calls), and there were zero mid-session system prompt mutations.

Response headers (captured via custom plugin)

All GLM-5.2 responses from opencode-go return:

  • cache-control: no-store
  • No x-cache-status, no x-cache-hits, no age header
  • Headers: cf-ray, cf-placement, cache-control, connection, content-type, date, server, transfer-encoding

No cache telemetry is exposed in response headers, making diagnosis dependent on streaming body usage stats.

Contrast: DeepSeek V4 Flash (direct API, not opencode-go)

DeepSeek V4 Flash going directly to api.deepseek.com maintained stable cache across 142 consecutive calls with zero system prompt mutations. Response headers included eo-cache-status (EdgeOne CDN cache status) and age headers.

Configuration attempts that failed

Both promptCacheKey (model-level options) and setCacheKey: true (provider-level options) cause opencode-go to reject the request:

Plugins

opencode-wakatime@latest
@slkiser/opencode-quota
oh-my-openagent@latest
@codenomad/codenomad-opencode-plugin
./plugin/opencode-request-logger
./plugins/session-id-header.js
./plugins/fixed-prompt-cache-key.js
./plugins/start-work-placeholder-fix.js
./plugins/debug-provider.js

Note: session-id-header.js and fixed-prompt-cache-key.js inject routing headers
and promptCacheKey for @ai-sdk/openai providers, but opencode-go is a built-in
provider and these plugins do not apply to it. This was verified experimentally:
both promptCacheKey (model-level) and setCacheKey (provider-level) are rejected
by opencode-go's GLM endpoint as unsupported fields.

OpenCode version

1.17.9

Steps to reproduce

  1. Connect to opencode-go via /connect
  2. Select glm-5.2 model
  3. Run a multi-turn agent session with tool calls (e.g., file editing, git operations)
  4. Observe cached_tokens in streaming usage stats — it will intermittently drop to ~500
    even when system prompt hasn't changed and gap between calls is < 3 minutes
  5. Compare with DeepSeek V4 Flash on the same workload — cache remains stable

Screenshot and/or share link

No response

Operating System

Windows 11

Terminal

Windows Terminal (Git Bash)+CodeNomad

Activity

  1. rekram1-node commented on Jun 27, 2026

    @rekram1-node
    Contributor

    plz provide the session id so we can track it down, good chance that it got routed between multiple providers behind the scenes on acciident or soemthing

  2. LittleNightmare commented on Jun 27, 2026

    @LittleNightmare
    Author

    plz provide the session id so we can track it down, good chance that it got routed between multiple providers behind the scenes on acciident or soemthing

    The session where the cache drops were observed:
    ses_100fe7189ffePiB0hx1bgwZcYJ

    The previous GLM session where we first noticed the issue
    (system prompt grew mid-session due to skill discovery):
    ses_1071482eaffejgwViYRKXMw3Pv

    Both used glm-5.2 via opencode-go (opencode.ai/zen/go/v1/chat/completions).
    I have full request body logs for both if you need specific timestamps or data.

  3. MiunaQwQ commented on Jun 29, 2026

    @MiunaQwQ

    I’m seeing a very similar issue with GLM-5.2 on OpenCode Go, but in my case the cache sometimes drops almost completely to 0 or 64 cached tokens.

    Pricing used:

    • Input: $1.40 / M tokens
    • Output: $4.40 / M tokens
    • Cached read: $0.26 / M tokens

    Observed logs:

    Request UTC time Input tokens Cached read tokens Output tokens Reasoning tokens Cost
    1 2026-06-29 19:21 UTC 111300 0 1931 0 $0.1643
    2 2026-06-29 19:21 UTC 2515 111232 1478 0 $0.0389
    3 2026-06-29 19:21 UTC 115741 0 177 0 $0.1628
    4 2026-06-29 19:22 UTC 115926 0 806 0 $0.1658
    5 2026-06-29 19:22 UTC 116738 0 513 0 $0.1657
    6 2026-06-29 19:22 UTC 117751 64 146 0 $0.1655
    7 2026-06-29 19:22 UTC 2946 115200 203 0 $0.0350

    The key point is that request 2 and request 7 both show normal cache hits, with around 111k–115k cached tokens. However, the requests in between suddenly drop to 0 or 64 cached tokens.

    This happened within roughly one minute, from 2026-06-29 19:21 UTC to 2026-06-29 19:22 UTC, so it does not look like a normal cache TTL expiration.

    It also does not look like the prompt is inherently uncacheable. The cache can work and then recover later in the same session, but it intermittently fails for several turns.

    Cost impact:

    • Actual cost of the 4 abnormal turns: about $0.6599
    • Estimated cost if cache had stayed stable: about $0.1408
    • Extra cost: about $0.5191
    • Cost increase on affected turns: about 4.69x

    Excluding the initial cold request:

    • Actual cost: about $0.7338
    • Expected cost with stable cache: about $0.2147
    • Overall increase after warmup: about 3.42x

    This seems consistent with the issue described here, but the impact is even more severe in this case because cached tokens sometimes drop from ~115k to almost 0.

  4. rekram1-node commented on Jun 29, 2026

    @rekram1-node
    Contributor

    r u using any plugins? Is this in normal vanilla opencode?

  5. MiunaQwQ commented on Jun 29, 2026

    @MiunaQwQ

    r u using any plugins? Is this in normal vanilla opencode?

    Yes, I’m using the oh-my-openagent plugin.

    I have not tested this with completely vanilla opencode yet. However, with the same OpenCode Go gateway and the same general setup, deepseek-v4-flash and deepseek-v4-pro have normal cache behavior on my side.

    So my guess is that this issue is probably not caused by the plugin. If it were plugin-related, I would expect similar cache drops with the DeepSeek models through the same gateway as well, but I’m only seeing this behavior with glm-5.2 so far.

    I have not tested whether glm-5.1 or glm-5 have the same issue myself, but I noticed another issue mentioning similar cache behavior with glm-5.1, so my guess is that this may affect the GLM model family more broadly.

  6. MiunaQwQ commented on Jun 29, 2026

    @MiunaQwQ

    I’m adding two more screenshots from my New API gateway logs for easier comparison.

    The first screenshot is glm-5.2. It shows multiple requests where the cache line is missing, which means there were no cached read tokens reported for those requests. There is also one request where the cache read is only 64 tokens, even though nearby requests are around 67k–68k input tokens.

    The second screenshot is deepseek-v4-pro through the same New API gateway. In contrast, cache reads look stable there, with most requests showing cached tokens close to the input size.

    So this still looks more like a GLM-specific cache issue rather than a general plugin or gateway issue, because DeepSeek models through the same New API gateway appear to cache normally.

    Image Image
  7. Marvinthebored commented on Jul 5, 2026

    @Marvinthebored

    Root-caused this in #35402 (GLM-5.2, same symptom, byte-identical replay repro): the Zen gateway's per-model stickyProvider setting isn't enabled for the GLM models, so selectProvider re-resolves the upstream as the provider pool's live state (budget/TPS/failure filters) changes — same sticky id, different provider, cold cache. The sticky mechanism already exists in the gateway (createStickyTracker + the x-opencode-session header) and ships enabled for codex models; the ask in #35402 is to enable "prefer" for multi-sourced models like GLM. Repro script + gateway source analysis over there.

  8. wakefun commented on Jul 6, 2026

    @wakefun

    well within the gateway's ~5 min TTL

    To diverge a bit, I want to ask about the 5-minute TTL—where is this duration mentioned? I haven't found any explanation about TTL in the opencode documentation.

  9. LittleNightmare commented on Jul 12, 2026

    @LittleNightmare
    Author

    well within the gateway's ~5 min TTL

    To diverge a bit, I want to ask about the 5-minute TTL—where is this duration mentioned? I haven't found any explanation about TTL in the opencode documentation.

    The ~5 min TTL mentioned in the report is from pi-opencode-go-cache's README

  10. woohahahaaa commented on Jul 17, 2026

    @woohahahaaa

    +1, same issue — OpenCode Go + GLM-5.2 cache drops mid-session, today (2026-07-18)

    Confirming this is reproducible on opencode-go (opencode.ai/zen/go/v1) with glm-5.2. Within a single multi-turn session, cached_tokens intermittently drops even though the system prompt is byte-identical between turns. Input tokens consistently around ~70,000 per call, same order of magnitude as your 80,085 example.

    What I'm seeing

    Two screenshots from opencode.ai/workspace/... usage history, session yg0AIDMD, all on 2026-07-17:

    Time Input Output Cost (USD) Cache read (tooltip)
    11:51 70,093 43 $0.0983 (inferred 0 — full price at near-identical input to next row)
    11:52 70,130 1,275 $0.1038 0 ← drop (tooltip)

    Two consecutive calls, 1 minute apart, near-identical input (~70K), both showing cache=0. The second request at 11:52 (only 1 min after 11:51, well under the ~5 min TTL) should have hit on the prefix but didn't — the cache is being dropped between requests inside the TTL window.

    (I have additional screenshots from earlier in the session around 11:11–11:20, but those rows are separated by 30+ minutes from the 11:51 cluster, so the cache expiry there is expected TTL behavior — not reporting them as the bug.)

    When it started

    Previously stable (cache hits near 99%). Started dropping today (2026-07-18) within the last ~24 hours. Coincides with the recent OpenCode release train (v1.17.17 / v1.17.18) and possible OpenCode Go backend re-routing.

    Configuration

    • OpenCode: latest (upgraded over the last few days)
    • Provider: opencode-go (built-in, authenticated via OPENCODE_API_KEY)
    • Model: glm-5.2
    • No OMO / oh-my-opencode, no multi-agent switching
    • No model switch, no Plan↔Build mode toggle, no compaction mid-session
    • Single short session (calls minutes apart)

    Agreements with @LittleNightmare's findings

    • Same OpenCode Go + GLM-5.2 pattern
    • Cache drops within the TTL window (in our case 1 min, well under 5 min)
    • System prompt unchanged across the dropped turns
    • DeepSeek V4 Flash on the same opencode-go provider presumably keeps cache stable (matches your contrast case)
    • cache-control: no-store and no x-cache-* headers in OpenCode Go responses — no telemetry to diagnose from the client side

    Reference: OpenCode's own baseline

    opencode.ai/docs/zh-cn/go says GLM-5.2/5.1 typical pattern is "700 input tokens, 52,000 cached tokens per request" → ~98.7% expected hit rate. Currently seeing much lower than this on the same provider.

  11. github-actions commented on Sep 17, 2026

    @github-actions
    Contributor

    To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions