---
title: Zero-Downtime Deploys
url: "/docs/apps/zero-downtime-deploy/"
canonical_url: https://docs.blossom88.com/docs/apps/zero-downtime-deploy/
markdown_url: https://docs.blossom88.com/docs/apps/zero-downtime-deploy.md
summary: Ship new versions without interrupting your users
categories:
- deployment
- health-checks
---

# Zero-Downtime Deploys

Add a health check so Blossom waits for your new version before switching traffic. New
Containers start next to the current ones and take traffic only once your App
answers its health check. The old version keeps serving until then, and if
the new one never gets healthy, the deploy stops while the old version keeps serving.

The health check is how Blossom knows your App is ready, not just started.
Without one, a new Container takes traffic as soon as its process starts,
which can be before your App finishes booting.

Existing connections get time to finish during the handoff. Long-lived
connections should reconnect when a Container is retired.

## Add A Health Check

Give the Service an endpoint that answers 200 when it's ready, then turn on
its Health Check under the Service's settings:

```yaml
Check: HTTP request
Path: /health
Timing: every 5s, wait up to 5s, unhealthy after 6 failures
```

Blossom uses that one check everywhere: a new release goes live only after it
passes, and a Container that keeps failing is replaced. Turn on **Also take a
failing Container out of traffic** to have the load balancer stop routing to
a Container while it fails.

A worker without a port uses a **Command** check: a command that exits 0 when
healthy.

## Health Endpoint Examples

Keep the endpoint fast, and don't depend on other services such as the
database, so a slow dependency doesn't take your App out of traffic.

### Rails

```ruby
# config/routes.rb
get '/health', to: 'health#show'

# app/controllers/health_controller.rb
class HealthController < ApplicationController
  def show
    render plain: 'ok', status: :ok
  end
end
```

### Node.js/Express

```javascript
app.get("/health", (req, res) => {
  res.status(200).send("ok");
});
```

### Python/Django

```python
# views.py
from django.http import HttpResponse

def health_check(request):
    return HttpResponse("ok", status=200)
```

## What You Get

- New versions go live only once they're healthy
- The current version serves while the replacement passes readiness checks
- Failing Containers replaced and, if you choose, taken out of traffic

See [Deploy Hooks](/docs/apps/deploy-hooks/) to run migrations
before a release goes live.
