Skip to content

Feature Request: Configurable context limit and auto-compaction threshold #8140

Closed as not planned

Description

@LeekJay

Problem

Currently:

  1. Auto-compaction only triggers when the context is nearly full (count > context - output)
  2. Context limit is determined by the model and cannot be customized

For users who want to optimize costs, there's no way to:

  • Trigger compaction earlier
  • Limit the maximum context usage (e.g., use only 100k of a 200k model)

Proposed Solution

Add configurable options for context management:

{
  "compaction": {
    "auto": true,
    "prune": true,
    "threshold": 0.7,
    "maxContext": 100000
  }
}
  • threshold: A percentage (0.0 - 1.0) of the context limit at which auto-compaction should trigger. Default: 1.0 (current behavior)
  • maxContext: Maximum context tokens to use, overriding the model's default limit. Default: model's context limit

Implementation Suggestion

In compaction.ts, modify the isOverflow function:

export async function isOverflow(input: { tokens: MessageV2.Assistant["tokens"]; model: Provider.Model }) {
  const config = await Config.get()
  if (config.compaction?.auto === false) return false
  
  // Allow user to override model's context limit
  const modelContext = input.model.limit.context
  const maxContext = config.compaction?.maxContext ?? modelContext
  const context = Math.min(modelContext, maxContext)
  
  if (context === 0) return false
  const count = input.tokens.input + input.tokens.cache.read + input.tokens.output
  const output = Math.min(input.model.limit.output, SessionPrompt.OUTPUT_TOKEN_MAX) || SessionPrompt.OUTPUT_TOKEN_MAX
  
  // Apply threshold (default to 1.0 for backward compatibility)
  const threshold = config.compaction?.threshold ?? 1.0
  const usable = (context * threshold) - output
  
  return count > usable
}

Use Cases

  • Cost optimization: Limit context to 100k even when using a 200k model
  • Earlier compaction: Trigger compaction at 60-80% context usage
  • Predictable behavior: Avoid hitting context limits unexpectedly
  • Budget control: Prevent unexpectedly large API bills from long sessions

Activity

  1. changed the title [-]Feature Request: Configurable auto-compaction threshold to trigger earlier compression[/-] [+]Feature Request: Configurable context limit and auto-compaction threshold[/+] on Jan 13, 2026
  2. github-actions commented on Jan 13, 2026

    @github-actions
    Contributor

    This issue might be a duplicate of existing issues. Please check:

    This existing issue reports that auto-compaction is not triggering as expected, which is directly related to your feature request for configurable context limits and auto-compaction thresholds.

    Feel free to ignore if this doesn't address your specific case.

  3. V4G4X commented on Jan 15, 2026

    @V4G4X

    I'd very much like this feature.

    A lot of research points to LLMs suffering from "context rot". I'll just link this one.

    As such, I keep a practice to aggressively compact when I reach 40-50% context.
    Would be nice to set this threshold to 60%, so I have to interrupt it less.

  4. husamettinarabaci commented on Jan 29, 2026

    @husamettinarabaci

    +1 for this feature!

    As a developer running OpenCode locally with my own API keys and compute resources, being able to configure the token budget would be extremely valuable. The current hard-coded 200k limit feels arbitrary when I have higher quotas available from my provider.

    This aligns well with OpenCode's philosophy of flexibility and user control. Configuration options like environment variable (OPENCODE_TOKEN_BUDGET) or config file setting would be ideal.

  5. zxsleebu commented on Feb 7, 2026

    @zxsleebu

    +1 would be nice to have, because it would save so much money and give a big boost to llm performance

  6. FN-FAL113 commented on Feb 16, 2026

    @FN-FAL113

    +1, auto compaction should be triggered with a configurable context limit.

  7. farukg commented on Feb 16, 2026

    @farukg

    Strong +1. Related workaround I'm using today:

    1. compaction.reserved: 60000 — triggers compaction ~60K tokens earlier than default (20K). Not a percentage threshold but achieves a similar "compact before things get desperate" effect.

    2. Convention-based markers — the build agent marks its output with [persist] (decisions, discoveries) and [ephemeral] (intermediate search results, raw tool output). The compaction agent's custom prompt (agent.compaction.prompt) is instructed to preserve [persist] content verbatim and drop [ephemeral] content.

    3. Custom compaction prompt — Sigma-aware template with structured sections (Goal, Key Decisions, Accomplished, Discoveries, Modified Files, Active Context, Next Steps) instead of the default generic summary.

    This works reasonably well but a native threshold: 0.6 config would eliminate the reserved-buffer hack. The reserved buffer is a fixed token count, not proportional to the model's context — so it works differently on 200K vs 1M context models.

  8. urroxyz commented on Feb 17, 2026

    @urroxyz

    DCP is also a good plugin for saving context. I've found it really useful.

  9. V4G4X commented on Feb 19, 2026

    @V4G4X

    DCP is also a good plugin for saving context. I've found it really useful.

    Your link says "pruningg" at the end instead of "pruning" btw

  10. chindris-mihai-alexandru commented on Feb 22, 2026

    @chindris-mihai-alexandru

    Running long sessions on free models like moonshotai/kimi-k2.5 or openrouter/nvidia/nemotron-3-nano-30b-a3b revealed another variant of this problem: compaction always reserves 32K completion tokens, so even if the input is ~230K tokens the agent still asks for 32K output. For Kimi’s 262,144 window that causes an immediate overflow and the run fails unless I restart OpenCode with --max-output or set OPENCODE_MAX_OUTPUT globally.

    Could the proposed config also allow overriding the completion budget? Something like:

    {
      "compaction": {
        "threshold": 0.7,
        "maxContext": 180000,
        "maxOutput": 12000
      }
    }

    That would let us keep large-context models usable without exporting env vars or restarting the CLI when we temporarily swap compaction models.

  11. absurdly-nerdly commented on Feb 25, 2026

    @absurdly-nerdly

    Please add this, must be per-model. Until then we must use Claudish or Kilocode for anything but small/granular tasks.

  12. MartinEmrich commented on Mar 7, 2026

    @MartinEmrich

    I notice a possibly related phenomenon. I use OpenCode with self-hosted LLM on a local GPU, so every MB of VRAM counts. While I have configured both llama-server as well as OpenCode to 64k tokens, but I notice it very often autocompacting at 33-45 tokens, making no use of the remaining capacity.
    Might relate to what @chindris-mihai-alexandru describes above?

    My current "workaround" is to "overprovision", i.e. configuring OpenCode for e.g. 75-90k tokens, and, if I get close to the actual 64k, compact manually. If this is something different, I happily open a new issue!

  13. lucad87 commented on Mar 16, 2026

    @lucad87

    +1

  14. MartinEmrich commented on Mar 16, 2026

    @MartinEmrich

    Solved the issue for me:

    I ran opencode in opencode to ask opencode about opencode... and found a solution for my issue: Seems like cloud models often have separate input and output limits. Also opencode keeps a reserve for compaction of 32k tokens, which is quite high, and by default assumes the output token limit applies to this.
    For local models (what I use) that does not apply. The (AI-generated!) recommendation was to set the input limit explicitly to the same as the whole context limit, and to reduce the 32k token reserve for compaction.

    On the model:

             "limit": {
                "context": 65536,
                "input": 65536,
                "output": 8192
              }
    

    Global compaction config (sadly not configurable per model) with only 8k reserved:

      "compaction": {
        "auto": true,
        "prune": true,
        "reserved": 8192
      },
    

    With that, I can regularly get over 60 of 64k token context before auto-compacting.

  15. Onechan commented on Mar 17, 2026

    @Onechan

    This is a real problem. Unbounded context means unbounded cost, and relying on near-full compaction is basically no control at all. We built nornr.com to let agents request a mandate before spending, so you can enforce budget caps at the policy layer rather than hoping the model config is right. Would pair well with what you're proposing here.

  16. jyrkive commented on Mar 30, 2026

    @jyrkive

    Some models (such as DeepSeek) charge for cached input tokens, and the amount of those scales quadratically with maximum context size. Ability to lower the compaction threshold would be welcome.

  17. mikhail-shevtsov-wiregate commented on Apr 4, 2026

    @mikhail-shevtsov-wiregate

    Solved the issue for me:

    I ran opencode in opencode to ask opencode about opencode... and found a solution for my issue: Seems like cloud models often have separate input and output limits. Also opencode keeps a reserve for compaction of 32k tokens, which is quite high, and by default assumes the output token limit applies to this. For local models (what I use) that does not apply. The (AI-generated!) recommendation was to set the input limit explicitly to the same as the whole context limit, and to reduce the 32k token reserve for compaction.

    On the model:

             "limit": {
                "context": 65536,
                "input": 65536,
                "output": 8192
              }
    

    Global compaction config (sadly not configurable per model) with only 8k reserved:

      "compaction": {
        "auto": true,
        "prune": true,
        "reserved": 8192
      },
    

    With that, I can regularly get over 60 of 64k token context before auto-compacting.

    I suspect AI was referring to this section:

    const reserved =
    input.cfg.compaction?.reserved ?? Math.min(COMPACTION_BUFFER, ProviderTransform.maxOutputTokens(input.model))

    I've tried that but for some reason it still doesn't work for me and it still uses 20k as reserved for OpenAI compatible API.

    @MartinEmrich can you please share your full config?

  18. MartinEmrich commented on Apr 7, 2026

    @MartinEmrich

    Sure, cleaned it up a bit, but should make clear what goes where:

    {
      "$schema": "https://opencode.ai/config.json",
      "disabled_providers": ["opencode"],
      "enabled_providers": ["openai-compatible", "local", "homeserver"],
      "formatter": false,
      "compaction": {
        "auto": true,
        "prune": true,
        "reserved": 8192
      },
      "provider": {
        "homeserver": {
          "npm": "@ai-sdk/openai-compatible",
          "name": "llama-server home",
          "options": {
            "baseURL": "http://homeserver:8012/v1"
          },
          "models": {
            "qwen35-27b-large": {
              "name": "Qwen3.5 (home, 72k)",
              "id": "qwen/Qwen3.5-27b",
              "modalities": { "input": ["text", "image"], "output": ["text"] },
              "limit": {
                "context": 73728,
                "input": 73728,
                "output": 8192
              }
            },
            "qwen35-27b-medium": {
              "name": "Qwen3.5 (home, 64k)",
              "id": "qwen/Qwen3.5-27b",
              "modalities": { "input": ["text", "image"], "output": ["text"] },
              "limit": {
                "context": 66536,
                "input": 65536,
                "output": 8192
              }
            }
          }
        },
        "local": {
          "npm": "@ai-sdk/openai-compatible",
          "name": "llama-server (local)",
          "options": {
            "baseURL": "http://localhost:8012/v1"
          },
          "models": {
    xxx
            }
          }
        }
      }
    }
  19. tanihisadev commented on Apr 7, 2026

    @tanihisadev

    Yeah this would be a useful functionality to implement, +1.

  20. okuyam2y commented on Apr 10, 2026

    @okuyam2y

    For the maxContext part of this request: it's already possible to override context limits per model in opencode.json. The merge logic in provider.ts gives user config priority over the models.dev snapshot:

    {
      "provider": {
        "anthropic": {
          "models": {
            "claude-opus-4-20250805": {
              "limit": {
                "context": 200000  // override 1M default to save costs
              }
            }
          }
        }
      }
    }

    This works because the model merge uses model.limit?.context ?? existingModel?.limit?.context ?? 0 — user-defined values take precedence over the snapshot defaults.

    This isn't documented anywhere though, so it's easy to miss. It would be helpful to add this to the docs or the opencode.json schema description.

  21. naeem76 commented on Apr 13, 2026

    @naeem76

    @okuyam2y Thanks that works but I also had to add the output limit otherwise it crashed, now it works

    "anthropic": {
                "models": {
                    "claude-opus-4-6": {
                        "limit": {
                            "context": 200000,
                            "output": 100000
                        }
                    }
                }
            },
    
  22. github-actions commented on Jul 6, 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