lago icon indicating copy to clipboard operation
lago copied to clipboard

[BUG]: Ingested event not counted in usage metrics (events_count = 0)

Open Pederzh opened this issue 11 months ago • 8 comments

Describe the bug Events are successfully ingested and visible in the developer events UI, but they are not being counted in the usage API response. When creating an event for an existing user and subscription, the event appears in /developer/events but the events_count remains 0 when fetching current usage via the API.

To Reproduce

  • Customer ID: stripe-customer-test
  • Subscription ID: test_id
  • Billable Metric: "Chat Number" (code: chat_number, aggregation: count_agg)

Steps to reproduce the behavior:

  1. Create an event for an existing user and subscription:

    curl --location --request POST '${LAGO_URL}/api/v1/events' \
    --header 'Authorization: Bearer ••••••' \
    --header 'Content-Type: application/json' \
    --data '{
        "event": {
            "transaction_id": "random-id-1",
            "external_subscription_id": "test_id",
            "code": "chat_number"
        }
    }'
    
  2. Verify the event was created successfully (returns event with lago_id)

  3. Check the event appears in the developer events UI at /developer/events Image

  4. Retrieve current usage for the customer:

    curl --location --request GET '${LAGO_URL}/api/v1/customers/stripe-customer-test/current_usage?external_subscription_id=test_id' \
    --header 'Authorization: Bearer •••••' \
    --header 'Content-Type: application/json'
    
  5. Observe that events_count is 0 instead of 1

Expected behavior After successfully creating an event, the usage API should reflect the event in the count. Specifically, events_count should be 1 for the billable metric "Chat Number" with code "chat_number".

Actual behavior

  • Event creation API returns success with lago_id: "0b46a06c-5b14-4a63-bb3a-5054df47ebc9"
  • Event is visible in /developer/events UI with correct payload
  • Usage API returns "events_count": 0 instead of expected "events_count": 1
  • lago_customer_id and lago_subscription_id are null in the event response

API Responses

Event creation response:

{
    "event": {
        "lago_id": "0b46a06c-5b14-4a63-bb3a-5054df47ebc9",
        "transaction_id": "random-id-1",
        "lago_customer_id": null,
        "code": "chat_number",
        "timestamp": "2025-05-26T22:53:00.937Z",
        "precise_total_amount_cents": null,
        "properties": {},
        "lago_subscription_id": null,
        "external_subscription_id": "test_id",
        "created_at": "2025-05-26T22:53:01Z"
    }
}

Usage API response:

{
    "customer_usage": {
        "from_datetime": "2025-05-26T00:00:00Z",
        "to_datetime": "2025-06-25T23:59:59Z",
        "issuing_date": "2025-06-25",
        "currency": "USD",
        "amount_cents": 0,
        "total_amount_cents": 0,
        "taxes_amount_cents": 0,
        "lago_invoice_id": null,
        "charges_usage": [{
            "units": "0.0",
            "events_count": 0,
            "amount_cents": 0,
            "amount_currency": "USD",
            "charge": {
                "lago_id": "a85ad6d7-9476-45a0-9558-f2f898424ed8",
                "charge_model": "standard",
                "invoice_display_name": null
            },
            "billable_metric": {
                "lago_id": "affa4df0-8978-4546-a9f9-a90f2938e8d9",
                "name": "Chat Number",
                "code": "chat_number",
                "aggregation_type": "count_agg"
            },
            "filters": [],
            "grouped_usage": []
        }]
    }
}

Environment

  • Lago Version: v1.28.1 (Docker Hub)
  • Deployment: Railway

Additional context

  • The event shows lago_customer_id: null and lago_subscription_id: null in the response, which might be related to the issue
  • The billable metric uses count_agg aggregation type
  • The charge model is "standard"
  • Events are visible in the UI but not reflected in usage calculations

Pederzh avatar May 26 '25 23:05 Pederzh

Hello @Pederzh can you share you subscription details?

jdenquin avatar May 27 '25 12:05 jdenquin

Sure! Thanks for the prompt answer @jdenquin! Just out of curiosity, is the lago-worker involved in the current_usage compute?

Here's the subscription details:

{
   "subscription":{
      "lago_id":"371f82e9-538a-4c2a-ad0e-d9d2da506c15",
      "external_id":"test_id",
      "lago_customer_id":"5ed9e8f8-2d8a-4146-aa8c-540709ba1380",
      "external_customer_id":"stripe-customer-test",
      "name":"",
      "plan_code":"test",
      "status":"active",
      "billing_time":"anniversary",
      "subscription_at":"2025-05-26T00:00:00Z",
      "started_at":"2025-05-26T00:00:00Z",
      "trial_ended_at":null,
      "ending_at":null,
      "terminated_at":null,
      "canceled_at":null,
      "created_at":"2025-05-26T22:43:47Z",
      "previous_plan_code":null,
      "next_plan_code":null,
      "downgrade_plan_date":null,
      "current_billing_period_started_at":"2025-05-26T00:00:00Z",
      "current_billing_period_ending_at":"2025-06-25T23:59:59Z",
      "plan":{
         "lago_id":"2d8d7f50-c989-4ef1-969a-47c99b4d5e94",
         "name":"test",
         "invoice_display_name":null,
         "created_at":"2025-05-26T22:43:14Z",
         "code":"test",
         "interval":"monthly",
         "description":"",
         "amount_cents":0,
         "amount_currency":"USD",
         "trial_period":0.0,
         "pay_in_advance":false,
         "bill_charges_monthly":null,
         "customers_count":0,
         "active_subscriptions_count":0,
         "draft_invoices_count":0,
         "parent_id":null,
         "charges":[
            {
               "lago_id":"a85ad6d7-9476-45a0-9558-f2f898424ed8",
               "lago_billable_metric_id":"affa4df0-8978-4546-a9f9-a90f2938e8d9",
               "invoice_display_name":null,
               "billable_metric_code":"chat_number",
               "created_at":"2025-05-26T22:43:14Z",
               "charge_model":"standard",
               "invoiceable":true,
               "regroup_paid_fees":null,
               "pay_in_advance":false,
               "prorated":false,
               "min_amount_cents":0,
               "properties":{
                  "amount":"0.3"
               },
               "filters":[
                  
               ],
               "taxes":[
                  
               ]
            }
         ],
         "usage_thresholds":[
            
         ],
         "taxes":[
            
         ]
      }
   }
}

Pederzh avatar May 27 '25 14:05 Pederzh

Well, it depends on your Lago configuration, do you use only one worker? If yes, it has an impact on the usage ingestion, it invalidate/refresh the cache for current_usage endpoint!

jdenquin avatar May 27 '25 15:05 jdenquin

I've encountered the same issue, and clearing the Redis cache seems to resolve it. However, shouldn't the current usage cache automatically refresh when a new event is recorded?

joshuacadman01 avatar Jun 19 '25 08:06 joshuacadman01

Hey @joshuacadman01 no, the cache will be refreshed when you'll call the current_usage endpoint (on API or UI). When you send a new event, we invalidate the cache for the associated charge/charge_filter

jdenquin avatar Jun 19 '25 15:06 jdenquin

@Pederzh is your issue fixed?

jdenquin avatar Jun 30 '25 09:06 jdenquin

I am getting the same error as @Pederzh. I create a Billable metric:

curl --location --request POST "http://localhost3300/api/v1/billable_metrics" \
  --header "Authorization: Bearer <token>" \
  --header 'Content-Type: application/json' \
  --data-raw '{
    "billable_metric": {
      "name": "AI Response Cost",
      "code": "tokens",
      "description": "Cost for AI model responses",
      "aggregation_type": "sum_agg",
      "field_name": "response_cost",
      "recurring": false
    }

Then assign it to a plan:

curl --location --request POST "http://localhost:3300/api/v1/plans" \
  --header "Authorization: Bearer <token>" \
  --header 'Content-Type: application/json' \
  --data-raw '{
    "plan": {
      "name": "AI Usage Plan",
      "code": "ai_plan",
      "amount_cents": 0,
      "amount_currency": "EUR",
      "pay_in_advance": false,
      "interval": "monthly",
      "charges": [{
        "billable_metric_id": "f4d525f1-fbc1-499a-a688-3a49990c9ec1",
        "charge_model": "dynamic"
      }]
    }
  }'

Then i create a user:

curl --location --request POST "http://localhost:3300/api/v1/customers" \
  --header "Authorization: Bearer  <token>" \
  --header 'Content-Type: application/json' \
  --data-raw '{
    "customer": {
      "external_id": "test_user",
      "name": "Test User",
      "email": "[email protected]"
    }
  }'

assign it to the previous plan:

curl --location --request POST "http://localhost:3300/api/v1/subscriptions" \
  --header "Authorization: Bearer <token>" \
  --header 'Content-Type: application/json' \
  --data-raw '{
    "subscription": {
      "external_customer_id": "test_user",
      "plan_code": "ai_plan",
      "external_id": "test_user"
    }
  }'

After that i post an event:

curl --location --request POST "http://localhost:3300/api/v1/events" \
  --header "Authorization: Bearer <token>" \
  --header 'Content-Type: application/json' \
  --data-raw '{
    "event": {
      "transaction_id": "796ea9e2-1f09-4d03-a82b-34dfs52f872d",
      "external_subscription_id": "test_user",
      "code": "tokens",
      "timestamp": 1756978800,
      "properties": {
        "model": "gpt-5",
        "total_tokens": 11045,
        "prompt_tokens": 10310,
        "response_cost": 0.020237500000000002,
        "completion_tokens": 735
      }
    }
  }'

I get the following result:

{
   "event":{
      "lago_id":"2b95564a-c32f-435d-913e-c3fc3fb0bb8c",
      "transaction_id":"796ea9e2-1f09-4d03-a82b-34dfs525872d",
      "lago_customer_id":null,
      "code":"tokens",
      "timestamp":"2025-09-04T09:40:00.000Z",
      "precise_total_amount_cents":null,
      "properties":{
         "model":"gpt-5",
         "total_tokens":11045,
         "prompt_tokens":10310,
         "response_cost":0.020237500000000002,
         "completion_tokens":735
      },
      "lago_subscription_id":null,
      "external_subscription_id":"test_user",
      "created_at":"2025-09-04T13:22:01Z"
   }
}

The lago_subscription_id=null and lago_customer_id=null. The usage is also not being recorded in the UI.

suleimanelkhoury avatar Sep 04 '25 13:09 suleimanelkhoury

On a second note, the Event gets recorded only if i create the user and the subscription form the UI, copy the external subscription ID that is automatically generated, and then use it inside the event.

suleimanelkhoury avatar Sep 04 '25 14:09 suleimanelkhoury

Has someone found a solution for this?

@jdenquin when on the UI I navigate to subscription details, even when reloading the "current usage" tab (within the subscription's Usage tab), the total events remain as zero or not updated. I think the refresh button calls the GraphQL `usageForSubscriptionUsage...do that refreshes or is it supposed to refresh the cache?

If hit the /api/v1/customers/{external_customer_id/current_usage directly, i get the same behavior. I have seen the events change, from zero to X, but they remain X even after correctly ingesting more events. Any ideas?

tomfloresa avatar Nov 15 '25 20:11 tomfloresa

@tomfloresa you may face a cache issue, when you ingest an event, it will invalidate the cache, so when you query current_usage again (from UI or API) it will rebuild the cache.

You can try to reset you whole cache by running this command in a rails console

Rails.cache.clear

jdenquin avatar Nov 17 '25 11:11 jdenquin