# How to update traces, observations, and scores?

Langfuse treats [traces and observations](/content/docs/observability/data-model/index.html) as **immutable**. Once ingested, they are final and cannot be reliably updated.

If you want to enrich traces or observations after they were ingested with evaluations or annotations, use [scores](/content/docs/evaluation/evaluation-methods/custom-scores/index.html). Scores can be added to traces, observations, sessions, and dataset runs at any time.

## [Traces and observations are immutable](/content/faq/all/tracing-data-updates#traces-and-observations/index.html)

Do not attempt to update a trace or observation after ingestion by re-sending an event with the same `id`.

In Langfuse v4, ingested data is **not deduplicated on the read path**, and the underlying storage does **not** guarantee consistency (not even eventual consistency) across records that share an `id`. Re-inserting therefore creates **duplicate records** rather than replacing the original. Duplicates inflate metrics (for example, `sum(totalCost)` in the Metrics API counts every version) and cause inconsistent results in dashboards, filtering, and exports.

This immutability applies to data that has already been ingested. Building up a trace over the course of a request — for example, updating a span with its output before the trace is flushed by the SDK — is normal, supported usage. The constraint only concerns re-ingesting data that Langfuse has already persisted.

If you need to correct or re-process data, the recommended approach is to add the corrected information as [scores](/content/docs/evaluation/evaluation-methods/custom-scores/index.html) rather than mutating the original record.

## [Enriching data after ingestion](/content/faq/all/tracing-data-updates#enriching-data/index.html)

There are two supported ways to add information to existing traces and observations without re-ingesting them:

**Via scores**

Use [scores](/content/docs/evaluation/evaluation-methods/custom-scores/index.html) to attach evaluations, annotations, or other metadata to traces, observations, sessions, and dataset runs at any time. This is the recommended way to enrich data after it has been ingested.

**Via the Langfuse UI**

UI-based updates — bookmarks and [publishing](/content/docs/observability/features/url/index.html) — can be applied to traces and scores at any time. [Tags](/content/docs/observability/features/tags/index.html) are set at creation and follow the immutable data model, so they can't be edited in the UI afterward.

## [Updating scores](/content/faq/all/tracing-data-updates#updating-scores/index.html)

Unlike traces and observations, scores can be overwritten. A score is identified by three fields: its `id`, its `name`, and its `timestamp` at date granularity (`toDate(timestamp)`). A re-ingested score overwrites the existing one only when **all three match**. If any of them differs, you get a **separate** score, not an update.

This is easy to trip over: sending a score with the same `id` but a different `name` — or a `timestamp` that falls on a different calendar date — creates a duplicate record instead of overwriting the original. To reliably overwrite a score, always send the same `id` (a stable idempotency key such as `trace_id-score_name`), `name`, and `timestamp`, and include the full score payload rather than only the changed fields.

**Deprecated:** For up to 30 days after a score is created, Langfuse may merge a re-ingested score that shares the same `id` into the existing record, backfilling any fields you leave unset. This partial-update behavior is deprecated and will be removed in a future version — do not rely on it. Always send the complete score with a matching `id`, `name`, and `timestamp`.

See [Scores via SDK/API](/content/docs/evaluation/evaluation-methods/scores-via-sdk#preventing-duplicate-scores/index.html) for details.

* * *

Was this page helpful?

Good

Bad

### On this page

[How to update traces, observations, and scores?](/content/faq/all/tracing-data-updates#how-to-update-traces-observations-and-scores/index.html) [Traces and observations are immutable](/content/faq/all/tracing-data-updates#traces-and-observations/index.html) [Enriching data after ingestion](/content/faq/all/tracing-data-updates#enriching-data/index.html) [Updating scores](/content/faq/all/tracing-data-updates#updating-scores/index.html)
