Skip to content

GQL

GQL

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 (Cypher Query Language) 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 (Cypher Query Language) only.

GQL (this guide)GraphQL
StandardISO/IEC 39075 GQLGraphQL
SyntaxMATCH (a)-[:knows]->(b) RETURN …query { persons { 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 (Cypher Query Language) 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)Records in table person
-[k:knows]->Records 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?