Skip to main content
Before you send production traffic to a new application, run through this checklist. It walks through the Sevalla features that most directly affect uptime, resilience, and recoverability - health checks, deployment automation, scaling, networking, and backups - so your first day in production goes smoothly. Use it as a final pass after your application is already deploying successfully, and before you point real users at it.

1. Configure health checks

Health checks are the single most important reliability feature to enable before go-live. Without them, Sevalla has no way to know if your application is actually able to serve traffic, or if it has silently hung. Two probes are available per process:
  • Readiness probe - determines whether the process should receive traffic. If it fails, the process is temporarily taken out of rotation until it passes again.
  • Liveness probe - determines whether the process is still functioning. If it fails, the process is automatically restarted.
For each probe you can configure a custom path and port, which is useful if your app exposes a dedicated /healthz-style endpoint on a separate port from your main web traffic. Checklist:
  • Web process has a readiness probe pointing at a real endpoint (not just /)
  • Liveness probe is configured if your app can end up in a hung/deadlocked state
  • Health check endpoint doesn’t depend on downstream services that could cause cascading restarts (e.g., don’t fail your liveness check just because a third-party API is slow)
Beyond the configurable probes, Sevalla also runs its own background healthcheck monitoring during runtime: your app’s healthcheck path is checked every 10 seconds, and if it fails to respond three times in a row, the pod is restarted automatically. This runs independently of deploy events, so a healthy healthcheck endpoint protects you during normal operation, not just during rollouts.

2. Use pipelines to control how code reaches production

If you’re deploying straight from a branch to production, you’re skipping one of the platform’s main safety mechanisms. Pipelines let you formalize the path code takes from commit to production and add gates along the way. Two pipeline models are available:
  • Trunk-based development - a development-stage application can be promoted into one or more separate production applications. Promotion can be triggered manually or via the API, making it straightforward to wire into external CI/CD tools like GitHub Actions.
  • Git Flow - models separate branches for development, staging, and production directly in the platform, with deployments firing automatically on push to each branch.
Either model supports adding intermediate stages (e.g. a QA stage) and enabling preview apps, which spin up a live environment for a pull request so changes can be tested in isolation before merging. Checklist:
  • Production deploys go through at least one intermediate stage (QA/staging), not directly from a feature branch
  • Promotion between stages is deliberate (manual click, PR merge, or API call) rather than automatic-everywhere
  • Preview apps are enabled if your team reviews changes before merging
  • Automatic deployments are explicitly enabled/disabled per stage as intended - check this in each application’s Settings, since it’s easy to leave a stage on auto-deploy by accident
  • Database migrations run as a separate job process with the right start policy (e.g. before deployment), not appended to the web process’s start command
Running migrations as a dedicated job process, rather than as part of your web process’s start command, means a failed migration blocks the deployment instead of crash-looping your web process, and gives you explicit control over whether migrations run before or after the new version goes live.

3. Set up autoscaling and right-size your resources

Every process has a Resource setting (CPU/RAM) and an optional horizontal auto-scaling setting. If auto-scaling is enabled, you define a minimum and maximum instance count for the web process. When CPU or memory usage on the current pod(s) crosses its target (80% by default, adjustable), an additional instance is added, up to your configured maximum. When usage drops, instances are scaled back down - never below your configured minimum. Before go-live, decide deliberately rather than leaving this on defaults: Checklist:
  • Pod size (CPU/RAM) is based on real load testing, not a guess
  • Horizontal auto-scaling is enabled for stateless web processes that expect variable traffic
  • Minimum instance count is at least 2 for anything customer-facing, so a single pod restart doesn’t cause a full outage
  • Maximum instance count is set high enough to absorb a traffic spike, but with an eye on cost
  • CPU/memory scaling targets are reviewed rather than left at the 80% default if your app has unusual usage patterns (e.g. memory-heavy but CPU-light)
  • Application Analytics (Applications > your app > Analytics) has been checked under real load to confirm the pod size and scaling settings actually hold up - it breaks down CPU, memory, HTTP requests, and instance count per process
See Scalability for more on configuring vertical and horizontal scaling.

4. Lock down domains, SSL, and environment configuration

  • Custom domains: every verified custom domain is automatically covered by a free SSL certificate through Sevalla’s Cloudflare integration (TLS 1.2/1.3). Only add a custom SSL certificate if you have a specific compliance or certificate-authority requirement - it isn’t needed for standard HTTPS.
  • CDN: if your application relies on Cache-Control headers to make static assets cacheable, turn on the CDN (Applications > your app > Networking > CDN & Edge caching) so Cloudflare’s edge network actually honors them. The CDN is not enabled by default.
  • Environment variables and secrets: confirm these are set in the application’s Environment Variables tab rather than committed to the repo. If you use a framework where some variables are inlined at build time (for example, any client-exposed/public variables), make sure those are set before the build runs, not only as runtime values - a value added after the last build won’t retroactively appear in an already-built bundle.
  • Ephemeral filesystem: the container filesystem does not persist across redeploys or pod restarts. Anything your app writes to local disk at runtime (uploads, generated files, on-disk caches, SQLite files) will be lost. If you need it to persist, prefer moving it to object storage over attaching a persistent storage disk before go-live - not after you lose data.
Checklist:
  • Production domain is added and shows a verified SSL status
  • CDN is enabled if your app serves cacheable static assets with Cache-Control headers
  • All required environment variables/secrets are set in Sevalla, not .env files in the repo
  • Any local disk writes your app performs are backed by object storage, persistent storage, or other external storage
  • DNS/verification records that Sevalla needs (e.g. _acme-challenge) are set to DNS-only rather than proxied, so certificate renewal doesn’t silently fail later
Anything your app writes to local disk at runtime is lost on every redeploy or pod restart. Attach persistent storage or move writes to object/external storage before go-live, not after you lose data. Prefer object storage over a persistent storage disk wherever possible: persistent storage pins a process to a single instance and blocks horizontal scaling entirely (no auto-scaling, no multi-instance scaling), while object storage keeps your web and background processes stateless and free to scale horizontally.

5. Confirm database resilience

If your application uses a Sevalla-hosted database:
  • Databases are backed up automatically once a day, with each automatic backup retained for 7 days.
  • You can also take up to 5 manual backups, retained for 14 days - useful immediately before a risky migration or schema change.
  • Backups can be restored either into the same database or into a different one (the target must be in the same data center), which makes it possible to test a restore without touching production.
  • If your application and database are both hosted on Sevalla, set up an internal/private connection between them. Traffic stays inside Sevalla’s network, which is faster, doesn’t incur internal bandwidth cost, and avoids exposing the database on the public internet.
Checklist:
  • Application connects to the database over the internal/private connection, not a public endpoint
  • You’ve taken at least one manual backup and confirmed you know how to restore it, before you need to do it under pressure
  • Anyone who might need to restore a backup knows where the Backups page is and what “restore to a different database” does (it does not touch your live database)

6. Turn on failure notifications

Set up email notifications for failed deployments under your username > User settings > Notifications. Combined with the runtime healthcheck monitoring described in step 1, this closes the loop: healthchecks catch runtime problems automatically, and deployment notifications catch problems introduced by a bad release before you find out from a user. Checklist:
  • Failed-deployment email notifications are turned on for at least one team member who can act on them
  • It’s clear who is responsible for responding when a notification fires

Go-live summary

This list isn’t exhaustive for every application type (queues, cron jobs, and multi-service pipelines each add their own considerations), but covers the checks that most commonly turn a rough launch into a smooth one.