Repository navigation
Description
Description
On the free tier (opencode/* models, no Go subscription, $0 Console balance) FreeUsageLimitError is not a simple "daily messages exhausted" state. It depends on the size of the individual request: a session with a large assembled context is rejected on every turn, while a new session on the same account succeeds in the same minute.
2026-10-25 00:06 local (UTC+8), same account, same machine, same model opencode/deepseek-v4.1-flash-free:
ses_08a6d445…(July session: 985 user messages, 14,966 assistant messages, 45.9M input tokens, last successful request 126k tokens on 23 Oct 18:21, assembled context now ≈447k tokens, estimated from the 1.79 MB context payload) →Free usage limit reached…,idleoutcomefailedses_e9155f04…(new session, 23k tokens per request) → normal answer 18 seconds later
So the quota is not "this account is blocked". The same account can still make small requests while a large session is refused.
Environment
- opencode 2.1.4, desktop app (bundled CLI), macOS (Darwin 25.6.0, arm64)
- Model:
opencode/deepseek-v4.1-flash-free, agentbuild - Shell: zsh; using the desktop app, not the TUI
- Plugins: 3 local plugins configured under
~/.config/opencode/plugins/*.ts; all three fail to load in 2.1.4 (Plugin must export a default definition), so effectively none are active - Free tier only: no OpenCode Go subscription, no paid balance
Reproduction
- Use only free
opencode/*models. - Let one session grow until its assembled request context is several hundred thousand tokens. Mine has 99 context items / 1.79 MB (
GET /api/session/{id}/context), and auto-compaction keeps it around that size. - Send any prompt to that session →
Free usage limit reached. Connect a provider or subscribe to OpenCode Go to keep going, or switch models.Stored as an assistant message with error typeprovider.free-limit, followed by anidlemessage withoutcome: "failed". - In the same minute, create a new session and send a prompt → it succeeds.
Expected Behavior
Either the request succeeds, or the error says what was exhausted and when it resets. The outcome should not depend on how much history a session carries.
Actual Behavior
The large session is rejected every time; small requests pass. Inside a single session the result flips with context size:
| time (local) | assembled ctx (tokens) | result |
|---|---|---|
| 00:06:41 | 23,163 | ok |
| 00:39:28 | 167,591 | fail |
| 00:39:57 | auto-compaction runs | — |
| 00:40:25 | 49,408 | ok |
| 00:50:06 | 82,107 | fail |
| 00:50:12 | 83,049 | ok |
The last two rows are 6 seconds apart at the same size, which looks like a rolling bucket at its boundary rather than a hard per-request cap.
Usage history from the same machine (session_message, providerID=opencode):
| day | requests | input tokens | cache read | free-limit errors |
|---|---|---|---|---|
| 20 Oct | 494 | 1,804,867 | 47.7M | 0 |
| 21 Oct | 251 | 1,020,301 | 24.7M | 0 |
| 23 Oct | 148 | 361,336 | 14.8M | 0 |
| 24 Oct | 3 | 0 | 0 | 3 (blocked all day) |
| 25 Oct | 133 | 728,646 | 12.8M | 18 |
20–21 Oct: heavy use, zero errors. 24 Oct: blocked from the first attempt. 25 Oct 00:06: works again, then ~730k input tokens in 45 minutes exhausts it. Something changed on the service side around 21–23 Oct, and the remaining allowance now behaves like a small bucket that refills over minutes/hours.
Additional Context
Client mapping: a QuotaExceeded error whose body contains FreeUsageLimitError becomes provider.free-limit with the message above. That is different from the "You've used today's free messages, they reset at …" copy, and I never see a reset time in this path.
How the numbers above were read (no instrumentation, just local state):
sqlite3 ~/.local/share/opencode/opencode.db "
select datetime(time_created/1000,'unixepoch','localtime') t,
json_extract(data,'$.tokens.input') + coalesce(json_extract(data,'$.tokens.cache.read'),0) ctx,
case when data like '%provider.free-limit%' then 'FAIL' else 'OK' end st
from session_message
where type='assistant' and json_extract(data,'\$.model.providerID')='opencode'
order by time_created desc limit 10;"Related issues, and how this one differs:
- session: titles never generated in v2 (no auto trigger + free-tier rejection) #58176, session: automatic titles fail with 403 FreeTierError when using free models #58521 — titles never generated on free tier (tool-less request rejected with 403
FreeTierError). Separate problem. - Free models report "Free usage limit reached" despite zero usage #58284, [BUG] FreeUsageLimitError raised with no free usage in the 24h window (free plan, $0 balance) — reset window not exposed to CLI/API #58205, Free models hit daily usage limit after only 20 seconds of use #58713, [Bug] Free usage limit immediately exceeded on the very first prompt after a fresh install/session #58641, Free usage limit error despite zero Console usage #58536 — "limit reached with zero usage". Here usage is real and the rejection correlates with per-request context size, reproducibly.
- [FEATURE]:Show exact free usage limit reset time #52894 — show the free-usage reset time.
Questions:
- Is the free allowance documented anywhere (tokens or requests, per day or rolling window)?
- Is rejecting a request because of its assembled context size intentional?
- Can the client expose the remaining allowance and reset time in this error path, as [FEATURE]:Show exact free usage limit reset time #52894 asks?
Activity
opencode-agent commentedon Oct 24, 2026
Thanks for the detailed measurements, @resulbegmyradow33-sys. They show clearly that on the free tier, long sessions with a large context hit
Free usage limit reachedwhile small new sessions still go through.How the free allowance is counted, how big it is and when it resets are decided by the OpenCode service, not by the app. Billing and account support isn't handled in GitHub issues, so please email help@anoma.ly with the details: the timestamps, the model, and the table of requests and tokens per day you gathered. If you've already emailed, the team will get to it, especially now that we've seen it here. Please keep email addresses, account details and anything related to payment out of this public issue and put them in the email instead.
Your questions about the app itself are already tracked here:
In the meantime, starting a new session or compacting the long one keeps each request small, which in your tests let requests through.
The bot will close this issue in 1 day.
resulbegmyradow33-sys commentedon Oct 24, 2026
Thanks. One clarification, because I think this is not an account-specific billing question:
The same account, same model and same minute produce both outcomes:
Free usage limit reachedAnd inside the new session the result flips with context size alone: 167k tokens failed, then auto-compaction brought it to 49k and it passed; later 82k failed and 83k passed six seconds apart. Nothing about the account changed between those pairs.
So the observable behavior is: whether a request is accepted depends on the size of that request. That is reproducible from local state without any Console access, which is why I filed it here rather than as billing support.
The question I still need an answer to is #2 above: is the per-request context-size check intentional? If yes, documenting it in #57540 would settle it and I'll close this myself. If no, the numbers in the report are enough to reproduce it.
opencode-agent commentedon Oct 25, 2026
Closing this now, since billing and account support happens by email rather than in GitHub issues. Thanks again for the detailed measurements, @resulbegmyradow33-sys.
For anything still open about how your free allowance is counted or about your account, please email help@anoma.ly. Please put any account details in the email, not here.
The app-side requests are still tracked in #57540 (documenting how free-tier usage is counted) and #52894 (showing the reset time when the limit is hit).
neriousy commentedon Nov 4, 2026
Thanks for the report, and sorry for the trouble!
We're tracking all free-tier quota and limit problems in one place: the pinned issue #59387. Please read it first. Most of these reports are fixed by updating to the latest OpenCode v2 (Desktop v1 users can download it from https://opencode.ai/v2/docs).
If you're on the latest v2 and still hitting this, please add your details there: OpenCode version, OS, model, and the exact error or reset time shown. Keeping everything in one thread helps us find the cause faster.
Closing as a duplicate of #59387.