Gotify: push notifications you own

May 18, 2026

notificationsservice-spotlight

Your backup script just finished. Your VPN container restarted. A playbook you kicked off an hour ago finally completed. How do you find out?

If you’re running a homelab of any real complexity, this question comes up constantly. You can tail logs, but only if you’re sitting at the terminal. You can check dashboards, but only if you think to look. What you really want is for your infrastructure to reach out and tap you on the shoulder the moment something worth knowing happens.

That’s the problem push notifications solve. And if you want to solve it without feeding your homelab’s internal events to a third-party service — here’s Gotify.

What Gotify actually is

Gotify is a self-hosted push notification server. It has three moving parts:

  1. A server — a small Go binary (or Docker container) that accepts incoming messages over a simple REST API and stores them.
  2. Apps — logical channels that services use to send messages. Each app gets its own token. Your backup script gets one token, your Ansible playbooks get another, your monitoring stack gets a third.
  3. Clients — the receiver side. A client token authenticates your phone or browser to receive the notifications that get pushed to it.

When your Ansible playbook wants to say “deployment complete,” it makes a single HTTP POST to Gotify’s API with its app token, a title, a body, and a priority number. Gotify stores it and pushes it in real time to anything listening on a client token — including the official Android and iOS apps, which use a persistent WebSocket connection for near-instant delivery.

That’s it. No special protocol, no proprietary SDK. A curl one-liner is enough to send a notification from literally any script in your stack.

Why this problem matters

The moment a homelab grows past “a few containers on a spare laptop,” the operator starts living in reactive mode. Something breaks, you find out when you happen to look. Playbooks run at 2 AM and you see the result at 9 AM.

Notifications close that loop. When every automation knows how to shout at you, you stop playing catch-up. You know your overnight backup job completed before you’ve made your morning coffee. You know a service restarted before a family member reports it’s down. You know a VM was provisioned successfully the moment Terraform finishes.

The other thing good notifications enable is triage without context-switching. A well-structured notification — right title, right priority, short message — tells you whether you need to act now, act later, or do nothing. That’s worth a lot at 11 PM.

The commercial alternatives

Before going further, it’s worth being honest about what exists in the cloud space, because “self-hosted” should be a deliberate choice rather than a reflex.

Pushover is the most direct comparison. It’s a paid service (small one-time device fee per platform) that provides a hosted notification server, polished mobile apps, and an API that looks a lot like Gotify’s. It works well, has good delivery reliability, and requires zero maintenance on your end. If you don’t care about self-hosting notifications or don’t want to run another VM, Pushover is a perfectly reasonable answer — and you wouldn’t be wrong for choosing it.

⚠️ Unverified: Pushover’s current pricing model and tier limits are general knowledge from outside the provided docs — specifics may have changed.

PagerDuty is the enterprise tier of the category: on-call scheduling, escalation policies, integrations with hundreds of monitoring tools, SLA-backed delivery, and pricing to match. It’s solving a related but meaningfully different problem — less “notify me when my backup finishes” and more “route the right alert to the right on-call engineer on the right team and log everything.” For a homelab, it’s massive overkill. It’s useful context though, because it shows how much operational complexity a mature notification system can grow to handle.

Ntfy (sometimes written as ntfy.sh after its hosted service) is the closest self-hosted peer to Gotify. It has a solid mobile app, supports a topic-based model instead of apps-and-clients, and offers a generous hosted tier if you want to use their servers instead of running your own. The API is slightly different — you POST to a topic URL rather than authenticating with a token — but the concepts translate directly. Either one is a defensible choice; the differences mostly come down to which mental model you prefer.

Apprise is a notification library more than a server. It can send to a wide range of services including email, Slack, Discord, Telegram, Matrix, and many more. It’s useful as a translation layer — “I want my scripts to send to whichever platform I choose without rewriting them” — but it doesn’t provide the persistent mobile push that Gotify or ntfy do. It’s worth knowing about if you want to scatter notifications to multiple destinations from a single send call.

Why Gotify specifically

Given that ntfy is a reasonable alternative, the choice between them often comes down to taste and architecture preferences.

Gotify’s app/client model maps cleanly onto a homelab with distinct service categories. When you create an “Infrastructure” app, a “Backup” app, and a “Service Alerts” app, you get natural separation: your phone can show you which part of the stack is talking to you at a glance. Priorities (0–10) let you decide at send time whether something warrants immediate attention or is just informational noise.

The priority system in practice: priority 0 is debug-level, 5 is a normal informational message, 7–8 is high (something important happened), 10 is critical (act now). That simple integer carries a lot of signal in a noisy homelab.

Gotify is also extremely lightweight. It runs comfortably in a small VM or container on very modest resources — a fraction of what most monitoring tools demand. For a foundation service that everything else depends on, small and stable is exactly what you want.

How it fits a homelab

Gotify works best when you treat it as infrastructure rather than an afterthought. The decision that makes the most difference: deploy it first, before everything else that might need to send notifications.

That might seem like a chicken-and-egg problem — “I want notifications about my infrastructure, but I need infrastructure to host the notification service.” In practice, it resolves cleanly. Gotify itself is simple enough to deploy in minutes, so you get it running early, grab the app tokens for each service category you plan to run, and then every subsequent service you bring up can notify Gotify from day one.

Once it’s running, integration is genuinely easy. The API accepts a POST to /message with a JSON body containing title, message, and priority. That’s the entire interface. Ansible’s uri module can call it directly. A bash script needs three lines. Terraform can call it via a null_resource. Any monitoring system that supports webhook outputs can send to it.

In practice, a well-configured homelab ends up with multiple categories of senders:

  • Infrastructure automation — Terraform provisioning results, Ansible playbook completions and failures
  • Scheduled jobs — Backup completion, database vacuum results, certificate renewal outcomes
  • Monitoring alerts — When something Alertmanager or Uptime Kuma catches crosses a threshold
  • Operational scripts — One-off scripts that run infrequently enough that you’d otherwise forget to check their output

The mobile app side is equally straightforward. Official apps exist for Android and iOS. They connect to your Gotify server via a client token and maintain a WebSocket connection for real-time delivery. You don’t poll — the server pushes.

One operational note worth knowing: if you’re fronting Gotify with a reverse proxy (which you should, so you get HTTPS), make sure the proxy isn’t aggressively timing out WebSocket connections. Gotify’s mobile delivery relies on that persistent connection, and a proxy default of 60 seconds will cause the app to constantly reconnect. Extending the timeout to something like an hour resolves it cleanly.

Who should run this

Gotify makes sense for you if:

  • You run more than a handful of services and want to stop discovering failures by accident
  • You have scheduled jobs that run unattended and you want to know when they complete (or don’t)
  • You have IaC automation that you trigger and then walk away from
  • You want a single place to route notifications from different parts of your stack without coupling each service to a specific chat platform

It’s probably not worth the effort if:

  • Your homelab is a handful of containers and you’re already keeping a close eye on them
  • You already have a working notification path you’re happy with (email, Telegram bot, Discord webhook, whatever)
  • You’d rather use ntfy’s hosted tier and not manage another server

The honest calculus: Gotify adds one more service to maintain. It’s a small, stable service with minimal resource requirements and infrequent updates, so the maintenance burden is low — but it’s not zero. If you break Gotify, you lose visibility into everything else breaking. That’s a good argument for treating it as your most-babied infrastructure piece: proper backups, monitoring of the monitor, and a fallback path to check on things if it goes dark.

The shape of a running setup

A mature Gotify setup in a homelab looks like this: one server running under a reverse proxy with a valid TLS certificate, a handful of application tokens organized by service category, and a single client token on your phone.

New services get provisioned with their app token at deploy time, stored wherever you keep secrets. Over time, the notification log becomes a useful operational record — a timestamped trail of what your homelab did while you weren’t watching.

That’s the thing about good notifications. They don’t just tell you about failures. They tell you that everything worked, quietly and constantly, in the background. Most of the time, that’s the message that matters most: nothing went wrong, everything ran, and you can go to sleep.

Wrapping up

Gotify is one of those services that sounds optional until you’ve run it for a month. After that, it feels load-bearing. The moment your infrastructure can reach out and tell you what it did, you stop spending mental energy wondering.

It’s a small thing — a lightweight server, a simple API, a mobile app. But it changes the operating posture of a homelab from reactive to informed. And in a stack where you’re responsible for everything from DNS to backups to VM provisioning, being informed is most of the job.

If you’re building out a homelab and looking for somewhere to start: deploy this first.

← all posts

Comments

No comments yet — be the first.

Leave a comment

Moderated before it appears.
Theme
Font