How to Install Ntfy on Ubuntu 24.04 VPS — Self-Hosted Push Notifications
When a server crashes at 3 a.m., when your backup job finishes, when your doorbell camera detects motion, when a GitHub Action fails -- you want to know immediately, on the device in your pocket, without paying a SaaS per-device fee or exposing data to a third party. Self-hosted push notifications solve this, and ntfy is the most ergonomic tool for the job. This guide walks you through installing ntfy on an Ubuntu 24.04 VPS, configuring authentication and ACLs, enabling iOS push support, and wiring it up to Home Assistant, Alertmanager, webhooks, and plain curl.
Skip the setup? Our Starter VPS plan gives you 2 vCPU, 4 GB RAM, and 50 GB NVMe for EUR 7.99/month -- plenty for a self-hosted ntfy instance plus monitoring and reverse proxy.
Table of Contents
What is Ntfy?
Ntfy (pronounced "notify") is an open-source HTTP-based pub-sub notification server. Publishers send messages to a named topic with a single HTTP request; subscribers listening on that topic receive the message instantly on any platform -- Android, iOS, web, desktop, or raw CLI. There are no SDKs to pull in, no access tokens to rotate per client, and no protocol to learn. If you can run curl, you can publish a notification:
curl -d "Backup finished" https://ntfy.yourdomain.com/backupsThat single line reaches every device subscribed to the backups topic. This simplicity is what makes ntfy irreplaceable for infrastructure work. Cron jobs, shell scripts, Kubernetes hooks, CI pipelines, and even smart home devices can publish notifications without any client library. The full API and documentation live at docs.ntfy.sh.
Ntfy supports rich features beyond plain text: priority (min through max, with urgent bypassing Do Not Disturb), tags that render as emoji, action buttons that trigger HTTP calls or open URLs, file attachments, click actions, markdown formatting, scheduled delivery, and email forwarding. Every feature except phone-call delivery works in the open-source self-hosted binary.
Typical use cases include disk space and backup alerts, Uptime Kuma downtime pings, motion detection from security cameras, CI/CD failures, Prometheus Alertmanager routing, and webhook receivers for GitHub, GitLab, or Stripe. Many individuals adopt it as a private replacement for Pushover or Pushbullet.
Why Self-Host Push Notifications?
Managed notification services work until they don't. Once you have more than a few devices or push mildly sensitive content, the tradeoffs bite:
- Data privacy -- Alerts contain server names, IPs, error messages, customer IDs. Self-hosting keeps all of it on infrastructure you control.
- No per-device licensing -- Pushover charges per platform. Pushbullet caps free accounts at 100 messages/month. Ntfy has no artificial caps.
- Unlimited topics -- Create one per server, environment, or customer. Topics are zero-cost and created on first publish.
- Control over retention -- Configure message cache duration, attachment size, and expiry to meet GDPR and internal policies.
- Reliable under your SLA -- You decide uptime and restart windows.
- Works in air-gapped networks -- Runs entirely inside a VPN if needed.
- Integrates with anything -- The publish API is plain HTTP, so every tool already supports it.
CloudCore / Starter Pricing for Ntfy
Ntfy's resource footprint is tiny, which makes it perfect for an entry-level VPS:
| Plan | vCPU | RAM | Storage | Monthly | Best for |
|---|---|---|---|---|---|
| Starter | 2 | 4 GB | 50 GB NVMe | EUR 7.99 | Personal use, homelab, up to ~1,000 subscribers |
| CloudCore Professional | 6 | 12 GB | 100 GB NVMe | EUR 19.99 | Small team, CI/CD alerts, 5k-10k subscribers |
| CloudCore Business | 8 | 24 GB | 200 GB NVMe | EUR 29.99 | Multi-service alerting, large topic list, 10k+ subscribers |
Ntfy vs. Pushover vs. Pushbullet vs. Gotify
| Feature | Ntfy (self-hosted) | Pushover | Pushbullet | Gotify |
|---|---|---|---|---|
| License | Apache 2.0, open source | Proprietary SaaS | Proprietary SaaS | MIT, open source |
| Self-hostable | Yes | No | No | Yes |
| Per-device cost | Free | USD 5 one-time per platform | Free (limited) / USD 5/mo Pro | Free |
| Publish API | curl -d "msg" URL/topic | Token + user key required | OAuth + SDK | App token required |
| Topic model | Public or ACL-protected topics | Delivery groups | Device-to-device | Applications |
| iOS support | Yes (via upstream APNs) | Yes | Yes (Pro) | No native app (third-party) |
| Android support | Native app | Native app | Native app | Native app |
| Web subscribe UI | Yes (built-in) | Limited | Limited | Yes |
| Attachments | Yes, up to configured limit | Images only | Files up to 25 MB | Yes (via message URL) |
| Priorities | 5 levels | 5 levels | None | 0-10 scale |
| Action buttons | Yes | Yes (paid) | No | No |
| Webhook receiver | Any HTTP client | Requires Pushover format | Proprietary format | Requires Gotify format |
| Typical use | Infra alerts, scripts, smart home | Personal reminders | Cross-device sync | Simple self-hosted alerts |
If you need a native iOS app, server-side topics, and publish-by-curl, ntfy is the right choice.
Prerequisites
Before starting, you need:
- A VPS running Ubuntu 24.04 LTS with root or sudo access
- SSH access to your server
- At least 1 GB of RAM (4 GB recommended for headroom)
- At least 10 GB of free disk space (more if you plan heavy attachment use)
- A domain name pointing to your VPS (required for TLS and iOS push support) -- configure an A record like
ntfy.yourdomain.com-> your VPS IP - Ports 80 and 443 open in your firewall for HTTP and HTTPS
Recommended Plan: Starter>
The Starter VPS plan is perfect for ntfy:>
- 2 vCPU cores
- 4 GB RAM
- 50 GB NVMe SSD
- Unmetered bandwidth
- EUR 7.99/month>
That leaves room for ntfy, Caddy, a monitoring agent, and several other light services on the same box.
Connect to your server:
ssh root@your-server-ipStep 1: Update System Packages
Always start with a fresh package index and latest security patches:
sudo apt update && sudo apt upgrade -yInstall a few helper utilities you will need throughout the guide:
sudo apt install -y curl ca-certificates gnupg apt-transport-https debian-archive-keyringIf your kernel was updated, reboot:
sudo rebootReconnect after a minute.
Step 2: Add the Heckel.io APT Repository
Ntfy is developed by Philipp Heckel, who publishes signed Debian packages via his apt repository at archive.heckel.io. Adding this repo gives you reliable, versioned upgrades through apt upgrade going forward.
Create the keyring directory and import the GPG key:
sudo install -d -m 0755 /etc/apt/keyrings
curl -fsSL https://archive.heckel.io/apt/pubkey.txt | sudo gpg --dearmor -o /etc/apt/keyrings/archive.heckel.io.gpgAdd the repository to your sources:
sudo tee /etc/apt/sources.list.d/archive.heckel.io.list > /dev/null <<'EOF'
deb [arch=amd64 signed-by=/etc/apt/keyrings/archive.heckel.io.gpg] https://archive.heckel.io/apt debian main
EOFOn ARM64 hosts (Ampere, AWS Graviton), change arch=amd64 to arch=arm64.
Refresh the package index:
sudo apt updateExpected output (abbreviated):
Get:1 https://archive.heckel.io/apt debian InRelease [3,000 B]
Get:2 https://archive.heckel.io/apt debian/main amd64 Packages [5,000 B]
Reading package lists... DoneStep 3: Install Ntfy
With the repo configured, install the ntfy package:
sudo apt install -y ntfyExpected output:
Setting up ntfy (2.11.0) ...
Created symlink /etc/systemd/system/multi-user.target.wants/ntfy.service -> /lib/systemd/system/ntfy.service.The installer creates:
/usr/bin/ntfyntfy/etc/ntfy/server.yml/lib/systemd/system/ntfy.service/var/cache/ntfyVerify the version:
ntfy --versionExpected output:
ntfy version 2.11.0 (c3db03a, runtime=go1.22.3, built=2026-03-20T14:22:11Z)Do not start the service yet -- we want to edit server.yml first.
Step 4: Configure server.yml
The default config file is heavily commented. Back it up before editing:
sudo cp /etc/ntfy/server.yml /etc/ntfy/server.yml.bakReplace it with a production-oriented baseline:
sudo tee /etc/ntfy/server.yml > /dev/null <<'EOF'
Public base URL of your ntfy instance
base-url: "https://ntfy.yourdomain.com"Listen on all interfaces, port 2586 (we'll put Caddy in front)
listen-http: ":2586"Behind a reverse proxy, trust X-Forwarded-For
behind-proxy: trueWhere to store the sqlite message cache and how long to keep messages
cache-file: "/var/cache/ntfy/cache.db"
cache-duration: "12h"Attachment storage
attachment-cache-dir: "/var/cache/ntfy/attachments"
attachment-total-size-limit: "5G"
attachment-file-size-limit: "15M"
attachment-expiry-duration: "3h"Rate limits (generous defaults for personal use)
visitor-request-limit-burst: 60
visitor-request-limit-replenish: "5s"
visitor-message-daily-limit: 10000Web UI
web-root: "app"Logging
log-level: "INFO"
log-format: "text"
log-file: "/var/log/ntfy/ntfy.log"
EOFReplace ntfy.yourdomain.com with your actual domain. Create the log directory:
sudo mkdir -p /var/log/ntfy
sudo chown ntfy:ntfy /var/log/ntfy
sudo chown ntfy:ntfy /var/cache/ntfyKey configuration fields explained:
base-url-- The public URL clients will use. Required for iOS push and click actions.listen-http-- The local port ntfy binds to. We use 2586 because 80 and 443 will be handled by Caddy.cache-file-- SQLite database that holds recent messages for late subscribers.cache-duration: 12hmeans a subscriber connecting now will see messages from the last 12 hours.attachment-*-- Controls file uploads. Total disk budget is 5 GB; each attachment is capped at 15 MB and auto-deleted after 3 hours.web-root: app-- Serves the web UI at/. Set todisableto only expose the API.behind-proxy: true-- Tells ntfy to useX-Forwarded-Forso per-IP rate limits work correctly behind Caddy.
Step 5: Start the Service and Publish a Test Message
Reload systemd and start ntfy:
sudo systemctl daemon-reload
sudo systemctl enable --now ntfyCheck the service status:
sudo systemctl status ntfyExpected output:
● ntfy.service - ntfy server
Loaded: loaded (/lib/systemd/system/ntfy.service; enabled; preset: enabled)
Active: active (running) since Thu 2026-04-16 09:00:00 UTC; 3s ago
Main PID: 4312 (ntfy)
Tasks: 8 (limit: 4587)
Memory: 25.4M
CPU: 142msConfirm the HTTP endpoint:
curl http://127.0.0.1:2586/v1/healthExpected output:
{"healthy":true}Publish a test message to a topic called hello:
curl -d "First ntfy message" http://127.0.0.1:2586/helloExpected output:
{"id":"8fxRzVw6pM3N","time":1713260800,"expires":1713304000,"event":"message","topic":"hello","message":"First ntfy message"}Open another shell and subscribe:
curl -s http://127.0.0.1:2586/hello/jsonIn the first shell, publish again -- the subscriber prints the message in real time. The core is working.
Step 6: Enable Authentication and ACLs
By default every topic is public. Anyone who knows or guesses a topic name can read or publish. For any real use you want authentication and per-topic ACLs.
Ntfy stores users in a SQLite file referenced by auth-file. Add these entries to /etc/ntfy/server.yml:
# Authentication
auth-file: "/var/lib/ntfy/user.db"
auth-default-access: "deny-all"deny-all flips the default so unauthenticated clients cannot read or publish anything. Create the auth directory:
sudo mkdir -p /var/lib/ntfy
sudo chown ntfy:ntfy /var/lib/ntfyRestart to apply:
sudo systemctl restart ntfyCreate Admin and User Accounts
The ntfy user CLI manages the auth database. Always run it with sudo -u ntfy so file permissions stay correct:
sudo -u ntfy ntfy user add --role=admin adminYou will be prompted for a password twice. Admin users can read and write every topic.
Create a regular user for scripts and devices:
sudo -u ntfy ntfy user add alerterCreate a separate user for your phone:
sudo -u ntfy ntfy user add phoneList users:
sudo -u ntfy ntfy user listExpected output:
user admin (role: admin, tier: none)
- read-write access to all topics (admin role)
user alerter (role: user, tier: none)
- no topic-specific permissions
- no access to any topic (server config: deny-all)
user phone (role: user, tier: none)
- no topic-specific permissions
no access to any topic (server config: deny-all)
Define Topic ACLs
Grant alerter write access to the servers and backups topics:
sudo -u ntfy ntfy access alerter servers write-only
sudo -u ntfy ntfy access alerter backups write-onlyGrant phone read access to every topic starting with servers or backups:
sudo -u ntfy ntfy access phone "servers*" read-only
sudo -u ntfy ntfy access phone "backups*" read-onlyThe asterisk lets one rule cover servers, servers-prod, servers-staging, etc.
Publish with Authentication
Every request now needs either a bearer token or basic auth:
curl \
-u alerter:yourpassword \
-d "Nightly backup complete" \
http://127.0.0.1:2586/backupsOr with a token (safer for scripts). Create one:
sudo -u ntfy ntfy token add alerterExpected output:
token tk_abcdefghijklmnopqrstuvwxyz0123 created for user alerter, never expiresPublish with the token:
curl \
-H "Authorization: Bearer tk_abcdefghijklmnopqrstuvwxyz0123" \
-d "Token-based auth works" \
http://127.0.0.1:2586/backupsTokens are revocable (ntfy token del) without touching the user's password.
Step 7: Attachment Caching
Ntfy supports attachments up to the configured size limit (15 MB in our config). Files are cached in attachment-cache-dir and auto-expire after attachment-expiry-duration.
Attach a file when publishing:
curl \
-u alerter:yourpassword \
-T /var/log/backup.log \
-H "Filename: nightly-backup.log" \
-H "Title: Backup Report" \
http://127.0.0.1:2586/backupsThe response includes an attachment object with the direct URL:
{
"id": "p8fMv9RzQ2",
"time": 1713260900,
"event": "message",
"topic": "backups",
"title": "Backup Report",
"message": "You received a file: nightly-backup.log",
"attachment": {
"name": "nightly-backup.log",
"type": "text/plain",
"size": 421038,
"expires": 1713271700,
"url": "https://ntfy.yourdomain.com/file/p8fMv9RzQ2.log"
}
}Mobile apps render image attachments inline. Log files and PDFs appear as tappable downloads.
Pruning Orphaned Attachments
attachment-total-size-limit: 5G is a hard cap -- new uploads beyond that are rejected. Ntfy also runs an internal janitor that deletes attachments once attachment-expiry-duration elapses. If you need to manually prune:
sudo systemctl stop ntfy
sudo find /var/cache/ntfy/attachments -type f -mtime +1 -delete
sudo systemctl start ntfyStep 8: iOS Push Configuration
iOS requires Apple Push Notification service (APNs) for any app to receive background pushes. Building your own APNs pipeline requires an Apple developer account and a signed certificate. To avoid that, the official iOS app uses a "poke" mechanism: when your self-hosted ntfy server has a message for an iOS subscriber, it sends a tiny wake-up ping through the hosted ntfy.sh instance, which is registered with APNs. The iOS app then wakes up and fetches the actual message directly from your server. Your message content never leaves your VPS.
Enable this by adding to /etc/ntfy/server.yml:
# iOS push via upstream APNs relay
upstream-base-url: "https://ntfy.sh"Restart:
sudo systemctl restart ntfyOn your iPhone:
https://ntfy.yourdomain.combackups)Send a test:
curl -u alerter:yourpassword -d "iOS test" https://ntfy.yourdomain.com/backupsWithin 1-3 seconds, the notification should appear on your iPhone's lock screen. If it does not, see Troubleshooting.
Step 9: TLS with Caddy
Caddy is the easiest way to get TLS: it pulls Let's Encrypt certificates automatically, renews them, and handles HTTPS redirection with zero config.
Install Caddy:
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
curl -1sLf "https://dl.cloudsmith.io/public/caddy/stable/gpg.key" | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf "https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt" | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install -y caddyReplace the default Caddyfile:
sudo tee /etc/caddy/Caddyfile > /dev/null <<'EOF' ntfy.yourdomain.com { reverse_proxy 127.0.0.1:2586 { flush_interval -1 transport http { read_timeout 24h } }
encode gzip } EOF
Key settings:
flush_interval -1-- Disables buffering so the server-sent-event stream reaches subscribers in real time.read_timeout 24h-- Long-polling subscribers hold the connection open for hours.encode gzip-- Compresses JSON responses for the web UI.
sudo systemctl reload caddyCaddy will request a certificate for ntfy.yourdomain.com on first request. Verify:
curl https://ntfy.yourdomain.com/v1/healthExpected output:
{"healthy":true}Open https://ntfy.yourdomain.com in a browser -- the web UI loads over HTTPS.
Integrations
Plain curl from Shell Scripts
The smallest possible integration. Drop this in any bash script:
notify() {
curl -s \
-H "Authorization: Bearer $NTFY_TOKEN" \
-H "Title: $1" \
-H "Priority: $2" \
-H "Tags: $3" \
-d "$4" \
"https://ntfy.yourdomain.com/servers" > /dev/null
}Example use
notify "Backup complete" "default" "floppy_disk,white_check_mark" "Nightly rsync to B2 finished in 8m32s"
notify "Disk alert" "urgent" "warning,rotating_light" "Root filesystem 92% full on vps-prod-01"Tags map to emoji via this reference. Priority accepts min, low, default, high, urgent.
Home Assistant
Home Assistant has first-class ntfy support via the REST notify integration. Add to configuration.yaml:
notify:
- name: ntfy_home
platform: rest
resource: https://ntfy.yourdomain.com/home
method: POST_JSON
authentication: basic
username: alerter
password: !secret ntfy_password
title_param_name: title
message_param_name: message
data:
priority: "default"
tags: ["house_with_garden"]Then in an automation:
automation:
- alias: "Front door opened"
trigger:
platform: state
entity_id: binary_sensor.front_door
to: "on"
action:
service: notify.ntfy_home
data:
title: "Front door"
message: "Door opened at {{ now().strftime('%H:%M') }}"For a deeper tutorial on the HA side of this integration, see our Home Assistant install guide.
Prometheus Alertmanager
Alertmanager's generic webhook receiver is a perfect fit. Add a receiver to alertmanager.yml:
receivers:
- name: ntfy
webhook_configs:
- url: "https://ntfy.yourdomain.com/alerts"
send_resolved: true
http_config:
authorization:
type: Bearer
credentials: "tk_abcdefghijklmnopqrstuvwxyz0123"Alertmanager will POST JSON that ntfy interprets as a message. For richer formatting, use a webhook template that maps alert labels into Title, Priority, and Tags headers. A full example lives in our Alertmanager guide.
Uptime Kuma
Uptime Kuma has a native ntfy notification type. In Uptime Kuma settings:
https://ntfy.yourdomain.comuptimeTest the notification and monitor downtime alerts arrive on your phone within seconds of a monitor going red.
GitHub / GitLab Webhooks via Middleware
Ntfy doesn't natively parse provider-specific webhook formats, but a tiny proxy in Caddy handles it. Add to the Caddyfile:
ntfy.yourdomain.com { route /webhook/github { request_header X-Ntfy-Title "GitHub: {http.request.header.X-Github-Event}" request_header X-Ntfy-Tags "octopus" rewrite * /github-events reverse_proxy 127.0.0.1:2586 }
reverse_proxy 127.0.0.1:2586 { flush_interval -1 } }
Point your GitHub webhook at https://ntfy.yourdomain.com/webhook/github and every push, PR, and release becomes a push notification.
Troubleshooting
| Problem | Cause | Solution |
|---|---|---|
curl: (7) Failed to connect to localhost port 2586 | Ntfy not running | sudo systemctl status ntfy; check journalctl -u ntfy -n 50 |
403 Forbidden on publish | ACL or deny-all blocking unauthenticated | Check user access: sudo -u ntfy ntfy access <user>; supply -u user:pass or bearer token |
| iOS app not receiving messages | upstream-base-url missing or wrong base-url | Ensure base-url is your public HTTPS URL and upstream-base-url: https://ntfy.sh is set; restart ntfy |
| Caddy TLS fails | DNS not pointing to VPS or port 80 blocked | Verify A record: dig ntfy.yourdomain.com; open 80/443: sudo ufw allow 80,443/tcp |
attachment too large error | File exceeds attachment-file-size-limit | Increase the limit in server.yml and restart, or compress the file |
| High memory after many subscribers | Each SSE connection holds state | Expected; 1,000 concurrent subscribers use ~200 MB. Upgrade plan or reduce keepalive |
| Messages lost on restart | cache-file not configured or pointing to ephemeral location | Ensure cache-file points to a persistent path like /var/cache/ntfy/cache.db |
Too Many Requests (429) | Per-visitor rate limit hit | Increase visitor-request-limit-burst or switch the caller to a user token (tokens have separate tier-based limits) |
Web UI shows Connection lost repeatedly | Reverse proxy buffering SSE | Confirm flush_interval -1 in Caddy and behind-proxy: true in server.yml |
Viewing Logs
Stream ntfy logs in real time:
sudo tail -f /var/log/ntfy/ntfy.logOr via journald:
sudo journalctl -u ntfy -fIncrease verbosity temporarily for debugging:
sudo sed -i 's/log-level: "INFO"/log-level: "DEBUG"/' /etc/ntfy/server.yml
sudo systemctl restart ntfyDon't forget to switch back to INFO once debugging is done -- DEBUG logs every single HTTP request.
FAQ
Is ntfy really free to self-host?
Yes. Ntfy is open source under the Apache 2.0 license. The server binary is free and has no feature gates. The only cost is your VPS. The hosted ntfy.sh service has optional paid tiers for increased limits, but a self-hosted instance on a 4 GB VPS can easily handle thousands of subscribers without any license fees. Every feature in the official documentation works on your self-hosted install except for phone-call delivery, which is exclusive to the hosted cloud service because it integrates with Twilio.
Does ntfy work with iOS push notifications?
Yes, but with one caveat. The iOS app requires a round trip through Apple's APNs infrastructure, which the official ntfy.sh instance handles for you. When you self-host, you configure upstream-base-url: https://ntfy.sh in server.yml to forward iOS devices through ntfy.sh for APNs delivery. Your messages stay private because only a short wake-up ping is sent upstream; the actual payload is fetched from your server by the iOS app when it wakes. If you need zero dependency on ntfy.sh for iOS, you would need an Apple developer account, a p8 key, and a custom fork of the iOS app -- not worth it for most deployments.
How is ntfy different from Gotify or Pushover?
Ntfy uses a pub-sub topic model where any HTTP client can publish to a topic with a single curl call and no SDK. Gotify requires an application token per publisher and has a slightly heavier UI model built around "applications" and "messages." Pushover is a commercial SaaS with per-device licensing and isn't self-hostable. Ntfy is the best fit for infrastructure alerts and scripted notifications because the publish API is trivial, and it supports attachments, actions, and priorities natively. See our Gotify install guide for a direct comparison if you're choosing between the two.
Can I use ntfy with Prometheus Alertmanager?
Yes. Alertmanager has a generic webhook receiver, and ntfy's publish endpoint accepts JSON. You point Alertmanager at https://ntfy.yourdomain.com/alerts, add a bearer token header for auth, and Alertmanager will POST firing and resolved alerts directly to your topic. Templating in Alertmanager lets you shape the title, priority, and tags per alert label. See the Integrations section above for a config example, or our dedicated Alertmanager install guide for the Prometheus side.
How much RAM does ntfy need?
Ntfy is remarkably lightweight. A base install uses under 30 MB of RAM and handles hundreds of concurrent subscribers on a 1 vCPU server. Memory scales with the number of open SSE connections -- each subscriber adds about 100-200 KB. Even at 10,000 concurrent subscribers you are looking at under 2 GB. For most homelabs and small teams, our Starter plan (2 vCPU, 4 GB RAM) provides enormous headroom and leaves room on the box for Caddy, monitoring, and occasional attachment traffic.
How do I rotate or revoke tokens?
Run sudo -u ntfy ntfy token list to see all active tokens. Revoke one with sudo -u ntfy ntfy token del <token-id>. Issue a new one with sudo -u ntfy ntfy token add <user> and update the caller. Unlike passwords, tokens can be rotated without disrupting the user's other clients.
Next Steps
Now that ntfy is running securely on your VPS, here's how to build on it:
- Add status monitoring with Uptime Kuma -- Get instant push notifications the moment any site or service goes down, without any SaaS in the loop.
- Wire up Prometheus Alertmanager -- Forward every firing and resolved alert to ntfy with rich title, priority, and tag templating.
- Integrate with Home Assistant -- Route smart home events (doors, motion, temperature) to your phone through a single protected topic.
- Compare with Gotify -- If you want a second opinion on the self-hosted notification space, spin up Gotify alongside and A/B test for a week.
- Read the official docs -- The full reference at docs.ntfy.sh covers scheduled delivery, email forwarding, actions, Firebase integration, and tier-based rate limits in depth.
Get ntfy running in minutes on the right-sized VPS>
The Starter VPS plan is ideal for a self-hosted ntfy deployment: enough RAM for thousands of subscribers, enough disk for a generous attachment cache, and plenty of spare capacity for Caddy and monitoring.>
- 2 vCPU cores
- 4 GB RAM
- 50 GB NVMe SSD
- Unmetered bandwidth
- EUR 7.99/month>
Get Your Starter VPS -- deploy in under 60 seconds and start pushing notifications from any curl command you write.