Skip to main content
RapidDev - Software Development Agency
retool-tutorial

How to Deploy a Retool App to Production

Retool separates editing from production: editors work on the draft (current edit), and users always run the latest published release. To deploy, open the Release Manager (three-dot menu → Manage Releases or the Deploy button), create a new release, and publish it. Released apps can be rolled back instantly by activating a previous version. Before releasing, verify your resources point to production databases via the environment selector.

What you'll learn

  • How Retool's release model works: editing vs. production separation
  • How to publish a new release version and what version numbers mean in Retool
  • How to configure staging vs. production resources so queries point to the right database
  • How to roll back to a previous release if issues appear in production
  • The pre-release checklist to run before deploying to live users
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Intermediate9 min read20-30 minRetool Cloud and Self-hostedLast updated March 2026RapidDev Engineering Team
TL;DR

Retool separates editing from production: editors work on the draft (current edit), and users always run the latest published release. To deploy, open the Release Manager (three-dot menu → Manage Releases or the Deploy button), create a new release, and publish it. Released apps can be rolled back instantly by activating a previous version. Before releasing, verify your resources point to production databases via the environment selector.

Quick facts about this guide
FactValue
ToolRetool
DifficultyIntermediate
Time required20-30 min
CompatibilityRetool Cloud and Self-hosted
Last updatedMarch 2026

Retool's Release and Deployment Model

Retool uses a draft/release model. When you edit an app, you're always modifying the current draft — this is not immediately visible to end users. Users run the most recently published release. This separation means you can make iterative changes and only push them to users when ready.

Publishing a release creates an immutable snapshot of the app at that point in time. If something breaks in production, you can roll back to the previous release in seconds. Retool stores a history of all published releases.

For apps connected to multiple environments (staging database for testing, production database for live users), the environment selector ensures queries run against the right backend at the right time.

This tutorial walks through the full deployment lifecycle: pre-release preparation, publishing, environment configuration, and rollback procedures.

Prerequisites

  • A Retool app that is ready to deploy (tested in editor and preview modes)
  • Editor or Admin access to the Retool app
  • Resources configured for both staging and production if using multiple environments
  • User permissions set up for who should access the deployed app

Step-by-step guide

1

Understand the draft vs. release model

Before deploying, understand how Retool's release system works. The current app you see when editing is the draft version. Users who open the app URL always run the most recent published release — they never see your draft edits in progress. To see which version users are running: open the app → three-dot menu (top-right) → Manage Releases. You'll see a list of all published releases with timestamps and the currently active version marked. Any release can be made active with one click — this is your rollback mechanism.

Expected result: You understand the draft vs. released distinction and can navigate to the Release Manager.

2

Run the pre-release checklist

Before publishing, verify these items in the app: 1. Test all queries in Preview mode — not just in the editor canvas 2. Confirm queries use the correct production resource (not a dev/staging database) 3. Check user permissions: Settings → Permissions → verify which groups can view/edit the app 4. Remove any test data, console.log() statements in JS queries, and debug-only components 5. Verify error handling: queries should have On Error handlers, not just silent failures 6. Check the app URL — ensure it doesn't expose query results in the URL via `{{ currentUrl }}` leakage 7. If using environment variables, confirm production values are set correctly

typescript
1// JS Query pre-release cleanup: remove console.log
2// BEFORE (dev/debug):
3console.log('Debug:', query1.data);
4const result = processData(query1.data);
5return result;
6
7// AFTER (production-ready):
8const result = processData(query1.data);
9return result;
10
11// Also ensure error handling is in place on queries:
12// Inspector → Interaction → On Failure → Show notification
13// 'Query failed: {{ error.message }}'

Expected result: App is tested in Preview mode with production resources and no debug artifacts remaining.

3

Configure the production environment

If your app has queries that connect to different databases depending on the environment, configure the environment before releasing. In the Retool editor, look for the Environment selector in the toolbar (it shows 'Staging' or 'Production' depending on your setup). Switch to Production and verify that all queries execute against the production resource. For apps using `{{ retoolContext.environment }}` in query logic, also confirm that production-specific behavior (stricter rate limits, real API keys, real payment processing) is tested.

typescript
1// Query logic that behaves differently by environment:
2// SQL query with environment-conditional behavior:
3-- This query runs in both environments
4-- Retool selects the resource based on the environment switcher
5SELECT * FROM orders WHERE status = 'pending'
6LIMIT {{ retoolContext.environment === 'production' ? 100 : 10 }}
7
8// JS Query environment check:
9if (retoolContext.environment === 'production') {
10 // Use real payment processor
11 return await processRealPayment.trigger();
12} else {
13 // Use test mode
14 return await processTestPayment.trigger();
15}

Expected result: All queries run against production resources when the environment selector shows Production.

4

Publish a new release

When the app is ready, publish it: 1. Open the three-dot menu (⋮) in the top-right of the editor, OR click the 'Deploy' button 2. Select 'Manage Releases' (or the release dialog opens directly) 3. Click 'Create Release' (or 'Publish' depending on your Retool version) 4. Enter a release note describing what changed (e.g., 'Add export to CSV button', 'Fix: pagination bug on orders table') 5. Optionally, specify a version tag 6. Click Publish The release is immediately active. Users opening the app URL will now run this version. Previous releases remain accessible in the Release Manager.

Expected result: The Release Manager shows the new release as the current active version with a green indicator.

5

Configure app sharing and permissions before releasing

Who can access the app URL? Configure this in Settings → Permissions → App Access. By default, only Retool users in your organization can access the app. For apps accessed by external users (e.g., customer portal, partner tool), configure public access or restricted email domains. Key permission levels: - Use: can run the app, cannot edit - Edit: can modify the app (editor access) - Own: can delete the app and manage permissions Set the app's Access Level to All users (all org members) or specific Groups.

typescript
1// Conditional UI based on user permissions:
2// Show admin controls only to users in the 'Admin' group:
3// Button component → Hidden property:
4{{ !current_user.groups.includes('Admin') }}
5
6// Show user's own records only:
7// SQL query WHERE clause:
8WHERE created_by = {{ current_user.email }}
9
10// Check environment and permissions in one expression:
11{{ retoolContext.environment === 'production' && current_user.groups.includes('Admin') }}

Expected result: App permissions are configured so the right users have access after deployment.

6

Roll back to a previous release

If a deployed release causes issues (a query breaks, the UI is broken for certain users, a critical bug slipped through), roll back instantly: 1. Open the three-dot menu → Manage Releases 2. Find the last known-good release in the list 3. Click 'Activate' or 'Set as Current' 4. The previous release becomes active immediately — no cache clearing or deployment pipeline needed The broken release remains in the release history and is not deleted. You can investigate and fix the issue in the draft, then publish a new release when ready.

Expected result: The Release Manager shows the previous release as active, and users running the app now see the rolled-back version.

7

Set up Protected Apps for Enterprise deployment control (optional)

On Retool Enterprise plans, Protected Apps adds a required code review step before any release can be published to users. This is analogous to a pull request process for app changes. Enable Protected Apps: Settings → Permissions → Protected Apps toggle. Once enabled, editors submit releases for approval, and designated reviewers must approve before the release goes live. This is valuable for apps handling financial transactions, medical data, or sensitive operations.

Expected result: Protected Apps is configured and all future releases require reviewer approval before activating.

Complete working example

JS Query: preDeploymentChecks
1// JS Query: preDeploymentChecks
2// Run this before publishing a release to catch common issues
3// Returns a list of warnings
4
5const warnings = [];
6const errors = [];
7
8// Check 1: Verify environment
9if (retoolContext.environment !== 'production') {
10 warnings.push('WARNING: App is in ' + retoolContext.environment + ' environment, not production');
11}
12
13// Check 2: Check for test/debug data in state variables (example)
14// if (testModeVar.value === true) {
15// errors.push('ERROR: testModeVar is still set to true');
16// }
17
18// Check 3: Verify required config vars are set
19const requiredVars = ['API_BASE_URL', 'STRIPE_KEY'];
20// requiredVars.forEach(varName => {
21// if (!retoolContext.configVars[varName]) {
22// errors.push('ERROR: Config var ' + varName + ' is not set for this environment');
23// }
24// });
25
26// Output summary
27if (errors.length > 0) {
28 return {
29 status: 'BLOCKED',
30 message: 'Cannot deploy — critical errors found',
31 errors,
32 warnings
33 };
34}
35
36return {
37 status: warnings.length > 0 ? 'DEPLOY_WITH_WARNINGS' : 'READY_TO_DEPLOY',
38 message: warnings.length > 0 ? 'Review warnings before deploying' : 'All checks passed',
39 errors: [],
40 warnings
41};

Common mistakes when deploying a Retool App to Production

Why it's a problem: Sharing the editor URL (ending in /editor) with end users instead of the app URL

How to avoid: Always share the production app URL without /editor. Editor URLs give users editing access and show the draft version. Find the correct share URL in the three-dot menu → Share App or from the app list in the Retool home page.

Why it's a problem: Publishing a release while the environment selector shows 'Staging', causing queries to run against the staging database for end users

How to avoid: Before releasing, switch the Environment selector to Production, test the app in Preview mode, then publish. The release captures the app configuration but not the environment selector state — users run the app against whichever resource is configured for their environment.

Why it's a problem: Not adding release notes, making it impossible to identify which release introduced a bug

How to avoid: Always write at least one sentence of release notes: 'Added CSV export to orders table' or 'Fixed: sorting bug on user list'. These appear in the Release Manager log and save significant time during incident investigation.

Best practices

  • Always test in Preview mode with the Production environment selected before publishing — the editor canvas can mask query/resource issues
  • Write descriptive release notes for every deployment — they're your deployment log and invaluable for diagnosing production issues
  • Configure rollback-ready releases: keep the last 3-5 stable releases active in the Release Manager so you can roll back instantly
  • Use Protected Apps (Enterprise) or a peer review process for apps handling financial, medical, or security-sensitive data
  • Never share the editor URL with end users — always share the app URL which serves the released version
  • Set app permissions before releasing: confirm which Groups have Use vs Edit access
  • Keep a staging copy of the app for testing major changes before deploying to the production app URL

Still stuck?

Copy one of these prompts to get a personalized, step-by-step explanation.

ChatGPT Prompt

I've built a Retool app and want to deploy it to my team. Explain: (1) the difference between the Retool draft and published release, (2) how to publish a new release using the Release Manager, (3) how to configure user permissions so my team can use but not edit the app, (4) how to roll back to a previous release if something breaks, and (5) what to check before deploying (pre-release checklist). Include Retool-specific UI paths and the retoolContext.environment variable.

Retool Prompt

Before I deploy this Retool app, help me: (1) switch the environment selector to Production and test all queries, (2) add On Failure error handlers to any queries missing them, (3) configure app permissions so the 'Operations Team' group has Use access but cannot edit, (4) publish a release with the note 'Initial production release'. Walk me through each step in the Retool editor.

Frequently asked questions

Do Retool users see my changes immediately when I edit an app, or only after I publish?

Users always see the most recently published release, not your in-progress edits. When you edit the app in the editor, you're modifying the draft. Only after you publish a release (via Manage Releases → Create Release) do users see the changes. This gives you a safe editing environment without affecting live users.

How many release versions does Retool store?

Retool stores an unlimited history of published releases. All previous releases appear in the Release Manager and can be activated (rolled back to) at any time. Releases are never automatically purged. This means you always have a rollback option regardless of how old the last stable release was.

Can I deploy a Retool app to a custom URL or embed it in another website?

Yes. Retool apps can be accessed at custom domains (requires DNS setup — see the custom domains tutorial). For embedding, Retool apps support iframe embedding — copy the app URL and embed it in an <iframe> tag. Note that users must be authenticated to Retool to access embedded apps unless you configure public access in app permissions.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Learning is great. Shipping is faster with help.

Our engineers have built 600+ apps on Retool and the tools around it. If your project needs to be live sooner than your learning curve allows — book a free consultation.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.