Tutorials

How to Invalidate Query Cache in Retool Programmatically

OTC Team··4 min read

If you've been trying to invalidate a query cache in Retool programmatically, you've probably hit a wall. For a long time, the only option was clicking the "Invalidate cache" link manually inside the Retool designer — not exactly useful when you need cache-busting to happen dynamically at runtime. The good news: Retool has shipped a native invalidateCache function, and this guide covers exactly how to use it.

Why Query Caching in Retool Can Cause Stale Data Problems

Retool lets you cache query results to improve app performance and reduce load on your database or API. For queries that hit slow external APIs — some taking 5–10 seconds or more — caching is a lifesaver on initial page load. But caching creates a real problem the moment your underlying data changes. If a user triggers an action that modifies data, your cached query will return stale results until the cache expires on its own. What you really need is the ability to force-reset that cache the moment you know the data has changed.

The Old Workaround: Injecting a Cache-Busting Parameter

Before the official fix landed, some developers got creative. One approach that circulated in the Retool community involved injecting a dummy invariant parameter into SQL queries — something like this:

SELECT * FROM users WHERE {{cacheControl.selectUsers}} = {{cacheControl.selectUsers}}

The idea was to increment cacheControl.selectUsers whenever you wanted to bust the cache, forcing Retool to treat it as a new query. It's clever, but it's fragile. It doesn't translate well to non-SQL data sources like DynamoDB or REST APIs, and it clutters your queries with logic that has nothing to do with your actual data fetching. Fortunately, you don't need this trick anymore.

How to Use invalidateCache in Retool

Retool now exposes an invalidateCache function directly on query objects. Here's how to use it across the three main contexts where it's available.

Option 1: Call invalidateCache Inside a JS Query

This is the most flexible approach. Create a new JavaScript query and call invalidateCache on whichever query you want to reset:

myQuery.invalidateCache();

You can chain this with a re-trigger of the query so fresh data loads immediately after the cache is cleared:

myQuery.invalidateCache();
myQuery.trigger();

This pattern is ideal when you need to bust cache after a form submission, a delete action, or any event that mutates the underlying data. Just call this JS query from whatever success handler is relevant.

Option 2: Use invalidateCache in an Event Handler (Run Script)

If you prefer keeping logic in event handlers rather than standalone JS queries, you can call invalidateCache directly under a component's event handler using the Run Script action type. Select Run Script as the action, then write:

myQuery.invalidateCache();

This works well for button onClick handlers or table row action buttons where you want an immediate cache reset tied to a specific user interaction.

Option 3: Use the "Control Query" Action in an Event Handler

Retool also exposes invalidateCache as a first-class option inside the Control query action type within event handlers. You don't have to write any code at all with this approach:

  • Open the event handler for your component (e.g., a button's onClick).
  • Set the action type to Control query.
  • Select the target query from the dropdown.
  • Choose Invalidate cache as the control action.

This is the cleanest no-code option if you want to avoid writing JavaScript entirely. It's especially useful for less technical Retool builders or apps maintained by teams who prefer visual configuration over scripting.

When Should You Invalidate the Query Cache?

Not every query needs cache invalidation logic, but here are the most common scenarios where it makes a real difference:

  • After a mutation: Any time a user creates, updates, or deletes a record, queries displaying that data should have their cache invalidated before re-running.
  • Slow API calls: If you cache an external API call that takes 5–10 seconds, you'll want to manually bust that cache when you know the upstream data has changed — not just wait for TTL expiration.
  • Multi-step workflows: When a workflow involves several sequential queries, earlier steps may change data that later cached queries depend on. Invalidating at the right step keeps your app consistent.
  • Page-level refresh events: If your app has a manual "Refresh" button, wiring it to invalidateCache followed by trigger gives users a reliable way to pull fresh data without a full page reload.

Key Takeaways

The invalidateCache function in Retool gives you clean, programmatic control over query caching without any hacky SQL tricks or workarounds. Whether you call it from a JS query, a Run Script event handler, or the Control query action, the behavior is the same: the cached result for that query is wiped and the next trigger fetches fresh data. If you're building Retool apps where data freshness matters — and it almost always does — this is a pattern worth adding to your standard toolkit.

Ready to build?

We scope, design, and ship your Retool app — fast.

Ready to ship your first tool?