litellm - 💡(How to fix) Fix [Bug]: Request Logs / Live Tail appear several hours behind when LiteLLM stores UTC values in timezone-naive SpendLogs timestamps [2 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
BerriAI/litellm#25234Fetched 2026-04-08 03:02:34
View on GitHub
Comments
2
Participants
2
Timeline
3
Reactions
0
Author
Timeline (top)
commented ×2labeled ×1

Root Cause

Database investigation suggests the root cause is:

  • LiteLLM_SpendLogs.startTime / endTime are stored as timestamp without time zone
  • recent rows are being written with UTC wall-clock values
  • the UI/log query path appears to treat them as local time
  • this makes fresh requests appear several hours “in the future” relative to local filtering/display, so they do not show up yet on the Logs page

Code Example

litellm_settings:
    request_timeout: 600
    set_verbose: False
    json_logs: True
    timezone: "US/Central"

---

litellm_settings:
     timezone: "US/Central"
     json_logs: True

---

select now() as db_now, current_setting('TimeZone') as db_timezone;

---

select column_name, data_type
   from information_schema.columns
   where table_name='LiteLLM_SpendLogs'
   order by ordinal_position;

---

select request_id, "startTime", "endTime", status, model
   from "LiteLLM_SpendLogs"
   order by "startTime" desc
   limit 10;

---

select count(*) as rows_total,
          count(*) filter (where "startTime"::date = date '2026-04-06') as rows_on_0406,
          count(*) filter (where "startTime" > (now() at time zone 'America/Chicago')) as rows_after_local_now,
          count(*) filter (where "startTime" <= (now() at time zone 'America/Chicago')) as rows_at_or_before_local_now,
          count(*) filter (where "startTime" <= (now() at time zone 'UTC')) as rows_at_or_before_utc_now
   from "LiteLLM_SpendLogs";

---

-- Postgres timezone
            db_now             |   db_timezone
-------------------------------+-----------------
 2026-04-06 12:02:03.290727-05 | America/Chicago

-- LiteLLM_SpendLogs timestamp column types
       column_name        |          data_type
--------------------------+-----------------------------
 startTime                | timestamp without time zone
 endTime                  | timestamp without time zone
 completionStartTime      | timestamp without time zone

-- Latest rows in SpendLogs
request_id | startTime               | endTime                 | status  | model
-----------+-------------------------+-------------------------+---------+----------------
...        | 2026-04-06 16:48:42.133 | 2026-04-06 16:48:45.929 | success | chatgpt/gpt-5.4
...        | 2026-04-06 16:48:15.178 | 2026-04-06 16:48:20.988 | success | chatgpt/gpt-5.4
...        | 2026-04-06 16:48:12.823 | 2026-04-06 16:48:14.311 | success | chatgpt/gpt-5.4
...        | 2026-04-06 16:48:04.825 | 2026-04-06 16:48:06.201 | success | chatgpt/gpt-5.4

-- Compare against DB local/UTC time
            db_now             |         db_now_utc         |       db_now_chicago
-------------------------------+----------------------------+----------------------------
 2026-04-06 12:03:13.221272-05 | 2026-04-06 17:03:13.221272 | 2026-04-06 12:03:13.221272

-- Rows appear to be ahead of local time but not ahead of UTC time
 rows_total | rows_on_0406 | rows_after_local_now | rows_at_or_before_local_now | rows_at_or_before_utc_now
------------+--------------+----------------------+-----------------------------+---------------------------
       636  |      4       |          4           |            632              |            636

-- Interpreting stored timestamps as UTC and converting to Central matches real activity time
request_id | startTime               | interpreted_cdt         | status  | model
-----------+-------------------------+-------------------------+---------+----------------
...        | 2026-04-06 16:48:42.133 | 2026-04-06 11:48:42.133 | success | chatgpt/gpt-5.4
...        | 2026-04-06 16:48:15.178 | 2026-04-06 11:48:15.178 | success | chatgpt/gpt-5.4
...        | 2026-04-06 16:48:12.823 | 2026-04-06 11:48:12.823 | success | chatgpt/gpt-5.4
...        | 2026-04-06 16:48:04.825 | 2026-04-06 11:48:04.825 | success | chatgpt/gpt-5.4
RAW_BUFFERClick to expand / collapse

What happened?

The LiteLLM UI Request Logs page appears several hours behind real-time even when Live Tail is enabled.

In my setup, activity that definitely occurred on 2026-04-06 shows up in the Usage dashboard, but the Request Logs page does not show those same recent requests yet. The logs page appears delayed by several hours.

I expected recent requests to appear immediately in Request Logs when Live Tail is enabled.

This looks like a timezone-handling bug in how LiteLLM stores or queries request log timestamps.

Observations:

  • LiteLLM config sets:
    litellm_settings:
      request_timeout: 600
      set_verbose: False
      json_logs: True
      timezone: "US/Central"
  • LiteLLM container also has TZ=US/Central
  • Postgres container uses TZ=America/Chicago
  • Usage dashboard shows activity on 2026-04-06
  • Request Logs / Live Tail does not show the same 2026-04-06 activity in real time

Database investigation suggests the root cause is:

  • LiteLLM_SpendLogs.startTime / endTime are stored as timestamp without time zone
  • recent rows are being written with UTC wall-clock values
  • the UI/log query path appears to treat them as local time
  • this makes fresh requests appear several hours “in the future” relative to local filtering/display, so they do not show up yet on the Logs page

Steps to Reproduce

  1. Run LiteLLM with:

    litellm_settings:
      timezone: "US/Central"
      json_logs: True

    and set container TZ to Central time as well.

  2. Use Postgres with local timezone America/Chicago.

  3. Generate fresh requests through LiteLLM.

  4. Open:

    • Usage page: recent same-day activity appears
    • LogsRequest Logs with Live Tail enabled: recent requests do not appear immediately
  5. Inspect Postgres:

    select now() as db_now, current_setting('TimeZone') as db_timezone;
    select column_name, data_type
    from information_schema.columns
    where table_name='LiteLLM_SpendLogs'
    order by ordinal_position;
    select request_id, "startTime", "endTime", status, model
    from "LiteLLM_SpendLogs"
    order by "startTime" desc
    limit 10;
    select count(*) as rows_total,
           count(*) filter (where "startTime"::date = date '2026-04-06') as rows_on_0406,
           count(*) filter (where "startTime" > (now() at time zone 'America/Chicago')) as rows_after_local_now,
           count(*) filter (where "startTime" <= (now() at time zone 'America/Chicago')) as rows_at_or_before_local_now,
           count(*) filter (where "startTime" <= (now() at time zone 'UTC')) as rows_at_or_before_utc_now
    from "LiteLLM_SpendLogs";
  6. Compare stored values to local time. In my case, rows stored around 2026-04-06 16:48 correspond to roughly 2026-04-06 11:48 Central, which matches the real request time.

Relevant log output

-- Postgres timezone
            db_now             |   db_timezone
-------------------------------+-----------------
 2026-04-06 12:02:03.290727-05 | America/Chicago

-- LiteLLM_SpendLogs timestamp column types
       column_name        |          data_type
--------------------------+-----------------------------
 startTime                | timestamp without time zone
 endTime                  | timestamp without time zone
 completionStartTime      | timestamp without time zone

-- Latest rows in SpendLogs
request_id | startTime               | endTime                 | status  | model
-----------+-------------------------+-------------------------+---------+----------------
...        | 2026-04-06 16:48:42.133 | 2026-04-06 16:48:45.929 | success | chatgpt/gpt-5.4
...        | 2026-04-06 16:48:15.178 | 2026-04-06 16:48:20.988 | success | chatgpt/gpt-5.4
...        | 2026-04-06 16:48:12.823 | 2026-04-06 16:48:14.311 | success | chatgpt/gpt-5.4
...        | 2026-04-06 16:48:04.825 | 2026-04-06 16:48:06.201 | success | chatgpt/gpt-5.4

-- Compare against DB local/UTC time
            db_now             |         db_now_utc         |       db_now_chicago
-------------------------------+----------------------------+----------------------------
 2026-04-06 12:03:13.221272-05 | 2026-04-06 17:03:13.221272 | 2026-04-06 12:03:13.221272

-- Rows appear to be ahead of local time but not ahead of UTC time
 rows_total | rows_on_0406 | rows_after_local_now | rows_at_or_before_local_now | rows_at_or_before_utc_now
------------+--------------+----------------------+-----------------------------+---------------------------
       636  |      4       |          4           |            632              |            636

-- Interpreting stored timestamps as UTC and converting to Central matches real activity time
request_id | startTime               | interpreted_cdt         | status  | model
-----------+-------------------------+-------------------------+---------+----------------
...        | 2026-04-06 16:48:42.133 | 2026-04-06 11:48:42.133 | success | chatgpt/gpt-5.4
...        | 2026-04-06 16:48:15.178 | 2026-04-06 11:48:15.178 | success | chatgpt/gpt-5.4
...        | 2026-04-06 16:48:12.823 | 2026-04-06 11:48:12.823 | success | chatgpt/gpt-5.4
...        | 2026-04-06 16:48:04.825 | 2026-04-06 11:48:04.825 | success | chatgpt/gpt-5.4

What part of LiteLLM is this about?

UI Dashboard

What LiteLLM version are you on ?

v1.82.3

Twitter / LinkedIn details

No response


This may be caused by storing UTC timestamps in timestamp without time zone columns and then filtering/displaying them as local time in the Logs UI. Using timestamptz or consistently normalizing UTC/local conversions in the logs query path may fix it.

extent analysis

TL;DR

  • The issue can likely be resolved by consistently handling timezone conversions for the startTime and endTime columns in the LiteLLM_SpendLogs table, possibly by using timestamptz instead of timestamp without time zone or by adjusting the query logic to correctly interpret and display timestamps in the local timezone.

Guidance

  • Investigate changing the data type of startTime and endTime columns in the LiteLLM_SpendLogs table from timestamp without time zone to timestamptz to properly store timezone information.
  • If altering the table structure is not feasible, adjust the query logic in the Logs UI to interpret the stored UTC timestamps correctly and convert them to the local timezone (US/Central or America/Chicago) for display.
  • Verify that the Postgres database and the LiteLLM application are configured to use the same timezone or handle timezone conversions consistently to avoid discrepancies.
  • Test the changes with the provided steps to reproduce the issue, ensuring that recent requests appear in real-time on the Request Logs page when Live Tail is enabled.

Example

-- Example of altering the table to use timestamptz
ALTER TABLE LiteLLM_SpendLogs
ALTER COLUMN startTime TYPE timestamptz;

ALTER TABLE LiteLLM_SpendLogs
ALTER COLUMN endTime TYPE timestamptz;

Note: This example assumes that altering the table structure is possible and desirable. The actual implementation may vary based on the specific requirements and constraints of the application.

Notes

  • The solution may require adjustments to the database schema, app

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING