---
title: How to update traces, observations, and scores?
description: "Langfuse treats traces and observations as immutable. What that means in practice, and how to correct or enrich data after it has been ingested."
tags: [observability]
---

# How to update traces, observations, and scores?

Langfuse treats [traces and observations](/docs/observability/data-model) 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](/docs/evaluation/evaluation-methods/custom-scores). Scores can be added to traces, observations, sessions, and dataset runs at any time.

## Traces and observations are immutable [#traces-and-observations]

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](/docs/evaluation/evaluation-methods/custom-scores) rather than mutating the original record.

## Enriching data after ingestion [#enriching-data]

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

**Via scores**

Use [scores](/docs/evaluation/evaluation-methods/custom-scores) 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](/docs/observability/features/url) — can be applied to traces and scores at any time. [Tags](/docs/observability/features/tags) are set at creation and follow the immutable data model, so they can't be edited in the UI afterward.

## Updating scores [#updating-scores]

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](/docs/evaluation/evaluation-methods/scores-via-sdk#preventing-duplicate-scores) for details.

<!-- agent-instructions -->

---

## Agent Instructions

This page is part of the [Langfuse](https://langfuse.com) documentation, published as plain Markdown for AI agents. Every page is available as Markdown by appending `.md` to its URL, or by sending an `Accept: text/markdown` header. This page: `https://langfuse.com/faq/all/tracing-data-updates.md`.

### Querying these docs

If the answer is not on this page, query the documentation instead of guessing:

- **Semantic search** across all Langfuse docs, returning an answer with the relevant pages and excerpts. Ask a specific, self-contained question:

  ```bash
  curl -sG "https://langfuse.com/api/search-docs" --data-urlencode "query=How do I trace a LangGraph agent?"
  ```

- **Index of every page**: <https://langfuse.com/llms.txt>, with per-section indexes [llms-docs.txt](https://langfuse.com/llms-docs.txt), [llms-integrations.txt](https://langfuse.com/llms-integrations.txt), and [llms-self-hosting.txt](https://langfuse.com/llms-self-hosting.txt).

### Before writing Langfuse code

- **Install the [Langfuse Agent Skill](https://langfuse.com/docs/api-and-data-platform/features/agent-skill).** It encodes Langfuse's own best practices for instrumentation, prompt management, and evaluation, and materially improves results.
- **Read [What does a good trace look like?](https://langfuse.com/docs/observability/best-practices.md)** before instrumenting an application.
- **Verify endpoints, parameters, and response fields** against the [API reference](https://api.reference.langfuse.com) instead of inferring them from code examples.
- **Use the [Langfuse CLI](https://langfuse.com/docs/api-and-data-platform/features/cli)** (`npx langfuse-cli api <resource> <action>`) to read or write traces, prompts, datasets, and scores from the terminal.

Found an error in these docs? Please open an issue at <https://github.com/langfuse/langfuse-docs/issues>.
