# Deploying on Render

Render can [automatically deploy](#automatic-deploys) your application each time you merge a change to your codebase:

[img]

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](disks)).

## 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:

[img]

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).

> *Services that pull and run a [*prebuilt Docker image*](deploying-an-image) do not support auto-deploys.*
>
> These services do not link a Git branch and must be redeployed [manually](deploys#manual-deploys).

### Configuring auto-deploys

Configure a service's auto-deploy behavior from its *Settings* page in the [Render Dashboard][dboard]:

[img]

Under *Auto-Deploy*, select one of the following options:

| 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, set your service's auto-deploy behavior to *On Commit* instead if you want 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:

[img]

**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 use one of the following in place of `render`:

- `deploy`
- `cd`

When an auto-deploy is skipped, a corresponding entry appears on your service's **Events** page:

[img]

> **For additional control over auto-deploys, you can 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][dboard], open the **Manual Deploy** dropdown:

[img]

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:

[img]

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:

<br/>

[diagram]

<footnote>

\*Consumes [pipeline minutes](build-pipeline#pipeline-minutes) while running. [View your usage.](https://dashboard.render.com/billing#included-usage)

</footnote>

You specify these commands as part of creating your service in the [Render Dashboard][dboard]. You can modify these commands for an existing service from its **Settings** page:

[img]

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**](#build-command)           | 120 minutes |
| [**Pre-deploy**](#pre-deploy-command) | 30 minutes  |
| [**Start**](#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**](build-pipeline#pipeline-minutes) while running.**
>
> You receive an included allotment 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 | Example Build Command(s) |
|--------|--------|
| Node.js | `yarn` `npm install` |
| Python | `pip install -r requirements.txt` |
| Ruby | `bundle install` |
| Go | `go build -tags netgo -ldflags '-s -w' -o app` |
| Rust | `cargo build --release` |
| Elixir | `mix phx.digest` |
| Docker | **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 or [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](disks) (if it has one).

The pre-deploy command is available for paid [web services](web-services), [private services](private-services), and [background workers](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**](build-pipeline#pipeline-minutes) while running.**
>
> You receive an included allotment 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 | `yarn start` `npm start` `node index.js` |
| Python | `gunicorn your_application.wsgi` |
| Ruby | `bundle exec puma` |
| Go | `./app` |
| Rust | `cargo run --release` |
| Elixir | `mix phx.server` |
| 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 | Description |
|--------|--------|
| **Wait** | Allow the in-progress deploy to finish, then proceed directly to the most recently triggered deploy:  [img]  - 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**. |
| **Override** | 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][dboard], open your workspace's **Settings** page.
2. Scroll down to the **Overlapping Deploy Policy** section and click **Edit**:

   [img]

3. Select an option and click **Save changes**.

### Canceling a deploy

You can cancel an in-progress deploy in the [Render Dashboard][dboard]:

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**:

   [img]

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][dboard]. Click **Manual Deploy > Restart service**:

[img]

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).