GlitchTip: Self-Hosted Error Tracking Without the Sentry Price Tag
Your application crashes at 2 AM. A user reports a vague bug. Your logs are a wall of text across six containers. You spend an hour grepping through log files to find the stack trace, then another hour figuring out which deployment introduced the problem.
Photo by Markus Spiske on Unsplash
Error tracking tools solve this by capturing exceptions as they happen, grouping them by root cause, and giving you the stack trace, context, and affected user count in one view. Sentry is the gold standard, but their self-hosted edition is notoriously complex, and their cloud pricing starts at $26/month.
GlitchTip is a lightweight, open-source error tracking platform that's compatible with Sentry's SDKs. If your application already uses a Sentry SDK, switching to GlitchTip is as simple as changing the DSN URL. You get error tracking, basic performance monitoring, and uptime checks -- all self-hosted in a Docker stack that actually stays manageable.
What GlitchTip Provides
- Error tracking -- Captures exceptions with full stack traces, grouped by issue
- Sentry SDK compatible -- Works with all official Sentry SDKs (Python, JavaScript, Go, Rust, Java, etc.)
- Performance monitoring -- Basic transaction tracing and response time tracking
- Uptime monitoring -- HTTP health checks for your services
- Alerting -- Email, webhook, Slack, and Microsoft Teams notifications
- Issue management -- Mark issues as resolved, ignored, or assign to team members
- Multi-project -- Organize errors by application or service
- Lightweight -- Runs on a fraction of the resources Sentry requires
Docker Deployment
# docker-compose.yml
services:
web:
image: glitchtip/glitchtip:latest
ports:
- "8000:8000"
environment: &environment
DATABASE_URL: postgresql://glitchtip:glitchtippass@db:5432/glitchtip
SECRET_KEY: your-random-secret-key
PORT: 8000
GLITCHTIP_DOMAIN: https://errors.yourdomain.com
DEFAULT_FROM_EMAIL: [email protected]
EMAIL_URL: smtp+tls://user:[email protected]:587
CELERY_WORKER_AUTOSCALE: "1,3"
CELERY_WORKER_MAX_TASKS_PER_CHILD: "10000"
depends_on:
- db
- redis
restart: unless-stopped
worker:
image: glitchtip/glitchtip:latest
command: ./bin/run-celery-with-beat.sh
environment: *environment
depends_on:
- db
- redis
restart: unless-stopped
db:
image: postgres:16
volumes:
- glitchtip_db:/var/lib/postgresql/data
environment:
POSTGRES_DB: glitchtip
POSTGRES_USER: glitchtip
POSTGRES_PASSWORD: glitchtippass
restart: unless-stopped
redis:
image: redis:7-alpine
restart: unless-stopped
volumes:
glitchtip_db:
# Generate a secret key
python3 -c "import secrets; print(secrets.token_hex(32))"
# Start GlitchTip
docker compose up -d
# Create the first admin user
docker compose exec web ./manage.py createsuperuser
Access GlitchTip at http://your-server:8000.
Key architecture notes:
- The
webservice handles the API and web dashboard - The
workerservice runs Celery background tasks (processing events, sending alerts, cleanup) - Redis is used as the Celery broker and for caching
GLITCHTIP_DOMAINmust match your public URL -- it's used to generate DSN URLs and email links- The YAML anchor (
&environment/*environment) ensures both web and worker share the same config
SDK Integration
GlitchTip uses the Sentry SDK protocol. Install the Sentry SDK for your language and point it at your GlitchTip instance.
Get Your DSN
- Create a project in GlitchTip (e.g., "web-app", "api-server")
- Copy the DSN from the project settings -- it looks like:
https://[email protected]/1
Python (Django/Flask/FastAPI)
pip install sentry-sdk
import sentry_sdk
sentry_sdk.init(
dsn="https://[email protected]/1",
traces_sample_rate=0.1, # 10% of transactions for performance monitoring
environment="production",
release="v1.2.3",
)
For Django, add the integration:
import sentry_sdk
from sentry_sdk.integrations.django import DjangoIntegration
sentry_sdk.init(
dsn="https://[email protected]/1",
integrations=[DjangoIntegration()],
traces_sample_rate=0.1,
)
JavaScript (Node.js)
npm install @sentry/node
const Sentry = require("@sentry/node");
Sentry.init({
dsn: "https://[email protected]/1",
tracesSampleRate: 0.1,
environment: "production",
release: "v1.2.3",
});
JavaScript (Browser)
npm install @sentry/browser
import * as Sentry from "@sentry/browser";
Sentry.init({
dsn: "https://[email protected]/1",
tracesSampleRate: 0.1,
environment: "production",
});
Go
go get github.com/getsentry/sentry-go
import "github.com/getsentry/sentry-go"
func main() {
sentry.Init(sentry.ClientOptions{
Dsn: "https://[email protected]/1",
TracesSampleRate: 0.1,
Environment: "production",
Release: "v1.2.3",
})
defer sentry.Flush(2 * time.Second)
}
The Sentry SDK handles everything automatically: uncaught exceptions are captured with full stack traces, context (OS, browser, runtime version), and breadcrumbs (recent events leading up to the error).
Like what you're reading? Subscribe to Self-Hosted Weekly — free weekly guides in your inbox.
Alerting
Email Alerts
GlitchTip sends email notifications by default when new issues are detected. Configure SMTP in the Docker environment:
EMAIL_URL: smtp+tls://user:[email protected]:587
DEFAULT_FROM_EMAIL: [email protected]
Webhook Alerts
For Discord, ntfy, or custom integrations:
- Go to your project's Settings > Alerts
- Add a webhook URL
- GlitchTip sends a JSON payload when new issues are detected:
{
"alias": "my-project",
"text": "GlitchTip Alert",
"title": "New Issue: TypeError: Cannot read property 'id' of undefined",
"url": "https://errors.yourdomain.com/my-org/issues/42"
}
Slack and Microsoft Teams
Native integrations are available in the project alert settings. Add your Slack webhook URL or Teams connector URL directly.
Alert Rules
Configure when alerts fire:
- Every new issue -- Get notified for every unique error
- Issue frequency -- Alert when an issue occurs more than N times in a time window
- Regression -- Alert when a previously resolved issue reappears
Performance Monitoring
GlitchTip supports basic transaction tracing when you set traces_sample_rate in the SDK. This gives you:
- Transaction list -- API endpoints and their average response times
- Slow transactions -- Identify which endpoints are slow
- Throughput -- Requests per minute per endpoint
This is not a replacement for dedicated APM tools like Grafana Tempo or Jaeger, but it covers the basics: "which endpoints are slow, and how slow?"
Uptime Monitoring
GlitchTip includes built-in uptime monitoring -- simple HTTP checks that verify your services are responding:
- Go to Uptime Monitors
- Add a URL and check interval (1, 5, 10, or 15 minutes)
- GlitchTip checks the URL and alerts if it's down
This overlaps with tools like Uptime Kuma, but having it in the same dashboard as your error tracking means one fewer tool to maintain.
GlitchTip vs Sentry
| Feature | GlitchTip | Sentry (Self-Hosted) | Sentry (Cloud) |
|---|---|---|---|
| Docker complexity | 4 containers | 20+ containers | N/A (hosted) |
| RAM usage | ~512 MB | 4+ GB | N/A |
| SDK compatibility | Sentry SDKs | Sentry SDKs | Sentry SDKs |
| Error tracking | Yes | Yes | Yes |
| Performance monitoring | Basic | Full | Full |
| Session replay | No | Yes | Yes |
| Profiling | No | Yes | Yes |
| Release tracking | Basic | Full | Full |
| Issue assignment | Yes | Yes | Yes |
| Source maps | Yes | Yes | Yes |
| Uptime monitoring | Yes | No | Yes |
| Pricing | Free (self-hosted) | Free (self-hosted) | $26+/month |
| Maintenance burden | Low | High | None |
Choose GlitchTip When
- You want error tracking without running 20+ Docker containers
- Basic performance monitoring is enough for your needs
- You're running a small team (1-10 developers) with moderate error volumes
- You want a simple, low-maintenance deployment
- You don't need session replay or profiling features
Choose Sentry When
- You need detailed performance tracing with distributed tracing
- You need session replay to see exactly what users experienced
- You have a large team and need advanced workflow features
- Your error volume justifies the infrastructure cost
Data Retention and Cleanup
GlitchTip stores events in PostgreSQL. Without cleanup, the database grows indefinitely.
Configure automatic cleanup:
environment:
GLITCHTIP_MAX_EVENT_LIFE_DAYS: 90 # Delete events older than 90 days
The Celery worker handles cleanup in the background. For high-volume applications, consider:
- Lower retention periods (30 days)
- Higher
traces_sample_rateonly in staging, lower (0.01-0.1) in production - Rate limiting in the SDK to cap events per minute
Production Tips
Reverse Proxy
Put GlitchTip behind a reverse proxy with HTTPS. Example Caddy config:
errors.yourdomain.com {
reverse_proxy localhost:8000
}
Backups
# Database backup (contains all errors, issues, and config)
docker exec glitchtip-db-1 pg_dump -U glitchtip glitchtip > glitchtip-backup.sql
Source Maps
For JavaScript applications, upload source maps so stack traces show original code, not minified bundles:
# Using sentry-cli (works with GlitchTip)
sentry-cli --url https://errors.yourdomain.com sourcemaps upload \
--org my-org --project my-project \
--release v1.2.3 ./dist
The Bottom Line
GlitchTip does 80% of what Sentry does with 20% of the operational complexity. Four Docker containers instead of twenty. Half a gigabyte of RAM instead of four. Full Sentry SDK compatibility means you're not locked in -- if you outgrow GlitchTip, you can switch to Sentry Cloud or self-hosted Sentry by changing the DSN. For most self-hosters and small teams, GlitchTip's error tracking, basic performance monitoring, and uptime checks are exactly enough to answer the question that matters: "what's broken, and since when?"
