---
title: "Do You Need a Graph Database? What BigQuery Graph Going GA Actually Changes"
description: "BigQuery Graph reached GA on 1 September 2026. Before you model anything as a graph, here is the honest test for whether you need one — plus the line in the pricing page that decides whether you can even run GQL."
author: Aleksei Aleinikov
date: 2026-09-02
lang: en
tags: [graph-database, bigquery-graph, gql, property-graph, spanner-graph, knowledge-graph, graph-vs-relational]
canonical: https://www.alekseialeinikov.com/en/blog/topics/data/do-you-need-a-graph-database-2026
source: alekseialeinikov.com
---

# Do You Need a Graph Database? What BigQuery Graph Going GA Actually Changes

Yesterday Google moved BigQuery Graph to general availability, and the announcement leans hard on the word *agentic*: knowledge graphs as the grounding layer for AI agents, auditable agent memory, natural-language chat over your relationships. It is a good launch, and it will generate a wave of posts explaining that graphs are the future of enterprise data.

This is not one of those posts. Before you model anything as nodes and edges, there is a much duller question worth answering: does your problem actually need a graph engine, or does it need three joins and an index? Most teams that reach for a graph database do not need one, and the ones that do usually discover it the same way — a query that cannot be written because they do not know how deep it goes. This is a guide to telling those two situations apart, what GA genuinely changed, and the one line in the pricing documentation that decides whether you can run any of it.

![Do you need a graph database in 2026: variable-length traversal in GQL versus self-joins in SQL, and where BigQuery Graph fits.](https://www.alekseialeinikov.com/blog/graph-database-2026.webp)

## What a Graph Engine Actually Buys You

The standard pitch is that graph databases are for "connected data". That pitch is close to meaningless, because a relational database models connections perfectly well — that is what a foreign key is.

The real difference is narrower and much more useful: **a graph engine lets you traverse to a depth you do not know when you write the query.**

Take a concrete question. An account is flagged for fraud. Which accounts received money from it within one to three transfers?

In SQL, "three" is a structural fact you must bake into the statement. Each hop is another self-join:

```sql
-- Exactly three hops. Not one, not two, not four.
SELECT DISTINCT a3.id AS reached
FROM transfers t1
JOIN transfers t2 ON t2.from_id = t1.to_id
JOIN transfers t3 ON t3.from_id = t2.to_id
JOIN accounts  a3 ON a3.id = t3.to_id
WHERE t1.from_id = 7;
```

Want one to three hops? Union three variants of that query. Want up to six? Write six. Want "however far it goes until the trail runs dry"? Now you need a recursive CTE, and the readability of the thing collapses.

In GQL the depth is a quantifier, and the query barely changes shape:

```sql
GRAPH graph_db.FinGraph
MATCH (src:Account {id: 7})-[e:Transfers]->{1, 3}(dst:Account)
WHERE src != dst
RETURN ARRAY_LENGTH(e) AS hops, dst.id AS dst_account_id
```

The `{1, 3}` is the whole argument for graph databases in one token. Change it to `{1, 6}` and you have not restructured anything. The variable `e` binds to an array of the edges actually traversed, so `ARRAY_LENGTH(e)` tells you how far each result was found.

![Variable-length traversal is the dividing line: SQL needs one self-join per hop and the depth must be known when you write the query, while GQL expresses the same question with a quantifier.](https://www.alekseialeinikov.com/blog/graph-vs-sql-traversal-2026.webp)

So here is the honest test. Look at the questions your business actually asks. If the number of hops is always known and small — customer to order to line item — you are describing a join, and a graph engine will add a modelling layer without adding an answer. If the number of hops is itself unknown, discovered, or unbounded — how did this identity connect to that one, what depends on this component, where did this payment eventually land — that is a traversal, and SQL will keep fighting you.

## The Trap in the Default Path Mode

One detail that deserves attention before you trust any traversal result, because it is a genuine footgun and it is on by default.

GQL has path modes. The default is `WALK`, and `WALK` does not care whether a path visits the same node or crosses the same edge twice. A three-hop pattern under `WALK` will happily return a path where the first and third edges are literally the same transfer, bounced back and forth.

Two modes exist to fix that:

- **`ACYCLIC`** filters out paths that have repeating **nodes**
- **`TRAIL`** filters out paths that have repeating **edges**

The documentation's own example is instructive: on the sample FinGraph, asking for six consecutive transfers with `TRAIL` returns zero paths, because there simply are no six-hop routes through that graph without reusing an edge. Under `WALK`, the same shape would have returned results — all of them artefacts of walking in circles.

There is also a set of path search prefixes worth knowing: `ALL` (the default), `ANY`, `ANY SHORTEST`, and `ANY CHEAPEST`, the last of which sums a `COST` expression on each edge:

```sql
GRAPH graph_db.FinGraph
MATCH ANY CHEAPEST (a:Account)-[t:Transfers COST t.amount]->{1,3}(b:Account)
LET total_cost = sum(t.amount)
RETURN a.id AS a_id, b.id AS b_id, total_cost
```

A path can carry a mode or a search prefix, but not both at the top level. If your first graph query returns suspiciously many results, the path mode is the first thing to check.

## What GA Actually Changed

Now to the launch itself, separating what shipped from what was announced.

**Graphs over tables you already have.** This is the substantive architectural claim and it holds up. You define node and edge tables over existing tables or views with `CREATE PROPERTY GRAPH` — no replication, no pipeline change. Google's documentation states plainly that you are charged once for the storage of the underlying tables regardless of how many graph models are built on top of them. That removes the historical reason graph projects died: standing up a second database and an ETL job to feed it.

**A graph that spans clouds.** The GA post introduces what Google calls a borderless graph Lakehouse — a single property graph whose node and edge tables can point at native BigQuery tables *and* Iceberg tables reached through Databricks Unity Catalog, AWS Glue or Snowflake, traversed in place. If it works as described, that is the most interesting thing in the announcement, because the usual failure mode of an enterprise knowledge graph is that half the entities live somewhere you are not allowed to copy from.

**Standards, not a dialect.** GQL is ISO/IEC 39075:2024, published in April 2024 — a 610-page specification from ISO/IEC JTC 1/SC 32. BigQuery Graph implements an interface compatible with both it and ISO SQL/PGQ. Whether you ever move, learning the pattern syntax is not vendor-specific knowledge.

**Performance claims, treated as claims.** The post states GQL is 2× faster than at preview and undirected traversal 100× faster, "against public benchmarks". No benchmark is named and no methodology is given. That is a vendor number about its own product against its own earlier version — plausible, unverifiable, and not something to put in a design document. Treat the direction as real and the multiplier as marketing until someone independent reproduces it.

**Agentic features, read the small print.** Chat with your graph in natural language, an agent skill for Claude Code, Codex and VS Code via the Data Agent Kit, and a context graph in BigQuery Agent Analytics that stores an agent's decisions as a traversable trace. This last one is genuinely clever — "why did the agent do this?" becomes a graph query. But the post says outright that some of what it describes is GA today and some is in preview or rolling out over the coming weeks, and the authoring half of the agent skill is explicitly "rolling out soon". Do not plan around the ones that have not landed.

## The Line in the Pricing Page

Here is the part that will determine whether any of this is available to you, and it is not in the announcement.

From the BigQuery Graph documentation:

> To run GQL queries, you must have a reservation that uses the Enterprise or Enterprise Plus edition. If you use on-demand pricing, you can call the `GRAPH_EXPAND` function to run SQL queries on your graph.

Read that twice. **GQL — the entire reason to use a graph engine — is gated behind an edition.** If you are on on-demand pricing, which is where a large share of BigQuery workloads start and many stay, you get a function you can call from SQL, not the pattern-matching language. The documentation carries a further warning that the feature may not be available on reservations created with certain editions at all.

![BigQuery Graph sits over existing tables with no ETL, but running GQL requires an Enterprise or Enterprise Plus reservation; on-demand pricing only gets the GRAPH_EXPAND function.](https://www.alekseialeinikov.com/blog/bigquery-graph-architecture-2026.webp)

None of this makes the product worse. It makes the evaluation different: this is a feature for organisations already on capacity-based pricing, not a thing you casually try on a sandbox project on a Friday. Establish which side of that line you are on before you spend a sprint modelling nodes and edges. The same discipline applies here as with any BigQuery commitment, which I went through in more detail in [BigQuery vs Snowflake](https://www.alekseialeinikov.com/en/blog/topics/data/bigquery-vs-snowflake-2026-honest-comparison).

## Analytics or Operations — Two Products, One Language

If you decide a graph is warranted, there is a second fork, and Google has been unusually clear about it.

BigQuery Graph and Spanner Graph share a graph schema and a query language. They do not share a workload.

| | BigQuery Graph | Spanner Graph |
| --- | --- | --- |
| Workload | Offline, batch | Online, real-time |
| Query latency | Seconds to hours | Milliseconds to seconds |
| Query pattern | Global — the whole graph | Local — a neighbourhood |
| Scale | Petabyte, historical | Horizontal, hot data |
| Consistency | Near real-time or batch | Strong, global |

The dividing question is not size, it is whether a user is waiting. Checking a card swipe against a graph of known fraudulent devices has to happen in milliseconds while the transaction is open — that is Spanner Graph. Finding every account within a few degrees of a confirmed fraudster across your entire history is a scan that can take minutes — that is BigQuery Graph.

Because the schema and language are shared, you are not choosing one forever. Google documents moving between them in both directions: forward ETL from Spanner to BigQuery through a Dataflow template, reverse ETL back with `EXPORT DATA`, or federated queries with no copy at all. The pattern their own docs describe is a loop — Spanner serves the real-time decision, BigQuery finds the historical pattern, and the label goes back to Spanner to change the next decision.

![Two graph products, one language: Spanner Graph answers neighbourhood questions in milliseconds while BigQuery Graph answers whole-graph questions in seconds to hours, with data moving both ways.](https://www.alekseialeinikov.com/blog/graph-analytics-vs-operational-2026.webp)

## Graph or Vector? Wrong Question

Every few months a new storage shape is announced as the foundation of AI, and the previous one is implicitly demoted. Vector databases got that treatment last year; graphs are getting it now. Both framings are wrong, because the two answer different shapes of question.

**Vector search finds what is similar.** You have a query, you want the passages that mean roughly the same thing. Similarity is fuzzy, learned, and has no explanation you can show anyone. I went through the mechanics of that in [do you need a vector database](https://www.alekseialeinikov.com/en/blog/topics/data/do-you-need-a-vector-database-postgres-vs-dedicated-2026) and [which embedding model to use](https://www.alekseialeinikov.com/en/blog/topics/ai/which-embedding-model-api-vs-self-hosted-2026).

**Graph traversal finds what is connected.** You have a starting node, you want everything reachable by a defined path. The relationship is explicit, typed, and auditable — you can point at the exact chain of edges that produced the answer.

For grounding an agent, that difference matters more than either camp admits. Vector search gets you into the right region of the corpus; it cannot tell you that this supplier is two hops from that delayed order. Traversal gives you a precise, explainable neighbourhood; it cannot find the right entry point from a vaguely worded question. GraphRAG is simply the observation that you want both — semantic entry, structural expansion.

This is why BigQuery Graph integrates vector and full-text search into the graph surface rather than treating them as a competing product. The interesting systems in 2026 use both in one query, which is exactly what you would expect once you stop treating storage engines as teams.

## The Bottom Line

Ask the depth question first. If your traversals have a known, fixed number of hops, you have a join problem, and a property graph will give you a new vocabulary for a query you could already write. If the depth is unknown or discovered, SQL has been costing you readability for years and a graph engine will pay for itself in the first query.

If the answer is yes, check the edition line before anything else. GQL needs an Enterprise or Enterprise Plus reservation; on-demand gets `GRAPH_EXPAND` and nothing more. That single sentence eliminates the option for some teams entirely, and it is better to learn it now than after the data model review.

Then pick the workload, not the product. Milliseconds with a user waiting is Spanner Graph. Whole-graph analysis measured in minutes is BigQuery Graph. They share a language, so the decision is reversible — which is rare enough to be worth saying out loud.

And when you write your first traversal, set the path mode. The default walks in circles, and it will not tell you.
