Back to top

Quick start

Getting up-and-running on SurrealDB is intended to be quick and easy. All of SurrealDB's functionality for starting a server, and importing and exporting data, is enabled through the command-line tool, which can be run as a binary, or from within Docker. When starting a SurrealDB server, configuration is made by passing in command-line options.

Make sure you’ve installed SurrealDB — it should only take a second!

Start the server

First, start the SurrealDB server. Under macOS or Linux, run the following command from a terminal window:

user@localhost % surreal start --log debug --user root --pass root memory
[2022-07-28 15:50:34] INFO  surrealdb::iam Root authentication is enabled
[2022-07-28 15:50:34] INFO  surrealdb::dbs Database strict mode is disabled
[2022-07-28 15:50:34] INFO  surrealdb::kvs Starting kvs store in memory
[2022-07-28 15:50:34] INFO  surrealdb::kvs Started kvs store in memory
[2022-07-28 15:50:34] INFO  surrealdb::net Starting web server on 0.0.0.0:8000
[2022-07-28 15:50:34] INFO  surrealdb::net Started web server on 0.0.0.0:8000

From Windows, run the following command from a command prompt window:

PS C:\> surreal.exe start --log debug --user toor --pass root memory
[2022-07-28 15:50:34] INFO  surrealdb::iam Root authentication is enabled
[2022-07-28 15:50:34] INFO  surrealdb::dbs Database strict mode is disabled
[2022-07-28 15:50:34] INFO  surrealdb::kvs Starting kvs store in memory
[2022-07-28 15:50:34] INFO  surrealdb::kvs Started kvs store in memory
[2022-07-28 15:50:34] INFO  surrealdb::net Starting web server on 0.0.0.0:8000
[2022-07-28 15:50:34] INFO  surrealdb::net Started web server on 0.0.0.0:8000

Connect to SurrealDB

Now that you have started a server, you can connect in a number of ways. In this quick start guide we will insert and query data using the SurrealQL REST endpoint. This endpoint runs SurrealQL queries which are submitted as a HTTP POST request.

You can use Postman to run queries on SurrealDB. The examples below use cURL on the command-line.
DATA="INFO FOR DB;"
curl --request POST \
	--header "Content-Type: application/json" \
	--user "root:root" \
	--data "${DATA}" \
	http://localhost:8000/sql
[
  {
    "time": "141.334µs",
    "status": "ERR",
    "detail": "You need to specify a namespace and a database to use"
  }
]

Most queries in the database need to have a NAMESPACE and a DATABASE specified, before they can be run. In this quick start guide, as we are authenticating as the root user, we can specify any NAMESPACE and DATABASE that we desire.

DATA="INFO FOR DB;"
curl --request POST \
	--header "Content-Type: application/json" \
	--header "NS: test" \
	--header "DB: test" \
	--user "root:root" \
	--data "${DATA}" \
	http://localhost:8000/sql
[
  {
    "time": "967.458µs",
    "status": "OK",
    "result": [
      {
        "login": {},
        "scope": {},
        "table": {},
        "token": {}
      }
    ]
  }
]

Inserting data

By default, SurrealDB doesn't need to have tables or fields defined before inserting data. Instead the database can be queried in schemaless mode, and tables are created ad hoc. In this guide, we will be running all queries in schemaless mode.

CREATE account SET
	name = 'ACME Inc',
	created_at = time::now()
;
DATA="CREATE account SET
	name = 'ACME Inc',
	created_at = time::now();"
curl -k -L -s --compressed POST \
	--header "Content-Type: application/json" \
	--header "NS: test" \
	--header "DB: test" \
	--user "root:root" \
	--data "${DATA}" \
	http://localhost:8000/sql
[
	{
		"time": "1.32125ms",
		"status": "OK",
		"result": [
			{
				"created_at": "2022-01-11T14:51:34.159492Z",
				"id": "account:c7epitis1s4fkfqb6q5g",
				"name": "ACME Inc"
			}
		]
	}
]

In the response above, we can see that the 'author' record has been created, and a random ID has been generated for this record. In SurrealDB every record can be created and accessed directly by its ID. In the following query, we will create a record, but will use a specific ID.

CREATE author:john SET
	name.first = 'John',
	name.last = 'Adams',
	name.full = string::join(' ', name.first, name.last),
	age = 29,
	admin = true,
	signup_at = time::now()
;
DATA="CREATE author:john SET
	name.first = 'John',
	name.last = 'Adams',
	name.full = string::join(' ', name.first, name.last),
	age = 29,
	admin = true,
	signup_at = time::now();"
curl -k -L -s --compressed POST \
	--header "Content-Type: application/json" \
	--header "NS: test" \
	--header "DB: test" \
	--user "root:root" \
	--data "${DATA}" \
	http://localhost:8000/sql
[
	{
		"time": "876.792µs",
		"status": "OK",
		"result": [
			{
				"admin": true,
				"age": 29.0,
				"id": "author:john",
				"name": {
					"first": "John",
					"full": "John Adams",
					"last": "Adams"
				},
				"signup_at": "2022-01-11T14:52:04.175729Z"
			}
		]
	}
]

Let's now create a blog article record, which links to the author and account tables. In the following example we link to the author record directly by its ID, and we link to the account record with a subquery which searches using the 'name' field.

CREATE article SET
	created_at = time::now(),
	author = author:john,
	title = 'Lorem ipsum dolor',
	text = 'Donec eleifend, nunc vitae commodo accumsan, mauris est fringilla.',
	account = (SELECT id FROM account WHERE name = 'ACME Inc' LIMIT 1)
;
DATA="CREATE article SET
	created_at = time::now(),
	author = author:john,
	title = 'Lorem ipsum dolor',
	text = 'Donec eleifend, nunc vitae commodo accumsan, mauris est fringilla.',
	account = (SELECT id FROM account WHERE name = 'ACME Inc' LIMIT 1);"
curl -k -L -s --compressed POST \
	--header "Content-Type: application/json" \
	--header "NS: test" \
	--header "DB: test" \
	--user "root:root" \
	--data "${DATA}" \
	http://localhost:8000/sql
[
	{
		"time": "1.359ms",
		"status": "OK",
		"result": [
			{
				"account": "account:c7epitis1s4fkfqb6q5g",
				"author": "author:john",
				"created_at": "2022-01-11T14:52:19.939224Z",
				"id": "article:c7epj8qs1s4fkfqb6q60",
				"text": "Donec eleifend, nunc vitae commodo accumsan, mauris est fringilla.",
				"title": "Lorem ipsum dolor"
			}
		]
	}
]

Querying data

The querying functionality in SurrealDB works similarly to a traditional relational SQL database, but with many of the added benefits of a NoSQL database. To retrieve data, we will use a SELECT query.

SELECT * FROM article;
DATA="SELECT * FROM article;"
curl -k -L -s --compressed POST \
	--header "Content-Type: application/json" \
	--header "NS: test" \
	--header "DB: test" \
	--user "root:root" \
	--data "${DATA}" \
	http://localhost:8000/sql
[
	{
		"time": "166.709µs",
		"status": "OK",
		"result": [
			{
				"account": "account:c7epitis1s4fkfqb6q5g",
				"author": "author:john",
				"created_at": "2022-01-11T14:52:19.939224Z",
				"id": "article:c7epj8qs1s4fkfqb6q60",
				"text": "Donec eleifend, nunc vitae commodo accumsan, mauris est fringilla.",
				"title": "Lorem ipsum dolor"
			}
		]
	}
]

In SurrealDB we can retrieve data from multiple different tables or records at once. In the example below we'll retrieve data from both the 'article' and the 'account' table in one query..

SELECT * FROM article, account;
DATA="SELECT * FROM article, account;"
curl -k -L -s --compressed POST \
	--header "Content-Type: application/json" \
	--header "NS: test" \
	--header "DB: test" \
	--user "root:root" \
	--data "${DATA}" \
	http://localhost:8000/sql
[
	{
		"time": "106.25µs",
		"status": "OK",
		"result": [
			{
				"account": "account:c7epitis1s4fkfqb6q5g",
				"author": "author:john",
				"created_at": "2022-01-11T14:52:19.939224Z",
				"id": "article:c7epj8qs1s4fkfqb6q60",
				"text": "Donec eleifend, nunc vitae commodo accumsan, mauris est fringilla.",
				"title": "Lorem ipsum dolor"
			},
			{
				"created_at": "2022-01-11T14:51:34.159492Z",
				"id": "account:c7epitis1s4fkfqb6q5g",
				"name": "ACME Inc"
			}
		]
	}
]

One of the most powerful functions in SurrealDB is the related records and graph connections. Instead of pulling data from multiple tables and merging that data together, SurrealDB allows you to traverse related records efficiently without needing to use JOINs. In this following example, we will fetch the blog article, but are going to filter records based on the field in a remote record, and then pull the remote record data into the final response output.

SELECT * FROM article WHERE author.age < 30 FETCH author, account;
DATA="SELECT * FROM article WHERE author.age < 30 FETCH author, account;"
curl -k -L -s --compressed POST \
	--header "Content-Type: application/json" \
	--header "NS: test" \
	--header "DB: test" \
	--user "root:root" \
	--data "${DATA}" \
	http://localhost:8000/sql
[
	{
		"time": "282.584µs",
		"status": "OK",
		"result": [
			{
				"account": {
					"created_at": "2022-01-11T14:51:34.159492Z",
					"id": "account:c7epitis1s4fkfqb6q5g",
					"name": "ACME Inc"
				},
				"author": {
					"admin": true,
					"age": 29.0,
					"id": "author:john",
					"name": {
						"first": "John",
						"full": "John Adams",
						"last": "Adams"
					},
					"signup_at": "2022-01-11T14:52:04.175729Z"
				},
				"created_at": "2022-01-11T14:52:19.939224Z",
				"id": "article:c7epj8qs1s4fkfqb6q60",
				"text": "Donec eleifend, nunc vitae commodo accumsan, mauris est fringilla.",
				"title": "Lorem ipsum dolor"
			}
		]
	}
]

Next steps

Congratulations, you’re now on your way to database and API simplicity! For the next steps, take a look at some of our in-depth guides to see some of the other advanced functionality that you can use in SurrealDB.