mlco2 / mlco2/codecarbon

API emissions are timestamped at send time, not measurement time

Open
#1,312 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
1.9k
Forks
323
Avg merge
1d 12h
Merged PRs (30d)
12

Description

When emissions are uploaded to the API, the timestamp stored server-side is the moment the HTTP payload was built, not the moment the measurement window ended. The measured timestamp is present in the payload and simply never read.

Impact

A user running a tracker with output_methods=["file", "api"] gets two different timestamps for the same measurement: the CSV row is stamped when the measurement was finalised, the API row when the POST was assembled. The two datasets do not line up, so a CSV row cannot be matched to its API row by time, and a dashboard chart and a local CSV chart of the same run do not agree.

The same defect applies to the run record itself, so a run's start time is also the time its creation request was assembled rather than when tracking started.

Reproduction

Run a tracker with both output_methods=["file", "api"] and compare the CSV timestamp column against the API rows for the same run — they do not agree.

Root cause

EmissionsData.timestamp is set when the measurement is finalised, in codecarbon/emissions_tracker.py:1047:

timestamp=datetime.now().strftime("%Y-%m-%dT%H:%M:%S"),

It survives into HTTPOutput._emit, which passes the whole dataclass down (codecarbon/output_methods/http.py:65-68). But ApiClient.add_emission discards carbon_emission["timestamp"] and generates a fresh one (codecarbon/core/api_client.py:192-193):

emission = EmissionCreate(
    timestamp=get_datetime_with_timezone(),

There is a second site with the same problem: ApiClient._create_run stamps the run the same way at codecarbon/core/api_client.py:234-235.

get_datetime_with_timezone() (codecarbon/core/api_client.py:25-28) is arrow.now() — i.e. "now, at payload-build time".

Expected vs actual

  • Expected: the stored timestamp locates the measurement window in time, and matches the CSV row for the same measurement.
  • Actual: it records when the POST was assembled.

Fixing this is also a prerequisite for any client-side batching or retry/spill-buffer work, which would otherwise misdate every replayed measurement by the full outage duration.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with codecarbon/emissions_tracker.py:1047 and follow the data through codecarbon/output_methods/http.py:65-68 into ApiClient.add_emission in codecarbon/core/api_client.py:192-193. Also inspect ApiClient._create_run at lines 234-235 and get_datetime_with_timezone at lines 25-28. Done means API emission and run timestamps reflect the measured or tracking time and match the corresponding CSV records; verify with the existing test suite.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
api, backend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
76/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.