Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 105 additions & 0 deletions sites/upsun/src/learn/overview/app-life-cycle.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
---
title: The application lifecycle
weight: 3
description: "Understand the {{% vendor/name %}} application lifecycle and learn how to use build, deploy, and runtime hooks to control app behavior"
---
<!-- vale off -->
Hooks let you run custom commands at specific points in your application’s lifecycle: during [`build`, `deploy`](/learn/overview/build-deploy.html), and at `runtime`. They’re essential for setting up your app, managing graceful shutdowns, or preparing instances to handle traffic in autoscaling environments.

Each web application on {{% vendor/name %}} can define web commands inside its `.upsun/config.yaml` file:

```yaml
applications:
myapp:
type: 'python:3.13'
web:
commands:
pre_start: "./scripts/setup.sh"
start: "uwsgi --ini conf/server.ini"
post_start: "./scripts/warm-up.sh"
```
## Web commands


| Name | Type | Required | Blocks Traffic | Description |
|---------------|--------|----------|------------------|-------------|
| **pre_start** | string | No | No | Runs just before `start`. Useful for short per-instance setup actions, such as moving cache files or setting permissions. |
| **start** | string | Yes | Yes (until running) | The main command that launches your app. The instance cannot serve traffic until `start` is successfully running. If it terminates, {{% vendor/name %}} restarts it immediately. |
| **post_start**| string | No | Yes (until completed) | Runs after the `start` command but *before* the container is added to the router. Instances will not receive traffic until this script completes successfully, making it ideal for warm-up tasks that must finish before the app begins handling requests. |

For more information about web commands, visit the [Single-runtime Image page](/create-apps/app-reference/single-runtime-image.html#web-commands).

{{< note theme="info" title="Blocking vs. non-blocking hooks" >}}

A hook is considered *blocking* if the instance cannot receive traffic until that hook finishes successfully.

- `start` blocks traffic until the application is running.
- `post_start` blocks traffic until all warm-up tasks complete.

Non-blocking hooks, such as `pre_start`, run before traffic concerns and do not affect when an instance begins receiving requests.

{{< /note >}}


## Lifecycle overview

Every application instance follows the same start-up flow:

- Pre-start prepares each instance before launch.
- Post-start completes warm-up tasks before the instance is routed into live traffic.

![The steps in the start-up flow](/images/hook-cycle.png "0.50")

This structure ensures applications can start cleanly, scale horizontally, and serve requests reliably, especially in autoscaling environments.

## Use cases

| Hook | When to use | Example task |
|------|--------------|----------------|
| **pre_start** | For configuration and prep that must complete before your app starts | Moving cache, updating file permissions |
| **post_start** | For initialization after your app starts but before it serves traffic | Cache warming, dependency loading |

### Autoscaling example

When autoscaling [adds new instances](/manage-resources/autoscaling.html#thresholds), each instance must start and warm up before serving live requests. Use `post-start` to complete initialization tasks such as:

- Cache priming or session loading
- Running lightweight readiness checks
- Loading config or dependencies into memory

This ensures new instances are ready to perform immediately when the router adds them.

{{< note theme="tip" title="Autoscaling" >}}

For more information about Autoscaling, visit the [Autoscaling docs page](/manage-resources/autoscaling.html).

{{< /note >}}

### Zero-downtime example

If your [application takes longer to become responsive](/learn/overview/build-deploy.html#application-is-slow-to-start), traffic might be switched back to your original application before it’s fully ready. This can cause temporary errors immediately after deployment.

If your framework needs time to initialize, `post_start` can help co-ordinate so the app receives traffic only when it’s ready. An example of a `post_start` command waiting for your application would be:

```
web:
commands:
post_start: |
date
curl -sS --retry 20 --retry-delay 1 --retry-connrefused localhost -o /dev/null
```
{{< note theme="info" title="Zero Downtime Deployment" >}}

For more information about Zero Downtime Deployment, visit the [build deploy documentation page](/learn/overview/build-deploy.html#zero-downtime-deployments).

{{< /note >}}

## Related content

- [Build and Deploy overview](/learn/overview/build-deploy.html)
- [Autoscaling](/manage-resources/autoscaling.html)
- [Single-runtime Image reference](/create-apps/app-reference/single-runtime-image.html#web-commands)
- [Zero-downtime deployments](/learn/overview/build-deploy.html#zero-downtime-deployments)


<!-- vale on -->
Binary file added sites/upsun/static/images/hook-cycle.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading