I used Google Analytics on my sites for years. It worked, but I increasingly felt uncomfortable about what I was handing over: visitor data going to Google, cookie consent banners required by GDPR, and no real understanding of where that data ended up.
Plausible Analytics is the open-source alternative. It's lightweight (the tracking script is under 1 KB — versus GA's 45 KB), cookie-free, GDPR-compliant by design, and you can self-host it so the data never leaves your server.
I run Plausible on Tencent Cloud Lighthouse. The 2 GB RAM / 2 vCPU plan handles Plausible comfortably for sites with moderate traffic; 4 GB for millions of monthly pageviews. Running Plausible on Lighthouse means your visitor analytics data stays on your server — not processed by any third party. As event volume grows, Plausible's ClickHouse database can grow significantly, and CBS cloud disk expansion lets you increase storage without migrating the analytics database. The snapshot feature also protects months of historical analytics data.
- Key Takeaways
Self-hosted Plausible gives you:
The trade-off versus paid Plausible Cloud: you manage the server, handle updates, and monitor disk usage as data accumulates.
| Requirement | Details |
|---|---|
| Server | Ubuntu 22.04, 2 GB+ RAM |
| Docker + Docker Compose | Installed |
| Domain | Required — Plausible needs a domain |
| Email (optional) | For reports and account registration |
curl -fsSL https://get.docker.com | sh
sudo systemctl enable docker
sudo usermod -aG docker $USER
newgrp docker
mkdir -p /opt/plausible
cd /opt/plausible
openssl rand -base64 64 | tr -d '\n'
# Save this output — you'll need it in the next step
nano /opt/plausible/plausible-conf.env
# Required — replace with your values
ADMIN_USER_EMAIL=you@example.com
ADMIN_USER_NAME=Admin
ADMIN_USER_PWD=your-secure-admin-password
BASE_URL=https://analytics.yourdomain.com
SECRET_KEY_BASE=YOUR_GENERATED_SECRET_KEY_HERE
# Disable registration for private instances
DISABLE_REGISTRATION=true
# Optional — for email reports
MAILER_EMAIL=plausible@yourdomain.com
SMTP_HOST_ADDR=smtp.sendgrid.net
SMTP_HOST_PORT=587
SMTP_USER_NAME=apikey
SMTP_USER_PWD=YOUR_SENDGRID_API_KEY
SMTP_HOST_SSL_ENABLED=false
Important: Set DISABLE_REGISTRATION=true if this is a private instance. Otherwise anyone who reaches the URL can create an account.
nano /opt/plausible/docker-compose.yml
version: "3.3"
services:
mail:
image: bytemark/smtp
restart: always
plausible_db:
image: postgres:16-alpine
restart: always
volumes:
- db-data:/var/lib/postgresql/data
environment:
- POSTGRES_PASSWORD=postgres
plausible_events_db:
image: clickhouse/clickhouse-server:23.3.7.5-alpine
restart: always
volumes:
- event-data:/var/lib/clickhouse
- ./clickhouse/clickhouse-config.xml:/etc/clickhouse-server/config.d/logging.xml:ro
- ./clickhouse/clickhouse-user-config.xml:/etc/clickhouse-server/users.d/logging.xml:ro
ulimits:
nofile:
soft: 262144
hard: 262144
plausible:
image: ghcr.io/plausible/community-edition:v2
restart: always
command: sh -c "sleep 10 && /entrypoint.sh db createdb && /entrypoint.sh db migrate && /entrypoint.sh run"
depends_on:
- plausible_db
- plausible_events_db
ports:
- 127.0.0.1:8000:8000
env_file:
- plausible-conf.env
volumes:
db-data:
driver: local
event-data:
driver: local
Plausible uses ClickHouse for event storage. Configure it to reduce logging:
mkdir -p /opt/plausible/clickhouse
nano /opt/plausible/clickhouse/clickhouse-config.xml
<clickhouse>
<logger>
<level>warning</level>
<console>true</console>
</logger>
<query_thread_log remove="remove"/>
<query_log remove="remove"/>
<text_log remove="remove"/>
<trace_log remove="remove"/>
<metric_log remove="remove"/>
<asynchronous_metric_log remove="remove"/>
<session_log remove="remove"/>
<part_log remove="remove"/>
</clickhouse>
nano /opt/plausible/clickhouse/clickhouse-user-config.xml
<clickhouse>
<profiles>
<default>
<log_queries>0</log_queries>
<log_query_threads>0</log_query_threads>
</default>
</profiles>
</clickhouse>
cd /opt/plausible
docker compose up -d
docker compose logs -f
Wait until you see Access PlausibleWeb.Endpoint at http://localhost:8000. The first startup takes about 30–60 seconds as the database initializes.
sudo apt install -y nginx certbot python3-certbot-nginx
sudo nano /etc/nginx/sites-available/plausible
server {
listen 80;
server_name analytics.yourdomain.com;
location / {
proxy_pass http://localhost:8000;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect off;
}
}
sudo ln -s /etc/nginx/sites-available/plausible /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
sudo certbot --nginx -d analytics.yourdomain.com
Navigate to https://analytics.yourdomain.com and log in with your admin credentials from plausible-conf.env.
After logging in:
myblog.com)Plausible provides a JavaScript snippet. Copy it — you'll add it to your website in the next step.
Add to your website's <head> section:
<script defer data-domain="myblog.com"
src="https://analytics.yourdomain.com/js/script.js">
</script>
Plausible can be accessed via a custom path to avoid ad blocker detection. In Plausible: Settings → Custom domain / proxy.
Add to Nginx:
# Proxy the Plausible script through your own domain
location = /analytics.js {
proxy_pass https://analytics.yourdomain.com/js/script.js;
proxy_set_header Host analytics.yourdomain.com;
}
location /api/event {
proxy_pass https://analytics.yourdomain.com/api/event;
proxy_set_header Host analytics.yourdomain.com;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
Then update the script tag to load from your own domain:
<script defer data-domain="myblog.com"
data-api="/api/event"
src="/analytics.js">
</script>
Install the Plausible Analytics WordPress plugin. Configure it to use your self-hosted instance:
analytics.yourdomain.comnpm install next-plausible
In _app.js:
import PlausibleProvider from 'next-plausible'
export default function MyApp({ Component, pageProps }) {
return (
<PlausibleProvider domain="myblog.com" customDomain="https://analytics.yourdomain.com">
<Component {...pageProps} />
</PlausibleProvider>
)
}
Add the script tag to your layout template (usually in layouts/_default/baseof.html for Hugo or _includes/head.html for Jekyll).
In Plausible dashboard → Site Settings → Email reports:
Set up traffic spike notifications:
After a few weeks, Plausible was reporting numbers much lower than expected — about 60% less than my previous analytics.
I thought something was wrong with the tracking script. After digging into the browser console, I found many visitors' requests to /api/event were being blocked by their ad blockers (uBlock Origin, Brave, etc.). Even though Plausible itself is privacy-friendly, the common ad blocking lists include patterns that match /api/event on unknown domains.
The fix: Set up the reverse proxy on your own website's domain (as described in Part 5 under "Custom Script Path"):
# Add to your website's Nginx config (not Plausible's Nginx)
location = /analytics.js {
proxy_pass https://analytics.yourdomain.com/js/script.js;
}
location /api/event {
proxy_pass https://analytics.yourdomain.com/api/event;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
By loading the script from your own domain and sending events to your own domain, it's effectively invisible to blockers. After this change, tracking accuracy improved significantly.
| Issue | Likely Cause | Fix |
|---|---|---|
| Plausible not starting | Database init taking time | Wait 60 seconds; check docker compose logs |
| No data appearing | Script not loading | Check browser console for script errors |
| "Domain mismatch" error | Wrong domain in script tag | Verify data-domain matches what's in Plausible |
| Low pageview counts | Ad blockers filtering | Use reverse proxy from your own domain (Part 5) |
| ClickHouse using too much disk | Normal data accumulation | Set data retention in Settings → Billing |
| Can't log in | Wrong credentials | Check plausible-conf.env for admin email/password |
| 502 from Nginx | Plausible not running | docker compose ps and check docker compose up -d |
| SMTP email not working | Config error | Test SMTP credentials with a standalone mail test |
✅ What you built:
https://analytics.yourdomain.comEvery website you add costs nothing extra — one Plausible instance handles all your sites. The data stays on your server, there are no GDPR cookie consent hoops, and the dashboard is refreshingly simple.
Is self-hosted Plausible Analytics GDPR compliant?
Self-hosted Plausible Analytics can be configured to be GDPR compliant — no data leaves your server, and many configurations don't require cookie consent banners because no personally identifiable data is collected.
How accurate is self-hosted analytics compared to other services?
Self-hosted analytics that serves tracking scripts from your own domain (avoiding ad blocker detection) often measures more accurately than third-party scripts that are commonly blocked.
How do I add tracking to multiple websites?
Most self-hosted analytics tools support multiple sites from a single installation. Add each site in the admin panel and get a separate tracking code for each.
How much server resource does Plausible Analytics need?
Analytics databases grow over time. The 2 vCPU / 4 GB RAM plan handles millions of monthly pageviews. Use CBS cloud disk expansion as the database grows.
👉 Get started with Tencent Cloud Lighthouse
👉 View current pricing and launch promotions
👉 Explore all active deals and offers