Open-source project
getzep/graphiti avatar
getzep/graphiti

Graphiti: A Temporal Knowledge Graph Framework for AI Agents

Build Real-Time Knowledge Graphs for AI Agents

31,078 stars3,164 forksPythonApache-2.0

At a glance

What is it?
Graphiti builds context graphs where facts carry validity windows and every derived claim traces back to an episode. It is a Python framework for teams that need history, not just similarity search, and it expects you to run your own graph database.
Who is it for?
Adopt Graphiti if you need facts with validity windows and provenance back to raw episodes, and you are willing to operate Neo4j or FalkorDB yourself. Do not adopt it if you want managed user, thread and message storage: the README puts that on Zep's side of the table.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 8 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 22, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The problem Graphiti solves: facts that change, and the history you lose when they do

Most retrieval stacks treat a document chunk as a static unit. When a customer changes address, or a policy is superseded, the old chunk either lingers in the index or gets overwritten. Neither outcome answers the question "what did we believe in March?"

Graphiti's answer is the context graph. The README describes it as a temporal graph of entities, relationships and facts, where each fact has a validity window: when it became true and when it was superseded. The README's own example is a fact like "Kendra loves Adidas shoes (as of March 2026)." Old facts are invalidated rather than deleted, so historical queries remain possible without recomputing the whole graph.

The audience is narrow but real: engineers building agents that operate on data which keeps moving. Support copilots reading ticket streams, assistants tracking account state, anything where the correct answer depends on when you asked. If your corpus is frozen and your questions are semantic lookups, the temporal machinery is overhead you will pay for and never use.

How Graphiti works: episodes in, entities and edges out

The README lays out four components. Entities are nodes with summaries that evolve. Facts or relationships are edges, stored as triplets with temporal validity windows. Episodes are the raw ingested data, and the README calls them the ground truth stream: every derived fact traces back to one. Custom types are developer-defined entity and edge types expressed as Pydantic models, which the README describes as support for both prescribed and learned ontology.

The data flow follows from that. You submit an episode, the framework extracts entities and relationships from it, and those land in the graph as nodes and edges. Because episodes are retained, the graph is not the only copy of the input. That is what makes provenance possible, and it is also why storage grows with your ingestion volume rather than with the size of the extracted graph.

Retrieval is hybrid. The README lists semantic search, keyword search and graph traversal as the three modes, combined rather than chosen between. The repository layout backs this up: graphiti_core/ holds the library, server/ holds a FastAPI service, and mcp_server/ exposes an MCP interface. There is also a signatures/ directory and a spec/, plus OTEL_TRACING.md at the top level for OpenTelemetry wiring.

Installing graphiti-core and adding your first episode

The package name on PyPI is graphiti-core, not graphiti. That mismatch trips people up, and the pyproject.toml confirms it: name = "graphiti-core", version 0.30.2, Apache-2.0, requiring Python >=3.10,<4.

The base install pulls in pydantic, neo4j, openai, tenacity, numpy, python-dotenv and posthog. Neo4j is the default backend, so the base install is not backend-neutral. Provider and database support sit in optional extras declared in pyproject.toml: anthropic, groq, google-genai, falkordb, falkordblite, voyageai, gliner2, sentence-transformers, neo4j-opensearch, neptune, tracing, and a kuzu extra that carries an explicit deprecation note.

bash
pip install graphiti-core

Before any code runs, the .env.example file shows the variables the project expects. Copy it and fill in the values. Note that the example leaves every value blank, including OPENAI_API_KEY and the Neo4j connection block.

bash
cp .env.example .env

Neo4j connection settings are NEO4J_URI, NEO4J_PORT, NEO4J_USER and NEO4J_PASSWORD. FalkorDB has its own parallel block: FALKORDB_URI, FALKORDB_PORT, FALKORDB_USER, FALKORDB_PASSWORD. The same file also lists USE_PARALLEL_RUNTIME, SEMAPHORE_LIMIT, MAX_REFLEXION_ITERATIONS and ANTHROPIC_API_KEY.

If you would rather not assemble the pieces by hand, docker-compose.yml defines a graph service built from the repository Dockerfile, listening on port 8000 with a healthcheck against /healthcheck, and a neo4j service on image neo4j:5.26.2 exposing 7474 for HTTP and 7687 for Bolt. The graph service reads OPENAI_API_KEY, NEO4J_URI, NEO4J_USER, NEO4J_PASSWORD, PORT and db_backend from the environment, and waits on Neo4j's healthcheck before starting.

bash
docker compose up

The compose file also defines a falkordb profile with a falkordb service on port 6379 and a graph-falkordb service on port 8001 mapped to container port 8000, so the two backends do not collide on the host. The examples/ directory is where the project points for runnable code: quickstart, langgraph-agent, ecommerce, podcast, wizard_of_oz, azure-openai, gliner2, opentelemetry and data.

Where Graphiti stops and you start

The README's own comparison table is the clearest statement of the boundary. On the Graphiti side: build and query individual context graphs, bring your own third-party graph database, build your own user and conversation management, custom implementation for retrieval, build your own developer tools, self-managed, self-hosted only.

Read that list again as a work estimate. Users, threads, message storage, a dashboard, API logs, SDKs beyond Python: none of that ships here. If your product needs per-user isolation with governance, the README points at Zep, which it describes as managing context graphs at scale on a proprietary Context Graph Engine.

The retrieval row deserves attention too. The README says Zep offers pre-configured retrieval with sub-200ms performance at scale, and that Graphiti performance depends on your setup. That is the project telling you latency is your problem, not its promise. Nothing in the README gives a Graphiti latency figure, and you should not assume one.

Two more constraints sit in the packaging. The falkordblite extra is gated on Python 3.12 or newer and pins redis<9, with a comment explaining that redis-py 8.x breaks falkordblite's embedded server startup. The kuzu extra carries a comment stating the upstream Kuzu project is unmaintained and the extra will be removed in a future release. Choosing Kuzu today means choosing a backend the project has already flagged for removal.

Graphiti compared with mem0, and what the comparison actually turns on

People search for Graphiti versus mem0, and the difference is structural rather than a matter of features. Mem0-style memory layers typically store extracted memories as flat records attached to a user or session, and retrieval is a similarity lookup over those records. The record is the unit.

In Graphiti the unit is the triplet, and the triplet carries a validity window. Facts connect to other facts through shared entities, so a query can traverse from one entity to related ones rather than stopping at the nearest vector. The README frames this as the contrast with traditional RAG: batch processing and static summarization on one side, incremental updates and historical queries without full recomputation on the other.

That buys you questions a flat memory store answers poorly. What was this customer's plan before the upgrade? Which policy applied on the date of the incident? It costs you a graph database, a schema you have to think about, and ingestion that runs entity and relationship extraction on every episode. Flat memory is cheaper to operate and simpler to reason about. If your questions are "what is similar to this?" rather than "what was true then?", the graph is not earning its keep.

Maintenance, licensing and upgrade cost

The repository is not archived, and the last push was on 2026-09-10. Recent releases are close together: v0.30.2 on 2026-09-08 covering FalkorDB updates, v0.30.0 on 2026-09-01 with a Neo4j custom database fix and search fixes, and mcp-v1.1.0 on 2026-09-01 with the same Neo4j custom database fix. The MCP server is versioned separately from the core library, so an upgrade plan needs to track two version lines rather than one.

Licensing is Apache-2.0, declared both in pyproject.toml and as the repository LICENSE file. That is a permissive licence, but the README does not describe what it means for your distribution model, and I am not going to guess. Read the LICENSE file and the Zep-CLA.md at the top level if contribution terms matter to your organisation.

Upgrade cost is driven by the optional extras. Each backend and each model provider is a separate dependency group with its own version pins, and the pins move: the falkordb extra is constrained to >=1.1.2,<2.0.0, and the falkordblite extra carries a redis<9 pin for a specific startup failure. If you depend on a backend whose extra is deprecated, treat the next major version as a migration, not a patch. The presence of py.typed and a MyPy check workflow means type surfaces are part of the contract, which helps, but it does not make a backend swap free.

Editorial conclusion

Adopt Graphiti if you need facts with validity windows and provenance back to raw episodes, and you are willing to operate Neo4j or FalkorDB yourself. Do not adopt it if you want managed user, thread and message storage: the README puts that on Zep's side of the table. Before committing, verify that your chosen backend is one of the supported ones in pyproject.toml, and check whether the Kuzu extra's deprecation notice affects you, since that extra is slated for removal.

Frequently asked questions

How does Graphiti work?

You submit episodes, the raw source data, and Graphiti extracts entities and relationships from them into a graph where each fact carries a validity window. Retrieval combines semantic search, keyword search and graph traversal, and every derived fact traces back to the episode that produced it.

How do I install Graphiti?

The package name on PyPI is graphiti-core, so the install command is pip install graphiti-core. Neo4j is the default backend and comes with the base install; other backends and model providers are optional extras declared in pyproject.toml, and connection settings go in a .env file copied from .env.example.

How do I use Graphiti?

The repository ships runnable examples under examples/, including quickstart, langgraph-agent, ecommerce, podcast and wizard_of_oz. The README also points to docker-compose.yml, which starts a graph service on port 8000 alongside Neo4j on 7474 and 7687.

What are the top alternatives to Graphiti?

The README positions Zep as the managed counterpart: it handles user and conversation management, ships a dashboard and SDKs for Python, TypeScript and Go, and runs on a proprietary Context Graph Engine instead of a third-party graph database. Zep is fully managed or in your cloud, while Graphiti is self-hosted only.

Is Graphiti spelled graphiti or graffiti?

The project is named Graphiti, from graph, and the repository is getzep/graphiti with the package published as graphiti-core. Graffiti, the art form, is unrelated.

Official sources

  1. getzep/graphiti on GitHub
  2. License: Apache-2.0
  3. Project website
  4. README
  5. Releases
For maintainers

Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/getzep-graphiti.svg)](https://hysenlabs.com/projects/getzep-graphiti)
Community notes

Community notes