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.)
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?
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.