Self-hosted service
gotify/server avatar
gotify/server

gotify/server: a self-hosted push server with a REST write path and a WebSocket read path

A simple server for sending and receiving messages in real-time per WebSocket. (Includes a sleek web-ui)

15,899 stars874 forksGoNOASSERTION

At a glance

What is it?
Gotify is a Go server that accepts messages over a REST API and delivers them to connected clients over WebSocket, with a bundled React web UI and an Android client. The judgement: it is a small, legible notification bus for people who already run their own infrastructure, and it is not a replacement for a mobile push platform.
Who is it for?
Adopt gotify/server if you want a notification endpoint you control, you are comfortable running a Go binary or the gotify/server container, and your receiving clients are the Android app, the gotify/cli tool, or your own WebSocket consumer. Do not adopt it if you need delivery to iOS, if you need per-message delivery receipts, or if you expect the vendor to run the infrastructure for you.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository last received commits 3 days ago.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The gap Gotify fills: an owned endpoint instead of a rented one

Public push services require an account, a project, and an outbound dependency on someone else's uptime. For a homelab script that wants to say a backup finished, that is a lot of ceremony. Gotify's README states the motivation plainly: the authors wanted a simple server for sending and receiving messages in real time over WebSocket, found few open source options and most of the existing ones abandoned, and required that it be self-hostable. The audience follows from that. It is for the person who already runs a reverse proxy, already has a place to put a small Go binary or a container, and wants the notification path to terminate on hardware they own. It is not aimed at product teams embedding notifications in a consumer app, because the README describes no iOS client and no hosted tier.

REST in, WebSocket out: the shape of the message path

The feature list describes two directions and they are asymmetric. Messages arrive through a REST API. They leave through a WebSocket connection held open by each receiving client. Everything else in the project hangs off that split. Users, clients and applications are separate managed entities, which is the part that matters for anyone wiring this into existing tooling. An application is the thing that owns a token and is allowed to publish. A client is the thing that is allowed to subscribe. A user owns both. That means a monitoring script does not need a user credential, only an application token, and revoking one noisy script does not disturb the others. The web UI is a React application living in the ui directory of the repository and is the default consumer of the same WebSocket endpoint any custom client would use, which is a useful property: if the UI works through your proxy, a hand-written subscriber will too.

Install and configure without guessing at the keys

The README points to gotify.net/docs/install for installation and gotify.net/docs/config for configuration rather than inlining either. That is a real constraint on what can be stated here, and it is worth being explicit about it: this article cannot give you a verified config file because the configuration page is not part of the supplied material. What the README does confirm is the distribution surface. There is an official container image at hub.docker.com/r/gotify/server, which is the path most people will take, and the project is written in Go, so a single static binary is the other obvious route. Beyond that, the honest instruction is to open the configuration page and read the current key names for your release before writing anything, because the project follows SemVer and the jump from v2.9.1 in February 2026 to v3.0.0 in July 2026 signals that the major version boundary was crossed, which is where breaking configuration or API changes are permitted to land. Treat any config snippet you find in a blog post as unverified until it matches the docs for the version you installed.

The v3.0.0 boundary and what it costs to stay current

Release cadence is not the same as maintenance burden, but the dates are informative. v3.1.0 shipped in August 2026, v3.0.0 in July 2026, and v2.9.1 in February 2026, with the last push to the default branch in September 2026. That is an active project, and the gap between the last v2 release and the first v3 release is roughly five months. The upgrade cost for a self-hosted notification server is mostly in two places: the configuration file and any client you wrote yourself against the REST or WebSocket API. The bundled Android app and the separate gotify/cli tool are maintained in their own repositories, so a server major version can move ahead of the clients you depend on. Before upgrading a running instance, read the release notes for the specific version rather than assuming the API is additive. The licence question is separate and worth flagging: the README states the project is licensed under the MIT License and points at the LICENSE file, but the repository metadata supplied here reports NOASSERTION. Those two things disagree. Open the LICENSE file in the repository and read it yourself rather than relying on either the badge or the metadata. This is not legal advice, just an observation that the two sources conflict.

Where Gotify is the wrong tool

The README lists an Android app and links to Google Play and F-Droid. It does not list an iOS client. If your recipients carry iPhones, the WebSocket delivery model does not help them, because a phone that is asleep cannot hold a socket open, and the project does not appear to offer a system-level push bridge to work around that. That single fact rules Gotify out for a lot of mixed-device teams. There is a second limitation that follows from the architecture rather than the platform list. WebSocket delivery is only as reliable as the connection. A message sent while a client is offline is stored server-side and delivered on reconnect, which is the behaviour the web UI depends on, but the README describes no delivery receipt or acknowledgement mechanism, so a sender cannot distinguish between a message that reached a device and one that is sitting in a queue. If your use case is an alert that must be confirmed as seen, this is the wrong shape of system. Third: Gotify is a notification bus, not a workflow engine. There are plugins, and the README links to a plugin documentation page, but nothing in the supplied material suggests routing rules, escalation, or scheduled delivery.

ntfy as the alternative, and the actual difference

The closest comparison in this space is ntfy, and the difference is not cosmetic. Gotify separates publishing from subscribing through managed applications and clients, each with its own token, and delivers to a persistent WebSocket connection. That model assumes a client that stays connected and a server that keeps state about who is allowed to do what. ntfy's model is topic-based and deliberately looser: you publish to a topic name and subscribers subscribe to that name, which makes the publish step a plain HTTP POST to a URL and makes integration with existing shell scripts and webhooks nearly frictionless. The trade-off runs in both directions. Gotify's application and client entities give you revocation and per-sender isolation that a shared topic name does not, and its web UI is part of the server rather than a separate interface. ntfy's topic model gives you a lower barrier to the first message and a wider set of clients, including iOS. If your constraint is that the first message must be sendable in one curl command with no account setup, ntfy fits better. If your constraint is that each script has its own revocable credential and the receiving surface is a browser or an Android device, Gotify's structure is the reason to pick it.

Who should install it, and what to check before you do

The install path is short and the operational surface is small, which is the whole appeal. Pull the gotify/server image, put it behind the reverse proxy you already run, create an application, and point the Android app or gotify/cli at it. The reverse proxy step is where most first attempts fail, because the client side of this system is a WebSocket and proxies that do not forward the upgrade headers will serve the web UI correctly while silently breaking delivery. Verify that before you debug anything else. If your notification recipients are Android or a machine you control, and you want a publish endpoint with per-application tokens, this is a reasonable thing to run. If you need iOS, delivery confirmation, or an escalation policy, stop here and look at ntfy or a commercial push service instead. The one thing to settle before you commit is the licence discrepancy: read the LICENSE file in the repository, because the README says MIT and the repository metadata says NOASSERTION, and only one of those can be right.

Editorial conclusion

Adopt gotify/server if you want a notification endpoint you control, you are comfortable running a Go binary or the gotify/server container, and your receiving clients are the Android app, the gotify/cli tool, or your own WebSocket consumer. Do not adopt it if you need delivery to iOS, if you need per-message delivery receipts, or if you expect the vendor to run the infrastructure for you. Before committing, verify three things: which config keys your target release actually accepts under server:, that your reverse proxy forwards WebSocket upgrade headers, and that the licence file in the repository matches the MIT statement in the README, since the repository metadata reports NOASSERTION rather than MIT.

Official sources

  1. gotify/server on GitHub
  2. Issues
  3. Project website
  4. README
  5. Releases
Community notes

Community notes