
GraphRAG (Graph-based Retrieval-Augmented Generation) is a RAG architecture that retrieves connected entities and relationships from a knowledge graph, instead of or alongside chunks ranked by vector similarity. It builds a knowledge graph from unstructured text so an LLM can reason across an entire private dataset rather than pattern-matching isolated passages.
The term originates from Microsoft Research, where Edge et al. formally introduced the approach in 2024, describing it as a way to move "from local to global" answering both narrow, specific questions and broad, corpus-wide questions using the same underlying graph.
Traditional RAG treats every piece of knowledge as an independent chunk. A query gets embedded, the closest-matching chunks are retrieved, and those are handed to the LLM as context. This works when the answer lives in one passage, but it has no concept of how facts across chunks relate ask it to trace "how is Vendor A linked to Client B through a shared subsidiary?" and it retrieves chunks that merely mention those entities, not the relationship between them.
GraphRAG changes the unit of retrieval: instead of chunks, it retrieves entities and the relationships connecting them, pulled from a knowledge graph built during indexing. Rather than asking "what text looks similar to this question," it asks "which entities does this question touch, and what's connected to them" letting it follow a chain of relationships across multiple documents to construct an answer no single chunk could supply alone.
GraphRAG was introduced by Microsoft Research in the 2024 paper "From Local to Global: A Graph RAG Approach to Query-Focused Summarization" authored by Darren Edge and colleagues. The paper starts from a specific gap in standard RAG: it works for retrieval-style questions but fails on global, sensemaking questions directed at an entire corpus - such as "what are the main themes in this dataset?" because that's fundamentally a query-focused summarization task, not a lookup task, and prior summarization techniques don't scale to the volume of text a typical RAG system indexes.
Their proposed approach uses an LLM to build a graph index in two stages: first deriving an entity knowledge graph from the source documents, then pregenerating community summaries for all groups of closely related entities. At query time, each relevant community summary is used to generate a partial response, and the partial responses are combined into a final answer.
Enterprise knowledge rarely lives in one place. A single business question "which of our clients also have exposure to a vendor we just flagged for compliance issues?" might require pulling threads from contracts, CRM notes, compliance filings, and internal memos, none of which mention each other directly. Vector-only RAG was never designed to connect information across sources like this; it was designed to find the single most relevant passage.
As enterprises push LLMs toward more complex, cross-functional questions, that gap becomes the main bottleneck - not model quality, but retrieval structure. GraphRAG matters because it addresses that structural gap directly, by making relationships between facts a first-class part of what gets retrieved.
Vector-only RAG ranks and retrieves chunks based on embedding similarity to the query. That approach breaks down in a few predictable ways
No relationship awareness - Similarity search can tell you that two chunks are semantically close, but it has no mechanism for representing that Entity A reports to Entity B, or that Company X acquired Company Y. Those relationships simply aren't encoded anywhere the retriever can use.
Answers scattered across documents get missed - If the full answer requires combining a fact from document 1 with a fact from document 12, vector RAG has to get lucky that both happen to rank in the top-k results for the same query.
No way to answer "about the whole dataset" questions - Vector RAG returns a fixed number of top-matching chunks it has no representation of the corpus as a whole, so it can't meaningfully answer questions like "what are the recurring risks across all our vendor contracts?"
Poor explainability - A retrieved chunk being "similar" to a query doesn't tell you why it's relevant in a business sense - there's no traceable path from question to entity to answer.
GraphRAG addresses each of these by building a persistent structure the knowledge graph that captures relationships during indexing, so they're available at query time instead of being re-inferred (or missed) on the fly.
Many real enterprise questions aren't single-fact lookups they require chaining several facts together, often from different documents, to reach an answer. This is called multi-hop reasoning: "find the vendor," then "find which of that vendor's subsidiaries we also contract with," then "check if that subsidiary is on a restricted list." Each hop depends on the result of the previous one.
Vector RAG has no native way to do this it can only retrieve chunks in relation to the original query, not in relation to intermediate facts it has already found. GraphRAG solves this naturally because the knowledge graph already encodes entities and their relationships as traversable connections. A local search can start at one entity node, follow a relationship edge to a neighboring entity, and follow another edge from there effectively walking the chain the question requires, rather than hoping a single similarity search surfaces everything at once.
Not every question has a discrete, findable answer sitting in one place some questions ask for a synthesis across an entire dataset. "What are the main complaints in our last 1,000 support tickets?" or "What themes come up most across this year's board meeting notes?" are not retrieval questions in the traditional sense; they're query-focused summarization (QFS) tasks, where the "answer" has to be constructed by aggregating patterns across the whole corpus.
Vector RAG isn't built for this it returns a limited set of top-ranked chunks, which can only ever represent a fraction of the corpus, so any summary built from them is inherently partial. GraphRAG handles this through its global search mode: because community summaries are pregenerated for clusters of related entities during indexing, answering a corpus-wide question means scanning those summaries, generating partial answers from each, and combining the strongest ones - giving a genuinely comprehensive answer instead of a best-effort one based on a handful of retrieved chunks.
It helps to stop thinking of GraphRAG as "RAG with extra steps" and instead think of it as building a map before you ever let anyone ask for directions. A vector index answers "what sounds like this question?" A graph answers "what's connected to what, and how?" Those are genuinely different questions, and GraphRAG is built around answering the second one.
The system runs in two phases that happen at completely different times: indexing, which is the slow, expensive, one-time (or periodic) work of building the map, and querying, which is the fast, cheap, per-question work of reading it.

Picture this for a support team handling incident reports. Here's what happens before a single user question gets asked:
Source material goes in as-is. Tickets, postmortems, runbooks, Slack exports no special formatting required, similar to any RAG pipeline.
This is what actually distinguishes GraphRAG. Instead of just chunking and embedding, an LLM identifies named entities a customer, a service, an incident and the relationships connecting them. From one incident report, extraction might surface: Incident-4471 → caused_by → Payment-Service-Outage, Payment-Service-Outage → depends_on → Auth-Service. Individually these are small facts; the value shows up once you have thousands sitting in the same structure.
One easy-to-underestimate detail: entity resolution. The same service gets referred to inconsistently "Auth Service," "authentication service,"the auth microservice" and naive extraction creates three separate nodes for one entity. Production pipelines reconcile these variants through embedding similarity and LLM-assisted disambiguation, or the graph turns into a mess of near-duplicates.
usually in a database like Neo4j, or an in-memory format for smaller projects. At this point it's technically queryable but this alone doesn't solve the "big picture" problem.
The graph gets clustered and pre-summarized. This is the step most explanations skip, and it's arguably the most important one. The graph runs through a community-detection algorithm Microsoft's implementation uses the Leiden algorithm grouping densely interconnected nodes into hierarchical clusters. An LLM then writes a summary for each: "This cluster covers repeated auth-service outages linked to three downstream payment incidents over Q2."

Once the graph and summaries exist, the expensive work is done — query time just reads what was drawn in advance. Which part it reads depends on the shape of the question.
when the question points at something specific. "What's caused Incident-4471 in the past?" names a specific entity, so the system finds that node and walks outward one hop to Payment-Service-Outage, another to Auth-Service retrieving a small, explicit subgraph rather than a paragraph of prose. This is the mode that behaves most like traditional RAG; if the dataset were structured cleanly enough, vector search could answer this almost as well. The real difference is precision: vector search finds text that resembles the answer, local graph search finds the entity itself and its actual named connections.
when the question has no single home. "What's been driving most of our incidents this quarter?" has no single node to anchor on the answer is scattered across hundreds of records. This is where local search and naive vector RAG both fail, since vector RAG can only retrieve a handful of "similar" chunks with no way to know what it's missing. Instead, the system pulls in pre-written summaries for relevant clusters say, "Auth-Service reliability" and "third-party payment API" drafts a partial answer from each in isolation, then merges them, reconciling overlap and surfacing what's actually recurring.
This two-step process exists partly because of token budget: a large graph can produce far more summaries than fit in one context window, so generating partial answers per-cluster and merging afterward lets the system draw on the full dataset without holding it all in memory at once.
local and global search aren't separate features bolted on they're two ways of spending the same upfront investment. Local search cashes in on the graph's explicit relationships; global search cashes in on the summarization work already done during indexing. That's the honest reason GraphRAG beats vector RAG on broad questions specifically, not across the board vector RAG never did that upfront summarization, so it's reconstructing an answer from raw fragments under a token limit at query time. GraphRAG isn't smarter in the moment it just isn't starting from scratch.
LazyGraphRAG defers graph construction until query time instead of running extraction and summarization over the entire corpus upfront, building out only the parts of the graph relevant to the question asked. This makes indexing much cheaper closer to standard vector RAG and retains most of the benefit for local queries, though it's less suited to broad summarization since it skips pregenerated community summaries. It's the right fit when cost, not capability, was the main obstacle.
Choosing between GraphRAG and vector RAG isn't about picking a "better" technology -it's about matching retrieval structure to the shape of your questions. The table below lays out where they diverge on the factors that actually affect cost, accuracy, and maintenance.
Most GraphRAG write-ups treat trade-offs as a footnote. In production, these limitations matter as much as the benefits they decide whether GraphRAG quietly underperforms or genuinely earns its cost.
The knowledge graph is never more reliable than the LLM that built it every entity and connection traces back to a single extraction pass over raw text, and that pass is far from perfect. Weaker models or messy source documents produce graphs with gaps, leaving "islands" of entities richly connected to each other but disconnected from the rest of the corpus.
This failure is invisible nothing throws an error. A multi-hop question that should have an answer just quietly comes up short, because the link existed in the source text but never made it into the graph.
People and organizations rarely get referred to the same way twice "Jon," "Jon Márquez," "J. Márquez" are obviously one person to a human reader, but three separate nodes to most GraphRAG pipelines. This remains one of the field's genuinely unsolved problems at scale.
When one entity splits across multiple nodes, each holds part of the picture, with no built-in way to know they should merge. The result isn't a dramatic failure it's an answer that's technically correct but quietly incomplete.
Every chunk needs at least one LLM call for extraction, then another round to summarize clusters a real cost difference from vector RAG, where you embed a chunk once and move on. It doesn't stop after the first index either: every time documents change, part of that pipeline has to re-run to keep the graph accurate. This is exactly the pain LazyGraphRAG was built to soften.
Vector RAG's classic failure is missing something relevant; GraphRAG's is the opposite pulling in too much. Anchoring on a heavily-connected node can drag in a sprawling web of loosely related context, which the LLM then has to sift through, diluting the final answer instead of improving it. More connected doesn't automatically mean more relevant.
GraphRAG rarely fails loudly. A stale index, a botched extraction, an unresolved duplicate none of these throw a warning; they just make the answer a little worse in ways that are easy to miss. That's why ongoing quality monitoring matters more here than with simpler RAG setups, where a bad retrieval usually shows up as an obviously empty or off-topic result.
You don't have to build a GraphRAG pipeline from scratch a growing ecosystem of open-source libraries, graph databases, and orchestration frameworks handles most of the heavy lifting: entity extraction, community detection, graph storage, and query routing.
The reference implementation released alongside the original paper, and the most complete out-of-the-box option entity extraction, Leiden-based community detection, hierarchical summarization, and both local and global search. It's Python-based and designed to run as an end-to-end system rather than assembled building blocks.
That completeness is also the trade-off: heavier indexing, more LLM calls, more moving parts to monitor. Teams wanting the research-grade approach tend to start here; teams optimizing for cost often look at LazyGraphRAG instead.
The most widely adopted graph database for production GraphRAG, since it's built natively around nodes and relationships rather than rows and tables. It doesn't force an either/or between vector and graph retrieval Neo4j supports combining vector search, full-text search, and graph traversal in a single query, with native integrations for LangChain and LlamaIndex.
Neither is a GraphRAG implementation on its own they're the orchestration layer most teams use to wire one together, connecting the LLM doing extraction, the graph or vector store, and the retrieval logic. LlamaIndex leans toward retrieval-focused abstractions quick to stand up; LangChain leans toward general-purpose chaining and agent logic, suiting teams that want GraphRAG as one component in a larger workflow.
A wave of research projects has emerged to address GraphRAG's cost and complexity. LightRAG trims down the heavier indexing machinery of the original design; HippoRAG draws on how human long-term memory is organized to retrieve information more efficiently over long time horizons. Both are less battle-tested than Microsoft GraphRAG or a Neo4j-based build, but worth watching if your priority is cutting indexing cost or latency rather than replicating the full original pipeline.
GraphRAG earns its keep in domains where knowledge is inherently relational, questions span many documents, or answers need to be explainable, not just plausible.
Large organizations accumulate knowledge in fragments wikis, Slack threads, memos with no consistent structure tying them together. "Who owns the payments integration and what teams depend on it?" isn't a lookup; it's a relationship question spanning multiple sources at once.
GraphRAG can represent "Team A owns Service X" and "Service X is a dependency for Team B" as connected nodes, then traverse that chain to an answer no single document fully contains vector search would need one document mentioning all the facts together, which rarely happens.
Compliance work is fundamentally about tracing relationships which entities connect to which contracts, which clauses reference which regulations. A question like "which vendor contracts reference a regulation we're now non-compliant with" requires connecting facts across hundreds of documents, not one passage.
Explainability matters as much as retrieval here teams need the actual chain of entities behind a conclusion, not just a similarity score, so it can be verified if challenged.
Fraud rarely shows up in one document it shows up as relationships that look unremarkable alone but suspicious in combination: shared addresses across shell companies, one owner under different names. This is a graph problem by nature, which is why graph databases predate GraphRAG in fraud detection.
Layering an LLM on top adds reasoning that pure graph analytics doesn't investigators can ask natural-language questions instead of hand-writing a graph query for every hypothesis.
Support teams often need to summarize patterns across thousands of interactions, not find one ticket "what's driving churn this quarter" is a summarization question. Vector RAG only returns a handful of top-matching tickets, a fraction of the real picture.
GraphRAG's global search was built for this: pregenerated community summaries let it synthesize across the whole corpus rather than gambling that a small sample represents it.
Building a GraphRAG system isn't one decision it's a series of smaller ones that compound. Get the graph database, extraction pipeline, and search design right, and the system earns its complexity. Get any one wrong, and you've paid GraphRAG's cost without its benefit.
Where the graph lives depends mostly on scale. For prototypes or small datasets, an in-memory library like NetworkX is often enough it avoids new infrastructure and lets you validate whether GraphRAG actually improves your answers before committing further. For production, a dedicated graph database like Neo4j makes more sense, since it's built natively around nodes and relationships and scales with the corpus.
This step determines whether your graph is useful or just expensive. Extraction means prompting an LLM to pull entities and their relationships "acquired," "depends on," "reports to" from each chunk. A weak prompt or underpowered model produces a fragmented graph with disconnected islands, and no retrieval logic can recover a connection that was never captured.
Once the graph exists, you need to decide how queries will actually traverse it driven by the kinds of questions your users ask, not by which mode is easier to implement. Local search anchors on a specific entity and pulls in its direct neighbors; global search scans pregenerated community summaries and combines partial answers into a comprehensive response.
GraphRAG solves what standard RAG can't: connecting facts across documents, not just retrieving the closest-matching passage. Its knowledge graph gives an LLM two ways to answer local search for entity-specific lookups, and global search for corpus-wide sensemaking.
That capability isn't free indexing costs more, and depends heavily on extraction quality, which often goes wrong in quiet, hard-to-detect ways. LazyGraphRAG and the ecosystem around Neo4j, LlamaIndex, and LangChain help, but don't eliminate the trade-off.
The real decision isn't "GraphRAG or vector RAG" it's which questions your system needs to answer. If answers usually live in one document, vector RAG is faster and cheaper. If your highest-value questions require tracing relationships no single document connects, that's the gap GraphRAG closes.