⚠️ Early Stage: This project is under active development and may contain bugs. If you find any, please open an issue.
- ✨ Why Statrix
- 🚀 Features
- 📸 Screenshots
- 🏗️ Architecture
- 📦 Prerequisites
- ⚡ Quick Start (Local)
- 🐳 Quick Start (Docker)
- ☁️ Koyeb Deployment
- 🔧 Environment Variables
- 📧 Email Alerts (Gmail SMTP)
- 🖥️ Server Agent Setup
- ✅ Post-Deployment Checklist
- 🔍 Troubleshooting
- 📄 License
Statrix is built for developers and teams that want full control over uptime monitoring — without SaaS lock-in, recurring subscriptions, or third-party data dependencies.
- 🔒 Own your data — everything lives in your own PostgreSQL database
- 🌐 Multi-type monitoring — websites, cron/heartbeat jobs, and server agents
- 📧 Email alerts — downtime and recovery notifications via SMTP
- 📊 Public status page — clean, professional, auto-refreshing status page for your users
- 🛡️ Incident management — create, track, and resolve incidents with built-in templates
- 🔧 Maintenance windows — schedule maintenance to suppress false alerts
- 🏷️ Monitor categories — organize monitors into logical groups
- 🔐 Single admin — simple, secure JWT-based authentication
| Type | Description | How It Works |
|---|---|---|
| Website Monitor | HTTP/HTTPS health checks | Statrix probes your URL at configurable intervals and records response time, status code, and availability |
| Heartbeat (Cronjob) | Ping-based liveness checks | Your app calls a generated Statrix URL on schedule — if the ping stops, Statrix flags it as down |
| Heartbeat (Server Agent) | OS-level telemetry | Lightweight agents on Linux, macOS, or Windows report CPU, RAM, disk, and network metrics |
- 🟢 Real-time public status page with overall health indicator
- 📈 30-segment uptime timeline visualization (~3 days per segment)
- 🔔 Active incident banners with full lifecycle tracking (open → resolved)
- 📝 Pre-built incident templates (Major Outage, Partial Outage, Degraded Performance, Scheduled Maintenance, Security Investigation)
- 👁️ Visibility controls — hide resolved incidents from the public page
- 🏷️ Monitor grouping by custom categories
- ⏱️ Response time tracking and uptime percentage calculation
- ⏸️ Pause/resume individual monitors
- 🔓 Public/private monitor toggles
- 📧 SMTP-based downtime and recovery emails
- 🎯 Per-monitor notification toggles
- 🧠 Redis cache layer for fast reads with automatic in-memory fallback
- 🔄 Background monitor loops via APScheduler
- 🔐 Leader election lock for safe multi-instance deployments
- 📊 System resource dashboard
┌─────────────────────────────────────────────────────────┐
│ Statrix Instance │
│ │
│ ┌──────────┐ ┌──────────────┐ ┌───────────────────┐ │
│ │ FastAPI │ │ Background │ │ Static Frontend │ │
│ │ REST API │ │ Monitor │ │ (Vanilla JS) │ │
│ │ │ │ Loop │ │ │ │
│ └─────┬────┘ └───────┬──────┘ └───────────────────┘ │
│ │ │ │
│ ┌─────▼───────────────▼─────┐ │
│ │ Redis Cache Layer │ ◄── Fast reads + state │
│ │ (in-memory fallback) │ │
│ └───────────┬───────────────┘ │
│ │ │
│ ┌───────────▼───────────────┐ │
│ │ PostgreSQL (asyncpg) │ ◄── Source of truth │
│ └───────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
▲ ▲
│ │
Server Agents Heartbeat Pings
(Linux/macOS/Win) (Cronjob URLs)
Key components:
backend/— FastAPI application serving REST APIs and static frontend- PostgreSQL — persistent storage and source of truth
- Redis — cache layer for fast reads, shared state, and leader election
- APScheduler — background loops for monitor checks and notifications
- Server agents — OS-level scripts posting telemetry to
/v2/(Linux/macOS) or/win/(Windows)
| Requirement | Details |
|---|---|
| 🐍 Python | 3.13+ (for local development) |
| 🐘 PostgreSQL | Supabase, Neon, or self-hosted |
| 🔴 Redis | Recommended for production (Aiven Valkey, Upstash, or self-hosted) |
| 📧 SMTP Account | Optional but recommended for alerts |
# 1. Clone the repository
git clone https://github.com/irisXDR/Statrix.git
cd Statrix
# 2. Create your environment file
cp .env.example .env
# Edit .env with your real values (see Environment Variables below)
# 3. Install dependencies
pip install -r requirements.txt
# 4. Start the application
uvicorn backend.main:app --host 0.0.0.0 --port 8000Once running, open:
| Page | URL |
|---|---|
| 📊 Public status page | http://localhost:8000/ |
| 🔐 Admin dashboard | http://localhost:8000/edit |
| 💚 Health check | http://localhost:8000/health |
# Build the image
docker build -t statrix .
# Run with your environment file
docker run --name statrix -p 8000:8000 --env-file .env statrixClick the Deploy to Koyeb button at the top of this README.
- Create a new Koyeb App and link your Statrix repository.
- Select branch
master. - Build method: Dockerfile.
- Port: 8000 (HTTP).
- Health check path:
/health. - Scaling: start with
min=1,max=1andWEB_CONCURRENCY=1. - Add environment variables from the tables below.
- Deploy and verify
/healthreturns healthy.
💡 Tips:
koyeb.yamlis included and pre-maps required environment variables.- If using Upstash Redis, provide a TLS URL (
rediss://...).- When
CACHE_FAIL_FAST=true, API endpoints return503if cache is unhealthy — this is by design.
Use .env.example as your baseline. All variables are aligned with backend/config.py and koyeb.yaml.
| Variable | Required | Default | Description |
|---|---|---|---|
DATABASE_URL |
✅ | — | PostgreSQL connection string (postgresql://...) |
JWT_SECRET_KEY |
✅ | — | Secret key for JWT token signing |
OWNER_EMAIL |
✅ | — | Admin account email (created on first startup) |
OWNER_PASSWORD |
✅ | — | Admin account password (created on first startup) |
APP_URL |
✅ (prod) | http://localhost:8000 |
Public base URL for generated links and notifications and receiving information from heartbeat monitors |
🔑 Generate secrets from the command line
# Generate JWT secret key
python -c "import secrets; print(secrets.token_urlsafe(32))"| Variable | Required | Default | Description |
|---|---|---|---|
OWNER_NAME |
❌ | (empty) | Display name for admin user |
APP_NAME |
❌ | Statrix |
Application name shown in UI |
COMPANY_NAME |
❌ | Statrix |
Company name for branding |
JWT_ALGORITHM |
❌ | HS256 |
JWT signing algorithm |
JWT_EXPIRE_HOURS |
❌ | 168 |
Token expiration (7 days) |
CORS_ORIGINS |
❌ | ["http://localhost:8000","http://127.0.0.1:8000"] |
Allowed CORS origins (JSON array) |
STATUS_PAGE_TITLE |
❌ | Statrix Status |
Public status page title (browser tab & heading) |
STATUS_LOGO |
❌ | (empty) | Custom HTTPS logo URL for status page |
| Variable | Required | Default | Description |
|---|---|---|---|
SMTP_SERVER |
❌ | smtp.gmail.com |
SMTP host |
SMTP_PORT |
❌ | 587 |
SMTP TLS port |
SMTP_USER |
(empty) | SMTP login username (required for alerts) | |
SMTP_PASS |
(empty) | SMTP password or App Password (required for alerts) | |
SMTP_FROM |
❌ | (empty) | Sender address (falls back to SMTP_USER) |
NOTIFICATION_EMAIL |
(empty) | Target email for alerts (required for alerts) |
| Variable | Required | Default | Description |
|---|---|---|---|
CACHE_BACKEND |
❌ | redis |
Cache backend (redis or inmemory) |
REDIS_URL |
(empty) | Redis connection string (required when CACHE_BACKEND=redis) |
|
CACHE_FAIL_FAST |
❌ | true |
Return 503 when cache is unhealthy |
CACHE_WARMUP_FULL |
❌ | true |
Preload cache from DB at startup |
CACHE_KEY_PREFIX |
❌ | statrix:v1 |
Redis key namespace |
CACHE_WARMUP_BATCH_SIZE |
❌ | 500 |
Warmup pipeline batch size |
MONITOR_LEADER_LOCK_ENABLED |
❌ | true |
Prevent duplicate sweeps in multi-worker setups |
MONITOR_LEADER_LOCK_TTL_SECONDS |
❌ | 90 |
Redis leader lock TTL |
LOG_LEVEL |
❌ | INFO |
Application log level |
UVICORN_ACCESS_LOG |
❌ | false |
Enable uvicorn HTTP access logging |
PG_POOL_MIN_SIZE |
❌ | 2 |
PostgreSQL connection pool minimum |
PG_POOL_MAX_SIZE |
❌ | 5 |
PostgreSQL connection pool maximum |
DATA_RETENTION_DAYS |
❌ | 7 |
Days of minute-level data to retain |
DATA_COMPRESSION_HOUR_UTC |
❌ | 2 |
UTC hour for daily data compression |
WEB_CONCURRENCY |
❌ | 1 |
Keep at 1 until leader-lock is validated |
PUBLIC_STATUS_CACHE_TTL_SECONDS |
❌ | 10 |
Live status payload TTL for Redis/local fallback cache |
STATUS_SUMMARY_ENABLED |
❌ | true |
Enable hybrid Redis + in-memory summary path for main public status |
STATUS_SUMMARY_WARMUP_DELAY_SECONDS |
❌ | 90 |
Delayed startup warmup for in-memory summary build from PostgreSQL |
STATUS_SUMMARY_COLD_WAIT_SECONDS |
❌ | 5 |
Max wait for first request while summary warmup runs |
STATUS_SUMMARY_FLUSH_INTERVAL_SECONDS |
❌ | 10 |
Today-only summary flush cadence |
STATUS_SUMMARY_MAX_TIMELINE_SEGMENTS |
❌ | 32 |
Max current-day transition segments retained per monitor |
STATUS_SUMMARY_PARTIAL_DOWNTIME_MINUTES |
❌ | 15.0 |
Threshold between partial and full down day states |
STATUS_SUMMARY_REDIS_PREFIX |
❌ | status:summary:v1 |
Redis key prefix for persistent summary keys |
Statrix supports email notifications for downtime and recovery using Gmail SMTP — no paid email APIs required.
| ✅ Free | ✅ Reliable for monitoring alerts |
| ✅ Easy to migrate later | ❌ Not suitable for bulk/marketing email |
⚠️ Gmail may showvia gmail.comin some clients. This is expected for Gmail SMTP.
| Setting | Value |
|---|---|
| From address | alerts@your-domain.tld |
| SMTP provider | Gmail (smtp.gmail.com) |
| Authentication | App Password (requires 2-Step Verification) |
- A dedicated Gmail account (e.g.
statrix.alerts@gmail.com) - 2-Step Verification enabled on that Google account
- Access to your DNS provider (Cloudflare, Namecheap, etc.)
- Sign in to the Gmail account.
- Go to Settings → See all settings → Accounts and Import.
- Under Send mail as, select Add another email address.
- Configure:
- Name:
Statrix Alerts - Email:
alerts@your-domain.tld - Treat as alias: unchecked
- Name:
| Setting | Value |
|---|---|
| SMTP Server | smtp.gmail.com |
| Port | 587 |
| Username | statrix.alerts@gmail.com |
| Password | Your App Password |
| Security | TLS |
🔒 Important: Do not use your Gmail account password. Use an App Password only.
If alerts@your-domain.tld has no mailbox, use temporary forwarding for one-time verification:
- Enable email routing at your DNS provider.
- Create route:
alerts@your-domain.tld→your-personal@gmail.com. - Add required MX records.
- In Gmail, click Verify.
- Open forwarded verification email and confirm.
After verification, you can safely remove the temporary forwarding rule and MX records. Gmail keeps the sender verified.
SPF (required):
your-domain.tld TXT "v=spf1 include:_spf.google.com ~all"
DMARC (recommended):
_dmarc.your-domain.tld TXT "v=DMARC1; p=none"
import smtplib
from email.message import EmailMessage
from datetime import datetime, timezone
SMTP_SERVER = "smtp.gmail.com"
SMTP_PORT = 587
SMTP_USER = "statrix.alerts@gmail.com"
SMTP_PASS = "APP_PASSWORD"
FROM_EMAIL = "Statrix Alerts <alerts@your-domain.tld>"
TO_EMAIL = "your-personal@gmail.com"
msg = EmailMessage()
msg["From"] = FROM_EMAIL
msg["To"] = TO_EMAIL
msg["Subject"] = "Statrix SMTP Test Successful"
msg.set_content(f"""
This is a test email from Statrix.
Time: {datetime.now(timezone.utc).isoformat()} UTC
Status: SMTP delivery OK
""")
with smtplib.SMTP(SMTP_SERVER, SMTP_PORT) as server:
server.starttls()
server.login(SMTP_USER, SMTP_PASS)
server.send_message(msg)
print("✅ Email sent successfully")python smtp_test.pySMTP_SERVER=smtp.gmail.com
SMTP_PORT=587
SMTP_USER=statrix.alerts@gmail.com
SMTP_PASS=APP_PASSWORD
SMTP_FROM=Statrix Alerts <alerts@your-domain.tld>
NOTIFICATION_EMAIL=your-personal@gmail.com- ~100 emails/day on most personal accounts
- Best suited for uptime and transactional alerts
- Not recommended for bulk sending
For full cross-platform agent documentation, see shell/README.md.
- 🖥️ Create a Server Agent monitor in the dashboard.
- 📋 Copy the generated install command.
▶️ Run it on the target host (Linux / macOS / Windows).
The dashboard command includes your exact SID, endpoint URL, and selected monitoring options — no manual configuration needed.
-
GET /healthreturnshealthy - Admin login works at
/edit - Create a test website monitor and force a failure
- Confirm downtime email arrives for a real monitor outage
- Recover the target and verify recovery email
- Confirm status page reflects state changes at
/
💥 App fails at startup
- Verify
DATABASE_URLandJWT_SECRET_KEYare set correctly. - Confirm the database is reachable from the runtime environment.
- Check logs for connection errors.
🔴 Redis / cache errors
- Verify
REDIS_URLusesredis://(plain) orrediss://(TLS). - When
CACHE_FAIL_FAST=true, APIs intentionally return503if cache is unhealthy. - For first deployment, keep
WEB_CONCURRENCY=1. - Statrix falls back to in-memory cache if Redis is unavailable.
📧 No email alerts
- Confirm
SMTP_USER,SMTP_PASS, andNOTIFICATION_EMAILare set. - Verify you're using a Gmail App Password (not your account password).
- Validate sender verification when using a custom from-address.
- Check spam/junk folders.
🖥️ Agent not reporting
- Verify
APP_URLis correct and reachable from the agent host. - Reinstall the agent using the dashboard-generated command.
- Review
shell/README.mdfor agent documentation.
Open-source is hard! If you enjoy this project and want to support its development, please consider sponsoring or donating!
🧸 Support the Project - 地獄の火の悪魔
Made with ❤️ by irisXDR
Inspired by HetrixTools
- irisXDR for creating it from scratch
- Some AI Tools have been used to create certain portions of this repository.




