Skip to content
Sign In

GQL

GQL

Query SurrealDB graph data with ISO GQL - a Cypher-like graph pattern language over HTTP and RPC.

Available since: v3.2.0

SurrealDB supports ISO/IEC 39075 GQL for graph pattern matching and data modification over your existing tables and RELATE edges. The surface syntax is closer to Cypher-style MATCH … RETURN than to SurrealQL SELECT, but it runs on the same storage model: node labels map to tables, edge types map to relation tables, and properties map to record fields.

Note

From 3.3.0, ISO GQL is enabled by default on POST /gql, the gql RPC method, and MCP - no experimental capability is required. On 3.2.x, enable it with --allow-experimental gql (or SURREAL_CAPS_ALLOW_EXPERIMENTAL=gql). The surface includes read queries (MATCH … RETURN) and data-modifying statements (INSERT, SET, REMOVE, DELETE) - see GQL mutations.

SurrealDB exposes two different graph query languages on separate endpoints. Do not abbreviate GraphQL to gql in product identifiers - the short name gql refers to ISO GQL only.

GQL (this guide)GraphQL
StandardISO/IEC 39075 GQLGraphQL
SyntaxMATCH (a)-[:knows]->(b) RETURN …query { people { name } }
HTTPPOST /gqlPOST /graphql
WebSocket RPCmethod: "gql"method: "graphql"
SetupOn by default from 3.3.0 (experimental gql on 3.2.x)DEFINE CONFIG GRAPHQL
SchemaTables and RELATE edges you already haveAuto-generated GraphQL schema from your database
  • You already think in graph patterns such as (a)-[:knows]->(b), SHORTEST, and ALL SHORTEST, and have yet to learn how to query such paths in SurrealQL.

  • You are migrating a database from Neo4j to SurrealDB and want to test to ensure that existing Cypher queries map to the same output.

  • You want a stable graph query surface aligned with the ISO GQL standard.

For general-purpose schema changes, bulk load, and full SurrealQL expressiveness, keep using SurrealQL and the /sql endpoint. For ISO graph-pattern writes (INSERT, SET, REMOVE, DELETE), see GQL mutations.

SurfaceHow to call
HTTPPOST /gql - raw GQL query in the request body
WebSocket RPC{ "method": "gql", "params": ["<query>", { "var": value }] } - use for typed $variables
Postgres wireSET dialect = 'gql' (or options=-c dialect=gql at connect) on a Postgres client connection
MCPgql tool (when the server exposes MCP)
SurrealQLeval::gql - nested GQL in the caller's transaction (capability-gated)

Session headers match /sql: Surreal-NS, Surreal-DB, and authentication. Responses use the same JSON envelope as /sql (status, result, time).

To experiment in the REPL without curl or POST /gql, wrap a GQL string in eval::gql. The function runs the same engine as the HTTP endpoint and participates in the caller's transaction (including mutations).

eval::gql needs the eval capability that --allow-all does not enable: --allow-eval-query (denied for every subject by default). From 3.3.0 you do not also need --allow-experimental gql (that flag is still required on 3.2.x).

Embedded REPL (surreal sql against memory or a file path - no separate surreal start):

echo 'eval::gql("MATCH (n:person) RETURN n.name AS name ORDER BY name");' | surreal sql --user root --pass secret --allow-eval-query --pretty --hide-welcome

To explore interactively instead, open the same REPL without piping:

surreal sql --user root --pass secret --allow-eval-query

Remote server (surreal start + surreal sql -e ws://…): pass --allow-eval-query on surreal start only. The client REPL does not enable eval at runtime.

surreal start --user root --pass secret --allow-eval-query

Optional bindings use an object as the second argument: eval::gql("… WHERE n.age > $min …", { min: 18 }). Full setup, seed data, and more examples can be found on the Eval functions page.

GQLSurrealDB
(:person)Rows in table person
-[k:knows]->Rows in relation table knows (in / out record IDs)
n.nameField name on the bound record
$minParameter - bind via RPC params object (typed JSON values)

GQL is not lowered to SurrealQL text - it compiles to an internal match plan and runs on the streaming engine. The sample queries page shows SurrealQL that returns the same shape where a close equivalent exists; some patterns (optional match blocks, path selectors) are much more concise in GQL.

  • -- starts a line comment, not an undirected edge.

  • Inequality is <>, not !=.

  • Label conjunction uses & (:person&employee), not :person:employee.

  • Variable-length quantifiers are postfix on the edge: -[e:knows]->{1,3}(b), not *1..3 inside the brackets.

  • No IN list membership operator in this subset.

Design notes, the supported subset, and mutation semantics are documented in the SurrealDB source tree under doc/opengql/ (REFERENCE.md, LOWERING.md). The parser grammar is vendored from the upstream opengql/grammar project; that name refers to the grammar repository, not the ISO standard SurrealDB implements.

Was this page helpful?