Back to Home

Alerts Server Pusk 16 MB on Go

Pusk — compact self-hosted alerts server on Go sized 16 MB. Supports Telegram bot migration, ACK with silence in Alertmanager, WebSocket for NAT. Works without external DBs, with PWA and push notifications.

Pusk: 16 MB alerts server without dependencies
Advertisement 728x90

Pusk: A 16 MB Self-Hosted Alert Server Built in Go

Pusk is a self-hosted solution that eliminates reliance on external messaging platforms for monitoring. A single 16 MB executable supports 13 Telegram Bot API methods, WebSocket, Web Push, and a PWA client. It runs without PostgreSQL or other databases—just SQLite in pure Go. Designed for scenarios where external APIs are unavailable due to limits, blocks, or isolation.

The architecture excludes external services. Go was chosen for fast builds (7 seconds) and its built-in net/http. The database uses modernc.org/sqlite without CGO, with an RSS of ~4 MB at startup. Logging is handled via slog in JSON or text format.

Why Not Standard Messengers?

Alternatives require migrations, databases, and significant resources:

Google AdInline article slot

| Platform | Dependencies | Bot Compatibility | ACK | RAM |

|-----------|-------------|---------------------|-----|-----|

| Mattermost | PostgreSQL, SMTP | Rewrite required | Plugin | 500+ MB |

Google AdInline article slot

| Matrix | Synapse, PostgreSQL | Rewrite required | No | 500+ MB |

| Telegram | Cloud | — | No | — |

Gotify/ntfy offer only push notifications without chat or ACK. Using a VPN for Telegram adds failure points. Pusk emulates the Bot API: change the base_url in your bot, and it works with your infrastructure.

Google AdInline article slot

Binary Structure

pusk (16 MB, ~6600 lines of Go, 110 tests)
├── Bot API    — /bot/<token>/<method>  (13 of 80+ Telegram Bot API methods)
├── Client API — /api/*                 (PWA backend)
├── WebSocket  — /api/ws                (real-time statuses, typing)
├── Web Push   — FCM / Mozilla          (notifications without polling)
├── Files      — /file/<id>             (media)
├── PWA        — /                      (web client)
└── SQLite     — data/orgs/*/pusk.db    (separate DB for each organization)

Supported methods: sendMessage, editMessageText, deleteMessage, answerCallbackQuery, sendPhoto, sendDocument, sendVoice, sendVideo, setWebhook, deleteWebhook, getWebhookInfo, getMe, getUpdates.

Middleware for compatibility:

func TelegramCompat(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        p := r.URL.Path
        if strings.HasPrefix(p, "/bot") && !strings.HasPrefix(p, "/bot/") {
            r.URL.Path = "/bot/" + p[4:]
        }
        next.ServeHTTP(w, r)
    })
}

Migrating from python-telegram-bot:

# Before:
app = ApplicationBuilder().token(TOKEN).build()

# After:
app = ApplicationBuilder().token(TOKEN).base_url("https://pusk.internal/bot").build()

Long Polling and Update Delivery

/getUpdates holds a connection for timeout seconds, accounts for offset, with an in-memory queue (100 updates/bot). On restart, the bot receives subsequent alerts without persistence.

For bots behind NAT—WebSocket relay:

import websockets, json, asyncio

async def relay():
    async with websockets.connect("wss://pusk.internal/bot/TOKEN/relay") as ws:
        async for msg in ws:
            update = json.loads(msg)
            print(update["message"]["text"])

asyncio.run(relay())

Auto-selection: webhook (with SSRF protection), relay (rate-limited to 30 msg/min), or getUpdates.

SQLite per Organization and Hot Backup

Each organization has a separate pusk.db in WAL mode. Does not block readers during writes. Backup: sqlite3 pusk.db ".backup backup.db". Suitable for tens of messages/min without PostgreSQL JOINs.

Workflow

  • Admin starts the server (docker run or binary), creates an organization—generates #general and a system bot.
  • Invitation via link (7 days, up to 50 people), auto-notification in chat.
  • Create #alerts, webhook from Zabbix/Grafana/Alertmanager (?format=alertmanager).
  • On-call: push/WebSocket, ACK button, the whole team sees the status.

Roles:

  • Admin: Full rights + user/channel management.
  • Member: Chat, ACK, files, @mention.

Enhancements for Alerting

  • ACK → Silence: POST /api/v2/silences to Alertmanager via PUSK_ALERTMANAGER_URL.
  • Colors: Red/green stripe for firing/resolved.
  • Push optimization: If WebSocket is active and channel open, skip push.
  • Isolation: Frontend embedded, no CDN. Web Push requires FCM/Mozilla.

Key Features

  • Single 16 MB binary with no external dependencies, SQLite in Go.
  • Partial emulation of Telegram Bot API for migration without rewriting.
  • ACK with auto-silencing for Alertmanager, color-coded status indicators.
  • WebSocket relay for NAT, rate limits, SSRF protection.
  • PWA with push, admin/member roles, isolation per org.db.

— Editorial Team

Advertisement 728x90

Read Next