# Deploying on Render — Understand how deploys work. Render can [automatically deploy](#automatic-deploys) your application each time you merge a change to your codebase: [image: High-level auto-deploy steps] You can also trigger [manual deploys](#manual-deploys), both programmatically and in the Render Dashboard. All service types redeploy with [zero downtime](#zero-downtime-deploys) (unless they attach a persistent disk). ## Automatic deploys As part of creating a service on Render, you link a branch of your [GitHub](github)/[GitLab](gitlab)/[Bitbucket](bitbucket) repo (such as `main` or `production`). Whenever you push or merge a change to that branch, by default Render automatically rebuilds and redeploys your service. Auto-deploys appear in your service's *Events* timeline in the Render Dashboard: [image: Auto-deploys in the Render Dashboard] If needed, you can [skip an auto-deploy](#skipping-an-auto-deploy) for a particular commit, or even [disable auto-deploys entirely](#disabling-auto-deploys). > *Auto-deploys require a linked [GitHub](github), [GitLab](gitlab), or [Bitbucket](bitbucket) account.* Services that use a [prebuilt Docker image](/deploying-an-image) or a [public Git repository URL](web-services#deploy-your-own-code) must be deployed [manually](#manual-deploys). ### Configuring auto-deploys Configure a service's auto-deploy behavior from its *Settings* page in the [Render Dashboard](https://dashboard.render.com): [image: Configuring auto-deploys in the Render Dashboard] Under *Auto-Deploy*, select one of the following: | Option | Description | | --- | --- | | *On Commit* | Render triggers a deploy as soon as you push or merge a change to your linked branch. This is the default behavior for a new service. | | *After CI Checks Pass* | With each change to your linked branch, Render triggers a deploy _only after_ all of your repo's CI checks pass. For details, see [Integrating with CI](#integrating-with-ci). | | *Off* | Disables auto-deploys for the service. Choose this option if you only want to trigger deploys [manually](#manual-deploys). | #### Integrating with CI If you set your service's [auto-deploy behavior](#configuring-auto-deploys) to *After CI Checks Pass*, Render waits for a new commit's CI checks to complete before triggering a deploy. If _all_ checks pass, Render proceeds with the deploy. For GitHub checks, Render considers a check "passed" if its [conclusion](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/collaborating-on-repositories-with-code-quality-features/about-status-checks#check-statuses-and-conclusions) is any of `success`, `neutral`, or `skipped`. > *Render does _not_ trigger a deploy if:* > > - Zero checks are detected for the new commit > - At least one CI check fails for the new commit > > If your repo doesn't run CI checks, use *On Commit* instead of *After CI Checks Pass* to enable auto-deploys. Select the tab for your Git provider to learn which CI checks are supported: **GitHub** Render detects the results of CI checks originating from the following: - GitHub Actions - Tools that integrate with the [GitHub checks API](https://docs.github.com/en/rest/guides/using-the-rest-api-to-interact-with-checks), such as [CircleCI](https://circleci.com/docs/enable-checks) Supported checks appear on commits and pull requests in the GitHub UI: [image: GitHub checks on a pull request] **GitLab** Render detects the results of jobs executed as part of [GitLab CI/CD pipelines](https://docs.gitlab.com/ci/pipelines/). **Bitbucket** Render detects the results of steps executed as part of [Bitbucket Pipelines](https://support.atlassian.com/bitbucket-cloud/docs/get-started-with-bitbucket-pipelines/). ### Skipping an auto-deploy Certain changes to your codebase might not require a new deploy, such as edits to a `README` file. In these cases, you can include a *skip phrase* in your Git commit message to prevent the change from triggering an auto-deploy: ```shell git commit -m "[skip render] Update README" ``` The skip phrase is one of `[skip render]` or `[render skip]`. You can also replace `render` with one of the following: - `deploy` - `cd` When an auto-deploy is skipped, a corresponding entry appears on your service's *Events* page: [image: A skipped deploy on a service's Events feed] > *For additional control over auto-deploys, configure [*build filters*](monorepo-support#setting-build-filters).* > > With build filters, Render triggers an auto-deploy only if there are changes to particular files in your repo (no skip phrase required). [See details.](monorepo-support#setting-build-filters) ## Manual deploys You can manually trigger a Render service deploy in a variety of ways. Select a tab for details: **Dashboard** From your service's page in the [Render Dashboard](https://dashboard.render.com), open the *Manual Deploy* dropdown: [image: Manual deploy options in the Render Dashboard] Select a deploy option: | Option | Description | | --- | --- | | *Deploy latest commit* | Deploys the most recent commit on your service's linked branch. | | *Deploy a specific commit* | Deploys a specific commit from your linked branch's commit history. Specify a commit by its SHA, or by selecting it from a list of recent commits. *This disables automatic deploys for the service.* This is because an automatic deploy might reintroduce commits you wanted to exclude from this deploy. Learn more about [deploying a specific commit](/deploying-a-commit). | | *Clear build cache & deploy* | Similar to *Deploy latest commit*, but first clears the service's build cache. This way, the new deploy doesn't reuse any artifacts generated during a previous build. Use this option to incorporate changes to your service's build command, or to refresh stale static assets. | | *Restart service* | Deploys the same commit that's _currently_ deployed for the service, with the same values for user-defined environment variables. For details, see [Restarting a service](#restarting-a-service). | **CLI** Run the following [Render CLI](cli) command: ```shell render deploys create ``` This opens an interactive menu that lists the services in your workspace. Select a service to deploy. **Deploy hook** Each Render service has a unique *Deploy Hook URL* available on its Settings page: [image: A service's deploy hook URL in the Render Dashboard] You can trigger a manual deploy by sending an HTTP GET or POST request to this URL. For details, see [Deploy Hooks](/deploy-hooks). **API** Send a `POST` request to the Render API's [Trigger Deploy endpoint.](https://api-docs.render.com/reference/create-deploy) This endpoint accepts optional body parameters for clearing the service's build cache and/or deploying a specific commit. For services that pull a Docker image, you can specify the URL of the image to pull. ## Deploy steps With each deploy, Render proceeds through the following commands for your service: [diagram] \*Consumes [pipeline minutes](build-pipeline#pipeline-minutes) while running. [View your usage.](https://dashboard.render.com/billing#included-usage) You specify these commands as part of creating your service in the [Render Dashboard](https://dashboard.render.com). You can modify these commands for an existing service from its *Settings* page: [image: Setting deploy-related commands in the Render Dashboard] Each command is described below. *If any command fails or times out, the entire deploy fails.* Any remaining commands do not run. Your service continues running its most recent successful deploy (if any), with [zero downtime](#zero-downtime-deploys). Command timeouts are as follows: | Command | Timeout | | --- | --- | | Build command | 120 minutes | | Pre-deploy command | 30 minutes | | Start command | 15 minutes | ### Build command Performs all compilation and dependency installation that's necessary for your service to run. It usually resembles the command you use to build your project locally. > *This command consumes pipeline minutes while running.* > > You receive an included amount of pipeline minutes each month and can purchase more as needed. [View your usage.](https://dashboard.render.com/billing#included-usage) #### Example build commands for each runtime ------ ###### Runtime Node.js ###### Example Build Command(s) `npm install` / `pnpm install` / `bun install` `yarn` --- ###### Runtime Python ###### Example Build Command(s) `pip install -r requirements.txt` `poetry install` `uv sync` > To use `uv`, a `uv.lock` file must be present in your service's root directory. [Learn more](uv-version). --- ###### Runtime Ruby ###### Example Build Command(s) `bundle install` --- ###### Runtime Go ###### Example Build Command(s) `go build -tags netgo -ldflags '-s -w' -o app` --- ###### Runtime Rust ###### Example Build Command(s) `cargo build --release` --- ###### Runtime Elixir ###### Example Build Command(s) `mix deps.get --only prod && mix compile` `mix deps.get --only prod && mix assets.deploy` --- ###### Runtime Docker ###### Example Build Command(s) *You can't set a build command for services that use Docker.* Instead, Render either: - [Builds a custom image](docker#building-from-a-dockerfile) based on your Dockerfile - [Pulls a specified image](/deploying-an-image) from your container registry ------ ### Pre-deploy command If defined, the pre-deploy command runs _after_ your service's build finishes, but _before_ that build is deployed. Recommended for tasks that should always precede a deploy but are _not_ tied to building your code, such as: - Database migrations - Uploading assets to a CDN > *The pre-deploy command executes on a separate instance from your running service.* > > Changes you make to the filesystem are _not_ reflected in the deployed service. You do not have access to a service's attached persistent disk (if it has one). The pre-deploy command is available for paid web services, private services, and background workers. If you _don't_ define a pre-deploy command for a service, Render proceeds directly from the [build command](#build-command) to the [start command](#start-command). > *This command consumes pipeline minutes while running.* > > You receive an included amount of pipeline minutes each month and can purchase more as needed. [View your usage.](https://dashboard.render.com/billing#included-usage) ### Start command Render runs this command to start your service when it's ready to deploy. #### Example start commands for each runtime | Runtime | Example Start Command(s) | | --- | --- | | Node.js | `npm start` / `pnpm start` / `bun run start` `yarn start` `node index.js` | | Python | `gunicorn your_application.wsgi` | | Ruby | `bundle exec puma` | | Go | `./app` | | Rust | `cargo run --release` | | Elixir | `mix phx.server` `mix run --no-halt` | | Docker | By default, Render runs the `CMD` defined in your Dockerfile. You can specify a different command in the *Docker Command* field on your service's *Settings* page. > *To run multiple commands with Docker, provide those commands to `/bin/bash -c`.* For example, here's a Docker Command for a Django service that runs database migrations and then starts the web server: ``` /bin/bash -c python manage.py migrate && gunicorn myapp.wsgi:application --bind 0.0.0.0:10000 ``` | ## Managing deploys ### Handling overlapping deploys Only one deploy can run at a time per service. Sometimes, a deploy will trigger while _another_ deploy is still in progress. When this occurs, your service can do one of the following: ------ ###### Policy **Wait** ###### Description Allow the in-progress deploy to finish, then proceed directly to the most recently triggered deploy: [image: A deploy waiting for an in-progress deploy to complete] - In this case, Render skips any "intermediate" deploys, such as Deploy B in the timeline above. - We recommend this option for most workspaces, because it helps maintain a regular cadence of deploys during periods of high change volume. - This is the default policy for workspaces created *on or after 2025-07-14*. --- ###### Policy **Override** ###### Description Immediately cancel the in-progress deploy and start the new one. - This is the default policy for workspaces created *before 2025-07-14*. ------ You can set which of these policies to use for your workspace: 1. In the [Render Dashboard](https://dashboard.render.com), open your workspace's *Settings* page. 2. Scroll down to the *Overlapping Deploy Policy* section and click *Edit*: [image: The Overlapping Deploy Policy setting in the Render Dashboard] 3. Select an option and click *Save changes*. ### Canceling a deploy You can cancel an in-progress deploy in the [Render Dashboard](https://dashboard.render.com): 1. Go to your service's *Events* page and click the word *Deploy* in the corresponding event entry. - This opens the deploy's details page. 2. Click *Cancel deploy*: [image: Canceling a deploy in the Render Dashboard] If you cancel an in-progress deploy while another deploy is [waiting](#handling-overlapping-deploys), Render immediately kicks off the waiting deploy. ### Restarting a service If your service is misbehaving, you can perform a restart from the service's page in the [Render Dashboard](https://dashboard.render.com). Click *Manual Deploy > Restart service*: [image: Restarting a service in the Render Dashboard] On Render, a service restart is actually a special form of [manual deploy](#manual-deploys): - Like any other deploy, Render creates a completely new instance of your service and swaps over to it when it's ready. - This makes restarting a [zero-downtime action](#zero-downtime-deploys). - If your service is [scaled](scaling) to multiple instances, a restart applies to all instances. - _Unlike_ other deploys, the new instance always uses the exact same Git commit and configuration as the running instance at the time of the restart. - This means that if you've recently updated your service's environment variables but haven't redeployed since then, restarting does _not_ incorporate those changes. ### Rolling back a deploy See [Rollbacks](rollbacks). ## Deployment concepts ### Ephemeral filesystem By default, Render services have an *ephemeral filesystem*. This means that any changes a running service makes to its filesystem are _lost_ with each deploy. To persist data across deploys, do one of the following: - Create and connect to a Render-managed datastore (Render [Postgres](postgresql) or [Key Value](key-value)). - Create and connect to a custom datastore, such as [MySQL](/deploy-mysql) or [MongoDB](/deploy-mongodb). - Attach a [persistent disk](disks) to your service. - Note the [limitations of persistent disks](disks#disk-limitations-and-considerations). ### Zero-downtime deploys Whenever you deploy a new version of your service, Render performs a sequence of steps to make sure the service stays up and available throughout the deploy process, even if the deploy fails. This *zero-downtime deploy* sequence applies to web services, private services, background workers, and cron jobs. Static sites _also_ update with zero downtime, but they're backed by a CDN and don't involve service instances. [Learn more about service types.](service-types#summary-of-service-types) > Adding a persistent disk to your service _disables_ zero-downtime deploys for it. [See details.](disks#disk-limitations-and-considerations) #### Sequence of events 1. When you push up a new version of your code, Render attempts to build it. - If the build fails, Render cancels the deploy, and your original service instance continues running without interruption. 2. If the build succeeds, Render attempts to spin up a _new_ instance of your service running the new version of your code. - *For web services and private services,* your _original_ instance continues to receive all incoming traffic while the new instance is spinning up: [diagram] 3. If the new instance spins up successfully (for web services, you can help verify this by setting up [health checks](health-checks)), Render updates your current deployed commit accordingly. - *For web services and private services,* Render also updates its networking configuration so that your _new_ instance begins receiving all incoming traffic: [diagram] 4. After 60 seconds, Render sends a `SIGTERM` signal to your app's process on the _original_ instance. - This signals your app to perform a [graceful shutdown](#graceful-shutdown). 5. If your app's process doesn't exit within its specified *shutdown delay* (default 30 seconds), Render sends a `SIGKILL` signal to force the process to terminate. - You can extend your service's shutdown delay. [See details.](#setting-a-shutdown-delay) [diagram] 6. For web services with [edge caching](web-service-caching) enabled, Render purges all of the service's cache entries. - This helps ensure that clients receive up-to-date content. [See details.](web-service-caching#invalidation-and-expiration) 7. The zero-downtime deploy is complete. *For services that are [scaled](scaling) to multiple instances,* Render performs steps 2-5 for one instance at a time. If _any_ new instance fails to become healthy during this process, Render cancels the entire deploy and reverts to instances running the previous version of your service. ### Graceful shutdown As part of deploying your service to a new instance, Render triggers a shutdown of the _current_ instance by sending your application a `SIGTERM` signal. Your application should define logic to perform a graceful shutdown in response to this signal. Common shutdown actions include: - Responding to remaining in-flight HTTP requests - Completing in-progress worker tasks (or marking them as failed so they're retried by other workers) - Terminating outbound connections to external services - Exiting with a zero status after other cleanup actions are complete If your service is still running after its configured *shutdown delay* (default 30 seconds), Render sends your application a `SIGKILL` signal. This terminates the application immediately with a non-zero status. #### Setting a shutdown delay If your service needs more than 30 seconds to complete a graceful shutdown, you can specify a longer shutdown delay (up to a maximum of 300 seconds) in one of the following ways: - Call the Render API's [Update service](https://api-docs.render.com/reference/update-service) endpoint and set the `maxShutdownDelaySeconds` field to the desired value. - Add the [`maxShutdownDelaySeconds`](blueprint-spec#maxshutdowndelayseconds) field to your service's associated `render.yaml` configuration. - Use this method if you manage your service with a [Blueprint](infrastructure-as-code). --- ##### Appendix: Glossary definitions ###### service type When you deploy code on Render, you select a *service type* based on the capabilities you need. For example, you create a *web service* to host a dynamic web app at a public URL. Related article: https://render.com/docs/service-types.md ###### persistent disk A high-performance SSD that you can attach to a service to preserve filesystem changes across deploys and restarts. Disables [zero-downtime deploys](/deploys#zero-downtime-deploys) for the service. Related article: https://render.com/docs/disks.md ###### build command The command that Render runs to build your service from source. Common examples include `npm install` for Node.js and `pip install -r requirements.txt` for Python. Related article: https://render.com/docs/deploys.md#build-command ###### pre-deploy command If set for a service, Render runs this command just before each of its deploys. Ideal for database migrations and other tasks that should always precede service startup. Related article: https://render.com/docs/deploys.md#pre-deploy-command ###### start command The command that Render runs to start your built service in a newly deployed *instance*. Common examples include `npm start` for Node.js and `gunicorn your_application.wsgi` for Python. Related article: https://render.com/docs/deploys.md#start-command ###### pipeline minutes The amount of time Render spends running *build commands* and *pre-deploy commands* for your services. Your workspace receives a monthly included amount of pipeline minutes. If you exceed this amount, Render bills you for a supplementary amount. Related article: https://render.com/docs/build-pipeline.md ###### web service Deploy this *service type* to host a dynamic application at a public URL. Ideal for full-stack web apps and API servers. Related article: https://render.com/docs/web-services.md ###### private service Deploy this *service type* to host a dynamic application that is not internet-reachable. Ideal for internal apps that only your other Render services can access. Related article: https://render.com/docs/private-services.md ###### background worker Deploy this *service type* to continuously run code that does not receive incoming requests. Ideal for processing jobs from a queue. Related article: https://render.com/docs/background-workers.md