> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cognee.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Time Awareness

> Step-by-step guide to using temporal mode for time-aware queries

A minimal guide to Cognee's temporal mode. Use it when your data contains dates and you want to ask time-scoped questions — before, after, or between two points in time — answered from an event timeline rather than embedding similarity alone.

## Before You Start

* Complete [Quickstart](/getting-started/quickstart) to understand basic operations
* Ensure you have [LLM Providers](/setup-configuration/llm-providers) configured
* Read [Recall](/core-concepts/main-operations/recall) for how querying memory works
* No data is required up front — the script ingests its own dated sample text, but it starts with `cognee.forget(everything=True)`, which wipes all existing Cognee data; run it against a setup you can afford to reset

## Code in Action

```python theme={null}
import asyncio

import cognee
from cognee import SearchType

TEXT = """
In 1998 the project launched. In 2001 version 1.0 shipped. In 2004 the team merged
with another group. In 2010 support for v1 ended.
"""

QUERIES = [
    "What happened before 2000?",
    "What happened after 2004?",
    "Events between 2001 and 2004",
]


async def main():
    await cognee.forget(everything=True)

    # temporal_cognify builds the event timeline alongside the usual graph.
    await cognee.remember(
        TEXT,
        dataset_name="timeline_demo",
        temporal_cognify=True,
        self_improvement=False,
    )

    for query in QUERIES:
        results = await cognee.recall(
            query_text=query,
            query_type=SearchType.TEMPORAL,
            datasets=["timeline_demo"],
            top_k=15,
        )
        print(f"\nQ: {query}")
        print(f"A: {results[0].text}")


if __name__ == "__main__":
    asyncio.run(main())
```

## What Just Happened

### Step 1: Remember Data with Temporal Mode

```python theme={null}
await cognee.forget(everything=True)

# temporal_cognify builds the event timeline alongside the usual graph.
await cognee.remember(
    TEXT,
    dataset_name="timeline_demo",
    temporal_cognify=True,
    self_improvement=False,
)
```

The script starts from a clean state, then ingests `TEXT` into the `timeline_demo` dataset. Because `temporal_cognify=True`, `remember()` extracts events and timestamps and builds the timeline during ingestion, so there is no separate `cognify()` step. This example uses one string treated as a single document; multiple documents, files, or entire datasets are processed the same way.

### Step 2: Ask Time-aware Questions

```python theme={null}
for query in QUERIES:
    results = await cognee.recall(
        query_text=query,
        query_type=SearchType.TEMPORAL,
        datasets=["timeline_demo"],
        top_k=15,
    )
    print(f"\nQ: {query}")
    print(f"A: {results[0].text}")
```

The loop runs the three query shapes temporal mode is built for — a before query, an after query, and one bounded by a pair of dates — using `SearchType.TEMPORAL`, imported from the `cognee` package at the top of the script. Each call is scoped with `datasets=["timeline_demo"]` so it only searches the timeline it just ingested; drop the argument to search every dataset you have access to. The answer for each query is `results[0].text`.

<Tip>
  * If the query has clear dates, the retriever filters events by time and ranks them
  * If no dates are detected, it falls back to event or entity retrieval and still answers
  * Increase `top_k` to inspect more candidate events
</Tip>

## Using the HTTP API

If your server is running, you can run temporal search via the API by setting `search_type` to `"TEMPORAL"`:

```bash theme={null}
curl -X POST "http://localhost:8000/api/v1/search" \
  -H "Content-Type: application/json" \
  ${TOKEN:+-H "Authorization: Bearer $TOKEN"} \
  -d '{
        "search_type": "TEMPORAL",
        "query": "What happened between 2001 and 2004?",
        "top_k": 10
      }'
```

<Note>
  The Python example above is still the easiest way to enable temporal ingestion because it lets you pass `temporal_cognify=True` directly to `remember()`.
</Note>

## Graphiti Mode: Episode-Based Temporal Graph

Cognee also ships a second temporal path built on [Graphiti-core](https://github.com/getzep/graphiti). Instead of extracting events and timestamps from text, it stores each document as a timestamped episode directly in Neo4j. Graphiti automatically tracks entities and how facts evolve over time across episodes. If you want, you can then index those episodes into Cognee's vector store to run standard `SearchType.*` queries alongside Graphiti search.

**When to prefer this mode:**

* You need a complete, immutable episode history
* You want direct access to Graphiti's graph traversal and search API
* Your pipeline requires a Neo4j-backed temporal store

Otherwise, start with native temporal mode — it needs no extra dependencies and works with any supported graph store.

### `temporal_cognify=True` vs. Graphiti mode

Both modes make your memory time-aware, but they work differently and are enabled in different ways:

|                    | Native temporal mode (`temporal_cognify=True`)                                              | Graphiti mode                                                                                                        |
| ------------------ | ------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
| **How to enable**  | Pass `temporal_cognify=True` to `remember()` (or `cognify()`)                               | Call `build_graph_with_temporal_awareness()` from `cognee.tasks.temporal_awareness`; requires the `graphiti` extra   |
| **What it builds** | Extracts events and timestamps from your text and adds them to Cognee's knowledge graph     | Stores each document as a timestamped episode and lets Graphiti derive how entities and facts change over time       |
| **Graph store**    | Any [supported graph store](/setup-configuration/graph-stores) (Ladybug default)            | Neo4j / AuraDB only (hard requirement of graphiti-core)                                                              |
| **How to query**   | `cognee.recall(query_type=SearchType.TEMPORAL, ...)` in the normal pipeline                 | `search_graph_with_temporal_awareness()` (Graphiti's own search), optionally indexed back into Cognee's vector store |
| **Best for**       | Time-scoped questions ("before 1980", "between 2000 and 2006") with no extra infrastructure | Complete, immutable episode history and direct access to Graphiti's traversal/search API                             |

<AccordionGroup>
  <Accordion title="Requirements" defaultOpen>
    <Note>
      Neo4j is a hard requirement of **graphiti-core itself**, not a Cognee design choice. Installing `cognee[graphiti]` binds your temporal store to Neo4j or AuraDB. If you want temporal search without a Neo4j dependency, use Cognee's native `SearchType.TEMPORAL` (see above) — it works with any [supported graph store](/setup-configuration/graph-stores).
    </Note>

    * Running Neo4j instance (v4.4+ or AuraDB)
    * Install the `graphiti` extra: `pip install cognee[graphiti]`
    * Set the following environment variables:

    ```bash theme={null}
    GRAPH_DATABASE_PROVIDER=neo4j
    GRAPH_DATABASE_URL=bolt://localhost:7687
    GRAPH_DATABASE_PASSWORD=your_neo4j_password
    # Neo4j username is fixed to "neo4j" in this integration
    ```
  </Accordion>

  <Accordion title="Build and Query with Graphiti">
    ```python theme={null}
    import asyncio
    import cognee
    from cognee.tasks.temporal_awareness import (
        build_graph_with_temporal_awareness,
        search_graph_with_temporal_awareness,
    )

    async def main():
        # 1. Add your data as usual
        text = "In 1998 the project launched. In 2001 version 1.0 shipped."
        await cognee.add(text, dataset_name="graphiti_demo")

        # 2. Retrieve the Cognee Data objects for the dataset
        all_datasets = await cognee.datasets.list_datasets()
        dataset = next(d for d in all_datasets if d.name == "graphiti_demo")
        data_items = await cognee.datasets.list_data(dataset.id)

        # 3. Build the episode graph in Neo4j
        graphiti = await build_graph_with_temporal_awareness(data_items)

        # 4. Query the graph (closes the connection after search)
        results = await search_graph_with_temporal_awareness(graphiti, "What happened in 1998?")
        print(results)

    asyncio.run(main())
    ```

    <Note>
      `search_graph_with_temporal_awareness` closes the Neo4j connection after returning results. For multiple queries, call `graphiti.search(query)` directly on the returned instance and close with `await graphiti.close()` when finished.
    </Note>
  </Accordion>

  <Accordion title="Index the Episodes">
    After building the episode graph, pull the Neo4j data into Cognee's vector store:

    ```python theme={null}
    from cognee.tasks.temporal_awareness.index_graphiti_objects import (
        index_and_transform_graphiti_nodes_and_edges,
    )

    await index_and_transform_graphiti_nodes_and_edges()
    ```

    <Note>
      This step requires `GRAPH_DATABASE_PROVIDER=neo4j` to be set. It raises a `RuntimeError` if the active graph engine is not Neo4j.
    </Note>
  </Accordion>
</AccordionGroup>

## Full Examples

Additional examples about temporal awareness are available on our [GitHub](https://github.com/topoteretes/cognee/tree/main/examples/guides).

* An advanced script running temporal search over real documents is on our [GitHub](https://github.com/topoteretes/cognee/blob/dev/examples/advanced_guides/temporal_awareness_example/temporal_awareness_example.py). Instead of the inlined four-sentence timeline above, it ingests two bundled biographies as separate documents with `temporal_cognify=True`, then mixes before / after / between range queries with person-centric questions that carry no dates — exercising the entity-retrieval fallback described in the tip above.

<Accordion title="Legacy guide">
  ```python theme={null}
  import asyncio
  import cognee


  async def main():
      text = """
      In 1998 the project launched. In 2001 version 1.0 shipped. In 2004 the team merged
      with another group. In 2010 support for v1 ended.
      """

      await cognee.add(text, dataset_name="timeline_demo")
      await cognee.cognify(datasets=["timeline_demo"], temporal_cognify=True)

      from cognee import SearchType

      # Before / after queries
      await cognee.recall(
          query_type=SearchType.TEMPORAL,
          query_text="What happened before 2000?",
          top_k=10,
      )

      await cognee.recall(
          query_type=SearchType.TEMPORAL,
          query_text="What happened after 2010?",
          top_k=10,
      )

      # Between queries
      await cognee.recall(
          query_type=SearchType.TEMPORAL,
          query_text="Events between 2001 and 2004",
          top_k=10,
      )

      # Scoped descriptions
      await cognee.recall(
          query_type=SearchType.TEMPORAL,
          query_text="Key project milestones between 1998 and 2010",
          top_k=10,
      )

      await cognee.recall(
          query_type=SearchType.TEMPORAL,
          query_text="What happened after 2004?",
          datasets=["timeline_demo"],
          top_k=10,
      )


  if __name__ == "__main__":
      asyncio.run(main())
  ```
</Accordion>

<Columns cols={2}>
  <Card title="Core Concepts Overview" icon="brain" href="/core-concepts/overview">
    Understand how Cognee builds and stores knowledge graphs.
  </Card>

  <Card title="API Reference" icon="code" href="/api-reference/introduction">
    Explore the search endpoint behind temporal queries.
  </Card>
</Columns>
