Shm
🛡️ Privacy-first, Agnostic Telemetry for Self-Hosted Software.
Install / Use
/learn @kOlapsis/ShmREADME
<img src="./docs/logos/shm-logo.svg" width="42"> Self-Hosted Metrics (SHM)
<div align="center">
Privacy-first, Agnostic Telemetry for Self-Hosted Software. Collect usage stats, verify active instances, and understand your user base without spying on them.
Website : https://self-hosted-metrics.com/
Features • Quick Start • SDK Integration • Architecture
</div>🖼️ Dashboard Preview
Modern, dark-mode dashboard showing aggregated business metrics and system health.
🚀 Why SHM?
When you distribute self-hosted software (on-premise), you fly blind. You don't know how many instances are running, which versions are active, or if your features are actually used.
SHM solves this with a lightweight, secure approach:
- Privacy First: Collects aggregate counters, never user content.
- Agnostic: Send any JSON payload. The dashboard adapts automatically.
- Secure: Every request is signed with an Ed25519 keypair generated on the client.
- Zero-Config Dashboard: Single Go binary with embedded UI. No frontend build required.
✨ Features
- 🔐 Cryptographic Identity: Instances generate a unique ID and keypair. No spoofing possible.
- 📦 Multi-App Support: Track multiple software products on a single SHM server.
- ⭐ GitHub Stars: Automatically fetch and display GitHub repository stars for your applications.
- 🎨 Dynamic Dashboard: Send
{"pizzas_eaten": 10}and SHM automatically creates the KPI cards and table columns. - ⚙️ Ops vs Business Separation: Automatically distinguishes between business metrics (KPIs) and system metrics (CPU, RAM, OS).
- 🐳 Docker Native: Runs anywhere with a simple
docker-compose.
🗣️ Feedback & Real-World Usage
SHM is young and evolving. If you are using it (even in dev), your feedback is extremely valuable.
👉 Share your experience here: https://github.com/kolapsis/shm/discussions
What matters most:
- real use cases
- missing metrics
- integration friction
- what you'd expect before using it in production
🎖️ Public Badges
Display your SHM metrics in your README with embeddable SVG badges.
Available Badges
Active Instances

Most Used Version

Aggregated Metrics

Combined Stats

Customization
All badges support query parameters for customization:
?color=00D084- Custom hex color (without #)?label=custom- Custom label text
Example:

Note: Replace your-shm-server.example.com with your actual SHM server URL and your-app with your application slug.
<table> <tr> <td align="center"> <a href="./docs/images/dashboard.png"> <img src="./docs/images/dashboard.png" width="300" alt="Dashboard Overview"> </a> <br><em>Dashboard</em> </td> <td align="center"> <a href="./docs/images/details.png"> <img src="./docs/images/details.png" width="300" alt="Instance Details"> </a> <br><em>Details</em> </td> <td align="center"> <a href="./docs/images/graph.png"> <img src="./docs/images/graph.png" width="300" alt="Metrics Graph"> </a> <br><em>Graph</em> </td> </tr> </table>
⚡ Quick Start (Server)
1. Create the configuration
Create a compose.yml file:
name: shm
services:
db:
image: postgres:15-alpine
container_name: shm-db
restart: unless-stopped
environment:
POSTGRES_USER: shm
POSTGRES_PASSWORD: ${DB_PASSWORD:-change-me-in-production}
POSTGRES_DB: metrics
volumes:
- postgres_data:/var/lib/postgresql/data
- ./migrations:/docker-entrypoint-initdb.d
healthcheck:
test: ["CMD-SHELL", "pg_isready -U shm -d metrics"]
interval: 10s
timeout: 5s
retries: 5
app:
image: ghcr.io/kolapsis/shm:latest
# Or build from source:
# build:
# context: .
# dockerfile: Dockerfile
container_name: shm-app
restart: unless-stopped
depends_on:
db:
condition: service_healthy
environment:
SHM_DB_DSN: "postgres://shm:${DB_PASSWORD:-change-me-in-production}@db:5432/metrics?sslmode=disable"
PORT: "8080"
ports:
- "8080:8080"
volumes:
postgres_data:
2. Download migrations
mkdir -p migrations
curl -sL https://raw.githubusercontent.com/kolapsis/shm/main/migrations/001_init.sql -o migrations/001_init.sql
curl -sL https://raw.githubusercontent.com/kolapsis/shm/main/migrations/002_applications.sql -o migrations/002_applications.sql
3. Start the services
docker compose up -d
Access the dashboard at http://localhost:8080.
Environment Variables
Core Settings
| Variable | Default | Description |
|----------|---------|-------------|
| SHM_DB_DSN | (required) | PostgreSQL connection string |
| PORT | 8080 | HTTP server port |
| GITHUB_TOKEN | - | GitHub Personal Access Token for higher API rate limits (5000 req/h instead of 60 req/h) |
Rate Limiting
Rate limiting is enabled by default to protect against abuse.
| Variable | Default | Description |
|----------|---------|-------------|
| SHM_RATELIMIT_ENABLED | true | Enable/disable rate limiting |
| SHM_RATELIMIT_CLEANUP_INTERVAL | 10m | Interval for cleaning up expired limiters |
| SHM_RATELIMIT_REGISTER_REQUESTS | 5 | Max requests per period for /v1/register and /v1/activate |
| SHM_RATELIMIT_REGISTER_PERIOD | 1m | Time window for register endpoints |
| SHM_RATELIMIT_REGISTER_BURST | 2 | Burst allowance for register endpoints |
| SHM_RATELIMIT_SNAPSHOT_REQUESTS | 1 | Max requests per period for /v1/snapshot (per instance) |
| SHM_RATELIMIT_SNAPSHOT_PERIOD | 1m | Time window for snapshot endpoint |
| SHM_RATELIMIT_SNAPSHOT_BURST | 2 | Burst allowance for snapshot endpoint |
| SHM_RATELIMIT_ADMIN_REQUESTS | 30 | Max requests per period for /api/v1/admin/* |
| SHM_RATELIMIT_ADMIN_PERIOD | 1m | Time window for admin endpoints |
| SHM_RATELIMIT_ADMIN_BURST | 10 | Burst allowance for admin endpoints |
| SHM_RATELIMIT_BRUTEFORCE_THRESHOLD | 5 | Failed auth attempts before IP ban |
| SHM_RATELIMIT_BRUTEFORCE_BAN | 15m | Duration of IP ban after brute-force detection |
See docs/DEPLOYMENT.md for deployment examples and security configuration.
📦 SDK Integration (Go)
Embed the telemetry client into your application.
go get github.com/kolapsis/shm/sdk
Implementation Example
package main
import (
shm "github.com/kolapsis/shm/sdk/golang"
)
func main() {
// 1. Configure the client
telemetry, err := shm.New(shm.Config{
ServerURL: "https://metrics.your-domain.com",
AppName: "MyAwesomeApp",
AppVersion: "1.0.0",
Environment: "production",
Enabled: true,
})
if err != nil {
panic(err)
}
// 2. Define your metrics (Callback)
// This runs every hour (configurable)
telemetry.SetProvider(func() map[string]interface{} {
// Replace with your actual metrics
return map[string]interface{}{
"documents_created": 42, // e.g. db.CountDocs()
"users_active": 10, // e.g. db.CountActive()
"jobs_processed": 100, // e.g. worker.TotalJobs()
}
})
// 3. Start in background
// SHM automatically adds System metrics (CPU, RAM, OS, Arch...)
go telemetry.Start(context.Background())
// ... run your app
}
📦 SDK Integration (Node.js / TypeScript)
Embed the telemetry client into your Node.js application.
npm install @kolapsis/shm-sdk
Implementation Example
import { SHMClient } from '@kolapsis/shm-sdk';
// 1. Configure the client
const telemetry = new SHMClient({
serverUrl: 'https://metrics.your-domain.com',
appName: 'MyAwesomeApp',
appVersion: '1.0.0',
environment: 'production',
enabled: true,
});
// 2. Define your metrics (Callback)
// This runs every hour (configurable)
telemetry.setProvider(() => ({
// Replace with your actual metrics
documents_created: 42, // e.g. db.countDocs()
users_active: 10, // e.g. db.countActive()
jobs_processed: 100, // e.g. worker.totalJobs()
}));
// 3. Start in background
// SHM automatically adds System metrics (CPU, RAM, OS, Arch...)
const controller = telem
Related Skills
node-connect
338.0kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
83.4kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
338.0kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
commit-push-pr
83.4kCommit, push, and open a PR
