How Cognee tracks time
Cognee builds a temporal knowledge graph by default: dates in your data become part of the graph (see How Dates Are Stored). Use this guide when you want to ask time-scoped questions — before, after, or between two points in time — and have them answered from the content dated inside that window rather than by embedding similarity alone.Before You Start
- Complete Quickstart to understand basic operations
- Ensure you have LLM Providers configured
- Read Recall for how querying memory works
- Any built-in graph store works. The default Ladybug/Kuzu store, Neo4j, and the Postgres demo graph answer the time-window lookups with a native query; Turso, Neptune, and Neptune Analytics use a generic fallback that scans the graph and walks each candidate’s neighbourhood, which is slower on large graphs. A community adapter, such as FalkorDB or Memgraph, needs
get_graph_dataandget_neighborhoodfor that fallback, or its ownget_timestamps_in_rangeandget_temporal_anchors - 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
What Just Happened
Step 1: Remember Dated Data
TEXT into the timeline_demo dataset. No ingestion flag is needed: the default remember() pipeline extracts the dates in the text as Timestamp nodes, which SearchType.TEMPORAL reads, 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
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.
How Dates Are Stored
The default pipeline asks the extraction LLM to model every date it finds as aTimestamp node, attached as a leaf to the entity it dates — for example marie_curie --born_at--> 1867. The chunk that mentions the date also links to the Timestamp through its contains edge, just as it does for entities.
- A date covers everything it states and no more:
"In 2001 version 1.0 shipped"becomes2001withprecisionyear, covering all of 2001, so it stays distinguishable from2001-01-01. - A
Timestampnode’s id is derived fromtimestamp_str, so every mention of the same date across chunks and documents shares one node.Timestampnodes are not embedded. - A date without a stated year (“on 27 April”, “later that spring”) is resolved against the last year stated earlier in the same document and handed to the extraction prompt as a hint; the chunk text itself is not changed.
- A date the LLM leaves in a form that cannot be normalized stays an ordinary
Entitynode.
- Reads a time window from the question. An LLM call turns the question into one UTC window, start inclusive and end exclusive. A named year, month, or day covers that whole unit; “before X”, “until X”, “after X”, and “since X” leave one side open (see How boundary words are read).
- Gathers candidates. It runs a hybrid search for four times
top_kcandidates and adds the chunks attached toTimestampnodes inside the window, which similarity search alone tends to miss. - Reranks. Candidates attached to an in-window timestamp — directly, or through an entity that is — move to the front, and the rest follow in similarity order. The list is then cut to
top_k.
- As precise as the question, or more precise → these all rank the same and keep their embedding-similarity order. For “in 2020”, a paragraph dated September 2020 is not pushed below a row dated
2020-09-14. - Coarser than the question → ranked lower, and the wider the timestamp the lower it goes. For “on 18 March 1965”, a chunk dated
1965-03-18comes before one that only says1965. - Open-ended window (“since 2022”, “before 1900”) → no precision preference. Every anchored candidate ranks the same and keeps its similarity order.
How boundary words are read
Whether the named point X is inside the window depends on the word in front of it:
A timestamp matches when its period overlaps the window, so “What changed since 1995?” includes anything dated in 1995, and a period such as
1990/1996 as well.
Relative and vague time expressions
Extraction only creates aTimestamp for a date it can place on a calendar. A phrase such as “when I was young, I loved running” or “when I was at primary 2, I transferred school” still produces its entities and chunk links, but no Timestamp node:
- The content remains fully retrievable through hybrid search, including the fallback inside
SearchType.TEMPORAL. - It is invisible to the time window, so a “before 2005” query will not move it to the front.
Using the HTTP API
If your server is running, you can run temporal search via the API by settingsearch_type to "TEMPORAL":
The
temporal_cognify option is deprecated and will be removed in the next release. remember() and cognify() still accept it, but passing it emits a DeprecationWarning (also logged), the value is ignored, and the default pipeline runs. cognee 1.6.2 was the last release in which temporal_cognify=True built the event graph. Datasets built with it hold Event nodes that current code no longer indexes: SearchType.TEMPORAL ignores them and graph completion no longer searches their names. To rebuild such a dataset, drop its graph and vectors and cognify it again:Full Examples
Additional examples about temporal awareness are available on our GitHub.- An advanced script running temporal search over real documents is on our GitHub. Instead of the inlined four-sentence timeline above, it ingests three bundled documents (two biographies and a news article) and prints the extracted
Timestampnodes with theirprecisionand the*_atedges tying them to entities, including a year-less “April 27” stored as 1986-04-27 (see How Dates Are Stored). It then asks each question with bothSearchType.HYBRID_COMPLETIONandSearchType.TEMPORALside by side; its last question names a date absent from the documents, exercising the plain-hybrid fallback described in Relative and vague time expressions. Like the script above, it starts withcognee.forget(everything=True), and it reads the graph throughget_graph_engine().get_graph_data(), an internal API that may change without notice.