A receipt for every rollout
Every Kamal role, not just web. Expected version against what’s actually running, health checks, and a before and after for errors and response time.
Production monitoring for Kamal apps
A receipt for every rollout. One calm overview of every app, server, and database. A message in Slack or Discord when something actually needs you.
Free plan · No card required · Read-only by design
Storefront · production
a84fd21 → c3e917b
p95
182 → 176 ms
Errors
0.1% → 0.1%
Queue wait
0.4 s
Elsewhere: one thing needs you
The nightly backup hasn’t checked in. An alert went to #ops.
Read-only. Never deploys or runs commands
Outbound HTTPS only. Opens no ports
Any provider. Your servers stay yours
No app changes needed to start
How it works
Run the Upstate CLI inside a Kamal project. It shows every change before it makes one, then gets out of your way.
It adds deploy hooks next to your existing .kamal/hooks, and installs a small observer on each server as a systemd service, so nothing about Upstate lands in your deploy.yml. Prefer a Kamal accessory? That’s one flag.
A hook tells Upstate which version you’re shipping. The observer separately reports which version is actually running.
Minutes later the deploy is Verified, or Upstate shows which container didn’t update and which check failed. In the browser, or with upstate receipt.
$ brew install upstate-run/tap/upstate
$ upstate connect
Found config/deploy.yml · roles: web, jobs · 2 servers
How should the observer run?
› 1. systemd service (recommended)
2. Kamal accessory
Shows every command first · asks before it changes anything
✓ Hooks added · observers reporting
$ kamal deploy
…
$ upstate receipt
✓ Verified c3e917b · web 2/2 · jobs 1/1 · p95 176 ms
What Upstate watches
Every Kamal role, not just web. Expected version against what’s actually running, health checks, and a before and after for errors and response time.
Apps, roles, servers from any provider, accessories, and the managed databases they depend on. Current health, resource pressure, and the monthly costs you enter.
Slack, Discord, email, or your own webhook. Choose which apps go to each channel. A recovery message closes the loop.
Give backups and scheduled jobs a check-in URL. Upstate notices late, failed, and stuck runs. A check-in shows a job reported success; it doesn’t replace a restore test.
TLS certificates on your HTTPS checks, plus domain expiry when public registration data is available. Unknown dates stay clearly marked.
Verified deploys, alerts, server usage, check-ins, and upcoming expiry in one weekly email. A quiet week still has something to show for it.
App health
For any Kamal app, Upstate reads kamal-proxy’s request log on your server and shows request rate, errors, and response time. Every deploy gets a before and after, and a regression raises an alert. Nothing to install in your app.
Counts and timings only. No request bodies, no job arguments, no customer data.
For you and your coding agent
Database ports open to the world, job roles with no health check, a Postgres accessory with no volume. Upstate flags the settings that quietly cause trouble, explains why each matters, and says plainly what it couldn’t check.
Every finding comes with a ready-made prompt for your coding agent. Connect Claude Code, Codex, or another MCP client and they can read your production evidence too, with read-only access you approve per account.
Install with
brew install upstate-run/tap/upstate
or download a verified binary.
upstate audit --local
Audit the Kamal config in this checkout. No account, no network, nothing uploaded.
upstate audit
Compare your config with what’s actually running, and keep the findings next to your deploy history.
upstate audit --hosts
SSH settings, open ports, security updates, and pending reboots, over your own SSH access. You approve each run; nothing is changed.
Your infrastructure stays yours
Upstate never deploys, restarts containers, or runs commands on your servers. The observer reports over outbound HTTPS, opens no ports, accepts no commands, and uses its own revocable credential. As a systemd service it runs as a locked-down, non-root user.
The CLI changes a server only when you run it, after showing its plan and asking first.
The observer reads the Docker socket. That’s privileged access even when mounted read-only, so install it only on servers you run.
CPU, memory, and disk usage; container state and image versions; health results; request counts and timings from kamal-proxy; selected Docker facts and labels; and basic cloud provider identity when available.
Container environment values, database contents, and application files. Application logs stay local by default.
Enable snapshots separately for the account and each server to see recent container logs. Tails are bounded, redacted before upload and again before storage, encrypted, and deleted after 72 hours. Redaction can’t catch every secret; opt in only for logs you’re authorized to share.
Pricing
Priced by what you run, not where it runs. Free watches 5 components (a typical Rails app with jobs, Postgres and Redis) on up to 3 servers. Solo watches 30 for $19. Not per server.
Paid Solo checkout is coming soon. Free is open now.
$0 / month
5 components · 7 days of history · up to 3 servers
Deploy receipts, app health, HTTP and certificate checks, account email alerts plus 1 chat or webhook destination, 3 check-ins, and the weekly digest.
Start free$19 / month
30 components · 90 days of history
Everything in Free, plus 10 notification destinations, 50 check-ins, slowest Rails actions, and on-demand log snapshots.
Your latest production receipt stays available on every plan. Full pricing, including component packs
Keep your servers and your deploy workflow. Add an overview that tells you what needs attention, with receipts to back it up.
Get started freeWe can't find the internet
Attempting to reconnect
Something went wrong!
Attempting to reconnect