Launch Checklist
The essential playbook for implementing launch checklist in your SaaS.
Use this checklist before opening your SaaS to real users. It is built for small production deployments where missing one item can cause downtime, broken auth, failed payments, or no visibility into incidents. Keep it as a release gate, not a nice-to-have document.
Quick Fix / Quick Setup
Final pre-launch verification
export APP_URL="https://yourapp.com"
export HEALTHCHECK_URL="$APP_URL/health"
# 1) App responds
curl -I "$APP_URL"
curl -sS "$HEALTHCHECK_URL"
# 2) TLS and DNS
openssl s_client -connect yourapp.com:443 -servername yourapp.com </dev/null 2>/dev/null | openssl x509 -noout -dates
dig +short yourapp.com
dig +short www.yourapp.com
# 3) Basic auth flow
# Manually verify: register, verify email, login, logout, password reset
# 4) Static assets
curl -I "$APP_URL/static/app.css"
# 5) Database migration status
python manage.py showmigrations || alembic current
# 6) Background worker health
ps aux | grep -E "celery|rq|worker"
# 7) Payment webhook endpoint
curl -I "$APP_URL/webhooks/stripe"
# 8) Logging and error tracking
# Trigger a test error route or send a test event to confirm alerts
# 9) Backups
# Confirm latest successful DB backup exists and restore process is documented
# 10) Rollback
# Confirm previous app version, image tag, or release artifact is availableRun this on the production environment and combine it with a manual smoke test using a real browser. For a team of one, this should be part of every launch and major deploy.
What’s happening
A launch checklist reduces preventable failures caused by missing environment variables, broken DNS, incomplete migrations, invalid webhook configuration, or no observability.
Most first-launch issues are not code bugs. They are configuration, infrastructure, or process gaps.
The goal is to verify the full request path:
DNS -> TLS -> reverse proxy -> app -> database -> worker -> external services -> alerts
Deployment Pipeline
Step-by-step implementation
1. Set a launch gate
- Freeze schema changes.
- Merge only launch-critical fixes.
- Create a short release window with enough time for validation and rollback.
- Tag the release in git.
- Record the deploy version, commit SHA, or container image digest.
git tag -a v1.0.0 -m "launch release"
git rev-parse HEAD
docker images --digests2. Verify production environment variables
Confirm production values exist for:
- app secret
- database URL
- SMTP or email provider keys
- payment keys
- webhook secrets
- storage credentials
- Sentry DSN
- allowed hosts
- CORS settings
- cookie settings
Quick check on host:
env | sortExample app config targets:
APP_ENV=production
APP_URL=https://yourapp.com
DEBUG=false
DATABASE_URL=postgres://user:pass@db:5432/app
SECRET_KEY=replace-me
ALLOWED_HOSTS=yourapp.com,www.yourapp.com
SESSION_COOKIE_SECURE=true
CSRF_COOKIE_SECURE=true
COOKIE_DOMAIN=.yourapp.com
STRIPE_SECRET_KEY=sk_live_...
STRIPE_WEBHOOK_SECRET=whsec_...
SENTRY_DSN=https://...
SMTP_HOST=smtp.provider.com
SMTP_USER=...
SMTP_PASSWORD=...Do not launch with test secrets, localhost callback URLs, or incomplete cookie settings.
3. Verify domain, DNS, and TLS
Confirm apex and www records point to the correct server or load balancer.
dig +short yourapp.com
dig +short www.yourapp.comCheck certificate validity:
openssl s_client -connect yourapp.com:443 -servername yourapp.com </dev/null 2>/dev/null | openssl x509 -noout -datesCheck redirect behavior:
curl -I http://yourapp.com
curl -I https://yourapp.comExpected:
- DNS resolves correctly
- HTTPS works
- certificate is valid
- HTTP redirects to HTTPS if required
4. Verify reverse proxy and app process health
Check Nginx, app server, containers, or systemd services.
systemctl status nginx
systemctl status gunicorn
journalctl -u nginx -n 200 --no-pager
journalctl -u gunicorn -n 200 --no-pagerDocker-based setup:
docker ps
docker logs <container_name> --tail 200Health endpoint:
curl -sS https://yourapp.com/healthExpected:
- proxy is forwarding to the correct port
- app process is running
- no crash loops
- health endpoint returns success
5. Run and verify database migrations
Apply migrations and verify status.
python manage.py showmigrations || true
alembic current || trueIf using Django:
python manage.py migrate
python manage.py showmigrationsIf using Alembic:
alembic upgrade head
alembic currentAlso confirm the app starts cleanly against the migrated schema.
Do not launch if:
- migrations were run against the wrong database
- app startup logs show schema mismatch
- new code depends on columns not yet present
6. Validate static and media file handling
Check CSS, JS, images, and uploads.
curl -I https://yourapp.com/static/app.cssIf using object storage, verify bucket permissions and application URLs. If uploads are part of the MVP, test one real upload and retrieval.
Expected:
- static files return
200 - cache headers are reasonable
- media upload path is correct
- no mixed local/cloud storage assumptions
7. Run auth smoke tests
Manually test:
- register
- email verification
- login
- logout
- protected route access
- password reset
- session persistence
- role-based access if used
Check for:
- correct callback URLs
- secure cookies
- correct session domain
- CSRF success behind proxy
- correct
ALLOWED_HOSTSand CORS behavior
If auth is still not fully verified, use Auth System Checklist.
8. Run payment smoke tests
If billing is enabled, test:
- pricing page
- checkout session creation
- successful payment
- webhook delivery
- subscription activation
- failed payment path
- customer portal or cancel flow
Basic endpoint check:
curl -I https://yourapp.com/webhooks/stripeConfirm:
- live keys are loaded
- test keys are removed from production
- product and price IDs are correct
- webhook secret matches the production endpoint
- billing state updates after webhook delivery
If payments are in scope, use Payment System Checklist.
9. Verify background jobs and scheduled tasks
Check worker health:
ps aux | grep -E "celery|rq|worker"Also verify:
- queued jobs are consumed
- retries are visible
- scheduled tasks are running
- email sending works from production
- webhook processing is not stuck behind a dead worker
If using systemd or Docker, inspect logs directly for worker services.
10. Confirm monitoring, logs, and alerts
At minimum, verify:
- application logs available
- server logs available
- uptime checks active
- error tracking active
- alert delivery works to a real inbox or chat
Useful checks:
curl -I https://yourapp.com
journalctl -u nginx -n 200 --no-pager
journalctl -u gunicorn -n 200 --no-pagerTrigger a test error route or send a test event to Sentry or your alerting system.
If observability is incomplete, use Monitoring Checklist.
Suggested visual: launch dashboard screenshot with logs, Sentry, uptime status, and payment webhook deliveries side by side.
11. Confirm backups and restore readiness
Verify:
- automated database backups exist
- latest successful backup timestamp is recent
- file storage backup policy is defined if needed
- restore procedure is documented
- recent restore drill exists if possible
Minimum rule: no backups means no launch.
12. Validate security and production settings
Check:
- debug mode disabled
- trusted hosts configured
- secure cookies enabled
- CSRF settings correct
- admin routes restricted
- rate limits configured where needed
- no public test credentials
- firewall rules are correct
- only required ports are open
Example target settings:
DEBUG=false
SESSION_COOKIE_SECURE=true
CSRF_COOKIE_SECURE=true
SECURE_PROXY_SSL_HEADER=X-Forwarded-Proto,https
ALLOWED_HOSTS=yourapp.com,www.yourapp.com13. Run manual browser smoke tests
Test core pages on desktop and mobile widths:
- landing
- signup
- login
- dashboard
- billing
- logout
- error page
Use a fresh account and a real email inbox. Validate one happy path and one failure path for auth and billing.
14. Prepare rollback before launch
Confirm:
- previous release artifact exists
- previous image tag or digest is available
- rollback command is documented
- migration rollback or compatibility plan exists
- launch owner is assigned
Example release records to keep:
Release tag: v1.0.0
Commit SHA: abc1234
Container image: registry/app@sha256:...
DB migration version: 20260420_add_subscriptions
Rollback owner: you@example.com15. Launch with active observation
For the first 30 to 60 minutes:
- tail logs
- watch error tracking
- watch response times
- confirm signup completion
- confirm payment events
- confirm background jobs run
- be ready to rollback immediately
Before this page, run Deployment Checklist. For a wider go-live gate, use SaaS Production Checklist.
Common causes
- Missing or incorrect production environment variables
- Wrong DNS records or incomplete domain setup
- Invalid TLS certificate or missing HTTP to HTTPS redirect
- Broken reverse proxy configuration between Nginx and app server
- Pending or failed database migrations
- Static or media files not served from the expected path
- Session cookie, CSRF, or callback URL misconfiguration causing auth failures
- Background worker or scheduler not running
- Stripe live keys, webhook secret, or product IDs misconfigured
- No active monitoring, alerts, or tested backup restore path
Debugging tips
Check the deployed environment directly. Do not assume CI variables match server variables.
Inspect response headers for redirects, cookies, cache-control, and proxy behavior.
Follow logs in real time during smoke tests and during the first launch window.
Use provider dashboards for email, payments, DNS, and storage to confirm events arrive there.
Test with a fresh user account and a real email inbox.
Validate one happy path and one failure path for auth and billing before launch.
Useful commands:
curl -I https://yourapp.com
curl -sS https://yourapp.com/health
openssl s_client -connect yourapp.com:443 -servername yourapp.com </dev/null 2>/dev/null | openssl x509 -noout -dates
dig +short yourapp.com
dig +short www.yourapp.com
systemctl status nginx
systemctl status gunicorn
docker ps
docker logs <container_name> --tail 200
journalctl -u nginx -n 200 --no-pager
journalctl -u gunicorn -n 200 --no-pager
python manage.py showmigrations
alembic current
ps aux | grep -E "celery|rq|worker"
curl -I https://yourapp.com/static/app.css
df -h
free -m
env | sortSuggested visual: launch dashboard screenshot with logs, error tracking, uptime monitor status, and webhook deliveries in one view.
Checklist
- ✓ Production domain resolves correctly
- ✓ TLS certificate valid and auto-renew configured
- ✓ App health endpoint returns success
- ✓ Debug mode disabled
- ✓ Secrets loaded from environment or secret manager
- ✓ Database migrations applied successfully
- ✓ Backups configured and latest backup verified
- ✓ Rollback path documented and previous release available
- ✓ Static files load correctly
- ✓ Media uploads work correctly
- ✓ Email sending works from production
- ✓ Register/login/logout/password reset verified
- ✓ Protected routes enforce auth correctly
- ✓ Payment checkout works with live configuration
- ✓ Webhook delivery succeeds and updates subscription state
- ✓ Background jobs and scheduled tasks are running
- ✓ Application logs available
- ✓ Error tracking receives events
- ✓ Uptime monitor is active
- ✓ Alerts reach a real inbox or chat channel
- ✓ Admin routes restricted
- ✓ Rate limits or abuse protection configured where needed
- ✓ Privacy, terms, and support contact pages are accessible if required
- ✓ Manual smoke test completed on critical pages
- ✓ Launch owner assigned for first-hour monitoring
Related guides
- SaaS Production Checklist
- Deployment Checklist
- Auth System Checklist
- Payment System Checklist
- Monitoring Checklist
FAQ
What is the minimum viable launch checklist for a small SaaS?
Verify DNS, HTTPS, app health, migrations, auth flows, payment flows if used, worker health, logs, error tracking, uptime monitoring, backups, and rollback.
Should I launch on Friday?
Usually no. Launch when you can actively monitor and fix issues immediately.
Do I need live payment testing before launch?
Yes. Use a controlled real flow or a fully verified test process plus webhook validation before public launch.
What if I cannot test rollback?
Do not launch until you at least confirm the previous release artifact exists and the rollback steps are documented and executable.
Which checks catch the most production issues?
Health endpoint, real browser smoke tests, live log tailing, webhook delivery checks, and verifying environment variables on the production host.
Should I launch without monitoring?
No. At minimum, enable uptime checks, application logs, and error tracking before real traffic.
Do I need a staging environment?
Helpful, but not mandatory for very small SaaS products. If you skip staging, production smoke tests and rollback discipline matter more.
Should I run migrations before or after deploy?
Usually during deploy, with a plan for backward-compatible schema changes if zero-downtime matters.
Can I launch without backups?
No. At minimum, have automated DB backups and a written restore procedure.
How long should I monitor after launch?
Actively watch the first 30 to 60 minutes, then review logs and metrics again within 24 hours.
Final takeaway
A launch is safe when core flows are verified end to end, observability is active, and rollback is ready.
For small SaaS products, the biggest launch risk is missing production configuration, not writing insufficient code.
Treat this checklist as a hard gate for every launch, not just the first one.