Implement Tenant-Level Usage Tracking

Hi guys
I’m building a multi-tenant automation platform on top of n8n and need a reliable way to track usage for billing and reporting.
Each tenant generates:
Workflow executions
WhatsApp messages
API requests
AI/LLM calls
File processing jobs
I’d like to measure usage per tenant and support things like:Free Plan → 1,000 messages/month
Pro Plan → 10,000 messages/month
Enterprise → Custom limits
My concerns are: Accurate usage tracking across multiple workers
Preventing double-counting during retries
Real-time quota enforcement
Historical reporting and invoicing
I’m considering: Usage events stored in PostgreSQL
Redis counters for real-time limits
Separate billing service
Event-driven usage tracking

Describe the problem/error/question

For teams running multi-tenant n8n systems: How are you tracking and enforcing tenant usage?
Do you calculate usage in real time or aggregate later?
Any patterns that work well for billing, quotas, and reporting at scale?

What is the error message (if any)?

Please share your workflow

(Select the nodes on your canvas and use the keyboard shortcuts CMD+C/CTRL+C and CMD+V/CTRL+V to copy and paste the workflow.)

Share the output returned by the last node

Information on your n8n setup

  • n8n version:
  • Database (default: SQLite):
  • n8n EXECUTIONS_PROCESS setting (default: own, main):
  • Running n8n via (Docker, npm, n8n cloud, desktop app):
  • Operating system:

Hello @Emmas A common production approach is to use real-time tracking for limits and database records for billing/reporting.

Workflow → Record Usage Event → Update Counter → Continue Processing

Track usage per tenant_id, such as:
Messages sent
API calls
Workflow executions
AI requests

For quota enforcement Many teams use Redis counters for fast checks:tenant_id → current_usage → plan_limit

If a tenant exceeds their limit, block or throttle new requests.

For billing make sure to Store usage events in a database and generate reports or invoices from that data.
This gives:Accurate billing history
Auditing
Monthly reporting

Helps to Avoid: Counting only workflow executions
Relying solely on Redis for billing data
Ignoring retries (they can cause double-counting)

The important boundary is the idempotency key for each billable event, not Redis vs Postgres.

Emit one append-only usage_event with tenant_id, meter (whatsapp_message, llm_call, file_job), source run/message id, period and units. Put a unique constraint on that event key, then update the Redis counter only after the insert succeeds. A retry replays the same key and does not create a second billable row; invoices come from the event table or monthly rollups, while Redis is just the fast pre-check.

Which meter is causing the most risk right now: WhatsApp sends, LLM calls, or file jobs?

Thanks guys @Niffzy @oimrqs_ops for the detailed explanation and sharing your experience

The Redis + PostgreSQL hybrid Niffzy described is the right architecture. For the double-counting problem specifically, the cleanest n8n pattern is to use the execution ID as an idempotency key: at the start of each workflow, store $execution.id in Redis with a TTL (e.g. 24h) using SET execution:{id} 1 EX 86400 NX. If the SET returns 0 (key existed), skip the usage increment - that execution was already counted. This handles retries without overcounting and works even across multiple n8n workers since Redis is shared.