FAQ
Frequently asked questions about TideMeter.
General
What is TideMeter?
TideMeter is a self-hosted, privacy-focused web analytics platform. It provides insights about your website traffic without collecting personal data or using cookies.
Is TideMeter free?
Yes. TideMeter is open source under the MIT License and completely free to self-host. You only pay for your own server infrastructure.
How does TideMeter compare to Google Analytics?
TideMeter focuses on privacy and simplicity. Unlike Google Analytics, TideMeter:
- Doesn’t use cookies or require consent banners
- Doesn’t collect personal data
- Keeps all data on your servers
- Has a much smaller tracking script (~1.5KB vs ~45KB)
- Provides a simpler, more focused dashboard
How does TideMeter compare to Plausible or Umami?
TideMeter shares the privacy-first philosophy but differentiates with:
- PayloadCMS-based admin panel
- Dual database support (PostgreSQL + ClickHouse)
- Modern Next.js 16 stack with Turbopack
- Built-in team management
Privacy
Does TideMeter use cookies?
No. TideMeter never creates or reads cookies on your visitors’ browsers.
How does TideMeter identify unique visitors?
TideMeter generates a visitor hash using SHA-256, combining:
- The visitor’s IP address
- The User-Agent string
- The website ID
- A daily rotating salt
This hash changes every day, making cross-day tracking impossible. The raw IP address is never stored.
Do I need a cookie consent banner?
No. Since TideMeter doesn’t use cookies or collect personal data, cookie consent banners are not required under GDPR, ePrivacy Directive, or CCPA.
Is TideMeter GDPR compliant?
Yes. TideMeter is designed to be GDPR compliant by architecture:
- No personal data is processed or stored
- No cookies or persistent identifiers
- All data stays on your own servers
- No data transfers to third parties
Technical
What are the system requirements?
Minimum:
- 1 CPU core
- 1 GB RAM
- 10 GB disk space
- Docker (recommended) or Node.js 22+
Which databases are supported?
- PostgreSQL — Default, recommended for most use cases (up to ~100K daily events)
- ClickHouse — Optional, for high-volume analytics (millions of events/day)
- SQLite — Planned, for simple single-server deployments
Does TideMeter support Single Page Applications (SPAs)?
Yes. The tracker automatically detects SPA navigation via the History API. Works with Next.js, React Router, Vue Router, SvelteKit, and any framework using pushState/replaceState.
Can I track multiple websites?
Yes. TideMeter supports unlimited websites from a single instance. Each website gets its own dashboard and tracking ID.
How do I upgrade TideMeter?
git pull origin main
pnpm install
pnpm build
# Restart your serverDoes TideMeter affect my site’s performance?
The tracking script is under 1.5KB gzipped and loads with the defer attribute. It has zero impact on Core Web Vitals and page load times.
Troubleshooting
The tracker isn’t recording visits
- Check that
data-website-idmatches your website configuration - Verify the script URL points to your TideMeter instance
- Check browser console for network errors
- Ensure your server is running and accessible
The dashboard shows no data
- Verify the tracker is installed correctly (see above)
- Check database connectivity in your
.envfile - Look at server logs for error messages
- Ensure the correct
ANALYTICS_DB_TYPEis configured
Build fails with DATABASE_URL error
The web app build requires DATABASE_URL to be set. Even a dummy value works:
DATABASE_URL="postgresql://x:x@localhost:5480/x" pnpm buildI deployed the image, the DB is connected, but no tables were created
This is expected on a brand-new deploy and resolves itself as soon as something hits the app.
TideMeter does not run migrations at container start. Schema creation happens lazily on the first request that initializes PayloadCMS — typically the Kubernetes readiness/startup probe calling /api/health. Until that first call, the database stays empty.
If you check the database immediately after kubectl apply and see no tables, wait for the pod to become Ready (or just curl the pod’s /api/health once) and check again. On a fresh pod the init does the full Payload schema migration + analytics SQL migrations in one go.
If tables still don’t appear after the pod is Ready:
- Check the pod logs for
[payload:onInit]errors — migration failures are re-thrown and/api/healthreturns 503. - Verify the
DATABASE_URLrole hasCREATEprivileges on the target schema. - Confirm you’re inspecting the same database the secret points at.
See Configuration → Database Migrations for the full startup sequence.
How do I use ClickHouse for analytics?
Set the ANALYTICS_DB_TYPE environment variable to clickhouse and provide the ClickHouse connection details:
ANALYTICS_DB_TYPE=clickhouse
CLICKHOUSE_URL=http://localhost:8124
CLICKHOUSE_DATABASE=tidemeter_analyticsUse the Docker Compose ClickHouse override for local development:
docker compose -f docker/docker-compose.yml -f docker/docker-compose.ch.yml up -dCan I track custom events?
Yes. Use the tracker’s JavaScript API to send named events with custom properties:
tidemeter.track("signup", { plan: "pro" });
tidemeter.track("purchase", { amount: 29.99, currency: "USD" });Can I identify users?
Yes. Use tidemeter.identify("user-id") to link anonymous visitor sessions to a known user ID. This enables per-user analytics in the visitor journey view.
How do I create the first admin user?
On a fresh database with no users, open /admin in your browser. PayloadCMS automatically redirects you to /admin/create-first-user where you set the email and password for the initial admin. No SMTP server or external email is required. Subsequent users are created from the admin panel by an existing admin.
Do I need to configure email?
No, it’s optional. TideMeter only uses email for password reset and account verification flows. If you skip email configuration:
- The first admin can still be created via
/admin/create-first-user. - Logging in and changing your password from
/admin/accountwork normally. - Payload prints a one-time
WARN: No email adapter providedon startup and writes any email it would have sent to stdout.
For single-user or private deployments, leaving email unconfigured is a perfectly valid choice.
To enable real delivery (so “forgot password” links work), TideMeter supports two backends, picked in this order:
- Resend — set
RESEND_API_KEY. Uses Resend’s HTTP API via@payloadcms/email-resend. No SMTP port required. - SMTP — set
SMTP_HOST(+SMTP_PORT,SMTP_USER,SMTP_PASSWORD). Uses Nodemailer and works with any SMTP provider (your own Postfix, Gmail, SendGrid, Mailgun, Postmark, AWS SES, etc.).
In both cases set SMTP_FROM_ADDRESS and SMTP_FROM_NAME for the visible From header. See Configuration → Email for the full table and provider-specific SMTP_USER conventions (e.g. SendGrid requires the literal username apikey).
I forgot my password and email isn’t configured. What now?
Connect to the PostgreSQL database and reset it directly. Payload stores password hashes in the users table; the simplest path is to delete the row and let /admin/create-first-user recreate the account on next visit:
DELETE FROM users WHERE email = '[email protected]';Then restart the app and visit /admin. (If other users exist, instead use the admin panel as another admin user, or configure SMTP and use the forgot-password flow.)