Why duplicate subscriptions appear and how to resolve them
Last updated: June 25, 2026
A customer can have multiple subscriptions for one plan. This happens because Lago deduplicates on external_id, not on plan: reuse an active subscription's external_id and Lago returns the existing one instead of creating a row, but send a different external_id and you get a second subscription that bills independently. Multiple active subscriptions per customer are allowed by design, so Lago treats two distinct IDs on the same plan as intentional. Accidental duplicates almost always trace to an integration generating a fresh external_id on each retry.
How to confirm it
Query List Subscriptions filtered by customer and plan, then compare the external_id of each active entry:
GET /api/v1/subscriptions?external_customer_id={customer_id}&plan_code={plan_code}&status[]=activeMore than one entry with distinct IDs means duplicates.
On self-hosted deployments, run the SQL below:
SELECT customer_id, plan_id, COUNT(*) AS active_count, array_agg(external_id) AS external_ids
FROM subscriptions
WHERE status = 1GROUP BY customer_id, plan_id
HAVING COUNT(*) > 1;How to resolve it
Decide which subscription to keep, then terminate each unwanted one by its external_id:
DELETE /api/v1/subscriptions/{external_id}Then review any invoices the duplicate generated and issue credit notes for incorrect charges.
How to prevent it
Use a stable, deterministic external_id derived from your own subscription or order ID, never a fresh value per attempt. Retries and duplicate webhooks are then safe automatically, because the repeated ID resolves to the existing subscription. We advise against adding your own check that blocks creation when the same plan is already active; it duplicates Lago's external_id guard and would wrongly block intentional multi-subscriptions.
This article reflects guidance drawn from customer case resolutions. It is not officially supported documentation and may not apply to all situations.