Guides
How to Disable Queries in a Retool Module from the Parent App
If you've ever placed a Retool module inside a modal, a tab, or a drawer, you've likely run into a frustrating performance problem: Retool runs every query inside that module on page load, regardless of whether the module is visible or whether a disabled flag has been set on individual queries. This guide covers why that happens, how to disable queries in a Retool module from the parent app right now, and what a proper native solution should look like.
Why Retool Module Queries Run Even When the Module Is Hidden
Retool modules are self-contained units of UI and logic. When a parent app renders, it initializes all modules — including their queries — whether those modules are painted on screen or not. This means a module sitting inside a closed modal is still firing queries against your database or API from the moment the page loads.
This becomes especially costly when a module query is tied to a dynamic value — like a table's selectedRow — that changes frequently. Every row selection in the parent app can trigger a re-run of queries inside a hidden module the user hasn't even opened yet. The result is unnecessary API calls, slower page performance, and in some cases, noticeable lag when interacting with inputs or selects inside the module once it does open.
The Community Workaround: Controlling Queries with an Input Flag
Until Retool ships a native toggle for this, the most reliable workaround is to gate every query inside your module behind a boolean input prop passed down from the parent app. Here's how to set it up step by step.
- Step 1 — Add a boolean input to your module. In your module's Input configuration, create a new input property — for example,
isEnabled— with a default value offalse. - Step 2 — Disable all module queries conditionally. For each query inside the module, open its settings and set the
Disable querytoggle to an expression like{{ !isEnabled.value }}. This tells Retool not to run the query unless the parent explicitly enables it. - Step 3 — Control the input from the parent app. In your parent app, find the module component and bind its
isEnabledinput to a condition that reflects when the module should be active — for example,{{ modal1.isOpen }}for a modal, or{{ tabs1.currentTabIndex === 2 }}for a tab. - Step 4 — Pass the flag to nested modules. If your module contains other nested modules, thread the
isEnabledinput down through each layer so inner modules also respect the disabled state. This adds overhead but keeps behavior consistent.
This approach works, but as several developers in the Retool community have pointed out, the overhead is real. You have to manually apply the disable condition to every single query in every module, and then carefully manage the parent-side logic to set isEnabled correctly across different scenarios — modals, tabs, drawers, conditional panels, and more. If you add a new query to the module later, it's easy to forget to add the disable guard.
What a Native "Disable All Module Queries" Feature Should Look Like
The right fix here is a first-class Retool feature, and the community has been clear about what it needs. There are two sensible approaches Retool could take:
- A module-level
enabledproperty exposed to the parent app, similar to how individual components have adisabledprop. Setting it tofalsefrom the parent would halt all query execution inside the module without requiring per-query configuration. - Automatic suppression for unpainted modules. Retool could detect when a module is not currently rendered in the viewport — because its parent modal is closed, its tab is inactive, or it's conditionally hidden — and automatically defer query execution until the module becomes visible.
Ideally, both options would exist. The automatic suppression would handle the common case with zero configuration, while the explicit enabled property would cover more advanced scenarios where a visible module still shouldn't run its queries until a specific condition is met. The module should also be able to read this property internally so it can propagate it to any nested modules it contains.
Performance Impact: Why This Matters in Production
For simple apps, a few extra background queries might be negligible. But in production internal tools — where a single app can contain dozens of modules, each with multiple queries tied to live data sources — the cumulative cost is significant. Users report lag when typing into inputs inside a module that's inside a modal, a problem that's partly caused by the module doing background work it shouldn't be doing. Teams building complex Retool apps on top of slow or rate-limited APIs feel this even more acutely.
Reducing unnecessary query execution is one of the highest-leverage performance improvements you can make in a Retool app. Until Retool ships a native solution, the input-flag workaround is your best option. It's tedious to set up, but it works — and it keeps your app from hammering your backend every time a user clicks a table row.
What to Do Right Now
If you're hitting this problem today, implement the isEnabled input flag pattern described above. Make it your team's standard pattern for any module that lives inside a modal, drawer, or tab. Document it in your internal Retool style guide so new queries added to existing modules automatically get the disable guard applied.
And if you want Retool to prioritize a native fix, leave a comment or a +1 on the Retool community thread for this feature request. The product team tracks community votes when prioritizing the roadmap, and this is one of those quality-of-life improvements that would meaningfully reduce overhead for teams building serious internal tools.
Ready to build?
We scope, design, and ship your Retool app — fast.