Convex CommunityCCConvex Community
Powered by
gwilliamnnG
Convex Community•6mo ago•
1 reply
gwilliamnn

Unexpected query invalidation behavior — mutation waits for refetches across unrelated queries

Hi Convex team,

I built a minimal reproduction and wanted to report the unexpected behavior I observed when calling a mutation that inserts a new message.

Short summary
- Mutation (DB write) completes quickly on the server (~0-30ms).
- The client-side mutation promise does not resolve immediately — it waits while multiple queries refetch.
- Convex revalidates all queries that touch the
messages
messages
table (including a global
getAllMessages
getAllMessages
query and per-period queries), even when the mutation’s data clearly only belongs to one query (e.g. "after cutoff").
- This causes the mutation to appear to take the combined refetch time on the frontend (in my test ~765ms), even though the backend mutation duration is ~0ms.

Reproduction steps (repo included)
1. Clone the public test repo: https://github.com/williamneves/convex-lab
2. Run Convex dev:
npx convex dev
npx convex dev

3. Start the frontend (Bun/Next):
bun run dev
bun run dev
and open the UI.
4. Click “Seed Users” and “Seed 20 Messages”.
5. Set a cutoff date and click “Generate Before Message” or “Generate After Message”.
6. Watch the Timing Analysis card and Convex logs.

Observed logs (snippet)
- insertMessage logs (server):
 [insertMessage] Mutation started for timestamp: 2025-08-19T04:11:32.820Z
 [insertMessage] DB operation took 0ms
 [insertMessage] Total mutation duration: 0ms
 [insertMessage] Created message by Carol Williams
 [insertMessage] Mutation started for timestamp: 2025-08-19T04:11:32.820Z
 [insertMessage] DB operation took 0ms
 [insertMessage] Total mutation duration: 0ms
 [insertMessage] Created message by Carol Williams

— Convex shows the mutation finished in ~0–26ms in the server logs.

- Queries revalidation logs (server):
 [getMessagesByPeriod] Query invoked - before 2025-08-20T02:46:44.651Z
 [getMessagesByPeriod] Artificial delay (computation loop)...
 simpleDelay: 478ms
 [getMessagesByPeriod] Retrieved 16 messages (before cutoff) in 0ms

 [getMessagesByPeriod] Query invoked - after 2025-08-20T02:46:44.651Z
 [getMessagesByPeriod] Artificial delay (computation loop)...
 [getMessagesByPeriod] Retrieved 47 messages (after cutoff) in 0ms

 [getAllMessages] Query invoked
 [getAllMessages] Artificial delay (computation loop)...
 simpleDelay: 478ms
 [getAllMessages] Retrieved 63 messages in 0ms
 [getMessagesByPeriod] Query invoked - before 2025-08-20T02:46:44.651Z
 [getMessagesByPeriod] Artificial delay (computation loop)...
 simpleDelay: 478ms
 [getMessagesByPeriod] Retrieved 16 messages (before cutoff) in 0ms

 [getMessagesByPeriod] Query invoked - after 2025-08-20T02:46:44.651Z
 [getMessagesByPeriod] Artificial delay (computation loop)...
 [getMessagesByPeriod] Retrieved 47 messages (after cutoff) in 0ms

 [getAllMessages] Query invoked
 [getAllMessages] Artificial delay (computation loop)...
 simpleDelay: 478ms
 [getAllMessages] Retrieved 63 messages in 0ms


- Frontend timing (UI card):
Backend Mutation: 0ms
Backend Mutation: 0ms
,
DB Op: 0ms
DB Op: 0ms
,
Frontend Total: 765ms
Frontend Total: 765ms
— frontend waited ~765ms for mutation promise to resolve.

Observed behavior summary
- The mutation completes on the server almost instantly.
- The client-side mutation promise resolves only after all related queries have re-fetched (including ones whose args should not match the new message).
-
getAllMessages
getAllMessages
is refetched even when the mutation only affects the “after” list — this results in unnecessary refetches and the user-perceived latency of the mutation includes query refetch time.

Expected behavior
- Mutation resolution should reflect the mutation’s server-side work (DB write + any server work).
- Query invalidation/refetch should be triggered but should not block the mutation promise resolution unless explicitly configured to do so.
- Ideally, invalidations should be scoped: only queries whose arguments indicate they could be affected by the mutation should be revalidated.

Questions / requests
1. Is the Convex client intended to wait for query revalidations before resolving a mutation promise? If so, is this configurable (non-blocking refetch vs. blocking)?
2. Is there a way to scope invalidation so only queries with matching args are revalidated (so
getAllMessages
getAllMessages
would not refetch if I inserted a message that only matched
after
after
)?
3. If current behavior is intentional, can you document when mutations block on refetches, and whether there’s a way to change that behavior (e.g., optimistic updates, fire-and-forget revalidation)?
4. I can provide the small test repo link, console logs, and server logs; what additional info would be most helpful for triage?

Repository & logs
- Repo: https://github.com/williamneves/convex-lab
- I can attach full terminal logs and Convex function logs if useful.
Arc_2025-08-20_23.07.13.png
Arc_2025-08-20_23.07.19.png
GitHub
GitHub - williamneves/convex-lab
Contribute to williamneves/convex-lab development by creating an account on GitHub.
GitHub - williamneves/convex-lab
Convex Community banner
Convex CommunityJoin
Join the Convex Discord! Explore Convex, the backend platform that keeps your app in sync.
15,138Members
Resources
Was this page helpful?

Similar Threads

Recent Announcements
Recent Announcements
james

Hi @everyone with everything going on today I forgot to post on discord about our EU launch! We have a region in Dublin now! You can start using it immediately, even for folks on the free plan. https://news.convex.dev/we-finally-got-our-eu-visa/ Stay tuned for more regions but also stay tuned for more infra improvements where we improve latency for teams no matter where their servers are located. Just at the tip of the iceberg re all the optimizations we have lined up.

james · 4d ago

Wayne

Hi @everyone happy Monday. Components Authoring [Challenge](https://www.convex.dev/components/challenge) updates! Meet the second batch of community-approved components **Firecrawl Scrape **- Scrape any URL and get clean markdown, HTML, screenshots, or structured JSON - with durable caching and reactive queries. https://www.convex.dev/components/firecrawl-scrape Built by: Gitmaxd **Durable Agents **- A Convex component for building durable AI agents with an async tool loop. https://www.convex.dev/components/durable-agents Built by: Siegfried **Convex Debouncer** - A server-side debouncing component for debouncing expensive operations like LLM calls, metrics computation, or any heavy processing that should only run after a period of inactivity. https://www.convex.dev/components/debouncer Built by: Ilya **DatabaseChat **- A Convex component for adding natural language database queries to your app. https://www.convex.dev/components/database-chat Built by: Nick **Transloadit** - A Convex component for creating Transloadit Assemblies, handling resumable uploads with status, and persisting status/results in Convex. https://www.convex.dev/components/transloadit Built by: Kvz **Loops** - A Convex component for integrating with Loops.so email marketing platform. https://www.convex.dev/components/loops Built by: Bobby The [challenge](https://www.convex.dev/components/challenge) is now ongoing, so keep building, and we'll keep rewarding. Thanks, everyone!

Wayne · 3w ago

Liz C

Hi everyone! Have you ever wanted to get your hands on some convex swag? Well you're in luck! We just launched our Convex swag store. Check it out here ---> https://store.convex.dev/

Liz C · 3w ago

Similar Threads

Mutation on queries.
SamSSam / support-community
4mo ago
Suboptimal Caching Behavior for Public Queries
StarlordSStarlord / support-community
14mo ago
Query behavior for same parameters
punnPpunn / support-community
3y ago
Function "versions" / Behavior across deployments
kabb8048Kkabb8048 / support-community
2y ago