Built a Self-Hostable Plausible + Sentry Alternative in One Day
Source: Dev.to
What it does
Drop one script tag on your site:
From that point you get:
- Pageviews, sessions, unique visitors, bounce rate
- Country / region / city breakdown (via local MaxMind GeoLite2 — no runtime API calls)
- Device, OS, browser breakdown
- Referrer categorisation — organic, social, email, referral, direct
- UTM campaign tracking
- JavaScript errors auto‑caught (
window.onerrorandunhandledrejection), grouped by fingerprint - Manual error tracking from any backend over a single HTTP call
- Audit logging
- Tracked link shortener with click analytics
All of it hits your own database. Nothing leaves your server.
The constraint that shaped everything
Shared hosting means no Redis, no background workers, no daemons, no WebSockets. You get PHP and MySQL and that’s it. This forced some interesting decisions.
Rate limiting without Redis
Most rate limiters use Redis or a DB table with a timestamp. I went file‑based – an append‑only .req file per request, stored in a per‑IP directory. Counting recent requests = counting files newer than the window.
// Count recent attempts — each file is one request
foreach (glob($userDir . "/*.req") as $file) {
if ($now - filemtime($file) (code snippet as provided)
If you’re on shared hosting, running a privacy‑first product, or just tired of paying for tools you could own—give it a try. Issues and pull requests are welcome.
Roadmap (v2)
- Webhooks for error alerts
- Redis caching (opt‑in)
- Async queuing
If you have thoughts on what matters most, please open an issue.