# INFO

The INFO command outputs information about the setup of the SurrealDB system.

The `INFO` command outputs information about the setup of the SurrealDB system. There are a number of different `INFO` commands for retrieving the configuration at the different levels of the database.

**SurrealQL Syntax**

```syntax title="SurrealQL Syntax"
INFO FOR [
	ROOT
	| NS | NAMESPACE
	| DB | DATABASE
	| TABLE @table
	| USER @user [ON @level]
    | INDEX @index ON @table
];
```

The information returned from an `INFO` command is an object containing items that almost always correspond to a matching [DEFINE](/docs/reference/query-language/statements/define/overview.md) statement. For example, the `INFO FOR NS` command returns the information on the access methods, databases and users of a namespace, which are defined with `DEFINE ACCESS`, `DEFINE DATABASE` and `DEFINE USER` statements.

> [!NOTE]
> Before SurrealDB v3.0.0, the output of an `INFO FOR` was only able to be used as a standalone statement and not in a dynamic context, such as inside other queries or as the value of a parameter.

> [!NOTE]
> From SurrealDB 3.2.2, `INFO FOR ROOT`, `INFO FOR NS`, `INFO FOR DB`, and `INFO FOR USER` always show password hashes as `PASSHASH '[REDACTED]'` (including for root). That keeps schema listings from exposing credential material to every role that can run `INFO`. The hash is still stored, while a privileged [export](/docs/reference/cli/surrealdb-cli/commands/export.md) still includes the real `PASSHASH` so backups can restore users. Note that Argon2 hashes remain one-way and salted, so redaction is about who can read the PHC string, not about treating a hash as a plaintext password.

## Example usage

There are a number of different `INFO` commands for retrieving the configuration at the different levels of the database.

## System information

### Root information
The top-level ROOT command returns information regarding:
- The users and namespaces which exists within the SurrealDB system.
- The memory allocated by SurrealDB itself. Note that this may not match what the operating system reports, as it also includes memory consumed by third-party libraries or pre-allocated memory.
- The level of parallelism: This number indicates the number of available hardware threads.

> [!NOTE]
> You must be authenticated as a top-level root user to execute this command.

#### Examples

```surql
INFO FOR ROOT;
```

```surql title="Sample output"
{
	accesses: {},
	namespaces: {
		ns: 'DEFINE NAMESPACE ns'
	},
	nodes: {
		"2d3b720d-f152-4c0d-8a16-26d1474ed3cd": 'NODE 2d3b720d-f152-4c0d-8a16-26d1474ed3cd SEEN 1745463977888 ACTIVE'
	},
	system: {
		available_parallelism: 14,
		cpu_usage: 0.3816290497779846f,
		load_average: [
			1.2734375f,
			1.68310546875f,
			1.9189453125f
		],
		memory_allocated: 13900485,
		memory_usage: 136314880,
		physical_cores: 14,
		threads: 32
	},
	users: {
		root: "DEFINE USER root ON ROOT PASSHASH '[REDACTED]' ROLES OWNER DURATION FOR TOKEN 1h, FOR SESSION NONE"
	}
}
```

### Namespace information

The `NS` or `NAMESPACE` command returns information regarding the users, databases and access methods under the namespace in use.

> [!NOTE]
> You must be authenticated as a top-level root user, or a namespace user to execute this command.

> [!NOTE]
> You must have a NAMESPACE selected before running this command.

#### Examples

```surql
INFO FOR NS;
```

```surql title="Sample output"
{
    accesses: {},
    databases: {
        db: 'DEFINE DATABASE db'
    },
    users: {
        n: "DEFINE USER n ON NAMESPACE ROLES VIEWER DURATION FOR TOKEN 1h, FOR SESSION NONE",
        username: "DEFINE USER username ON NAMESPACE PASSHASH '[REDACTED]' ROLES EDITOR DURATION FOR TOKEN 1m, FOR SESSION 12h"
    }
}
```

### Database information

The `DB` or `DATABASE` command returns information regarding the users, tables, params, models, functions, analyzers and access methods under the database in use.

> [!NOTE]
> You must be authenticated as a top-level root user, a namespace user, or a database user to execute this command.

> [!NOTE]
> You must have a NAMESPACE and a DATABASE selected before running this command.

#### Examples

```surql
INFO FOR DB;
```

```surql title="Sample output"
{
    accesses: {},
    analyzers: {},
    apis: {},
    buckets: {},
    configs: {},
    functions: {},
    models: {},
    params: {},
    tables: {
        person: 'DEFINE TABLE person TYPE ANY SCHEMALESS PERMISSIONS NONE'
    },
    users: {
        db_user: "DEFINE USER db_user ON DATABASE PASSHASH '[REDACTED]' ROLES OWNER DURATION FOR TOKEN 1h, FOR SESSION NONE"
    }
}
```

### Table information

The `TABLE` command returns information regarding the events, fields, tables, and live statement configurations on a specific table.

> [!NOTE]
> You must be authenticated as a top-level root user, a namespace user, or a database user to execute this command.

> [!NOTE]
> You must have a NAMESPACE and a DATABASE selected before running this command.

#### Examples

```surql
INFO FOR TABLE user;
```

```surql title="Sample output"
{
    events: {},
    fields: {
        name: 'DEFINE FIELD name ON user TYPE string PERMISSIONS FULL'
    },
    indexes: {},
    lives: {},
    tables: {}
}
```

### User information

The `USER` command returns information for a user [defined](/docs/reference/query-language/statements/define/user.md) on either the root, namespace, or database level.

> [!NOTE]
> You must be authenticated as a user equal to or greater than the level of the user you are attempting to obtain information for to execute this command.

#### Examples

```surql
INFO FOR USER root ON ROOT;
INFO FOR USER ns_user ON NAMESPACE;
INFO FOR USER db_user ON DATABASE;
```

If a level after `ON` is not specified, the `INFO` command will default to the database level. Thus, the following two commands are equivalent.

```surql
INFO FOR USER db_user ON DATABASE;
INFO FOR USER db_user;
```

```surql title="Sample output"
"DEFINE USER db_user ON DATABASE PASSHASH '[REDACTED]' ROLES OWNER DURATION FOR TOKEN 1h, FOR SESSION NONE"
```

### Index information

`INFO FOR INDEX` returns the status for an index: started, initial indexing, update indexing, built, or error.

This command only applies when the [`CONCURRENTLY`](/docs/reference/query-language/statements/define/indexes.md#using-concurrently-clause) clause is used in a `DEFINE INDEX` command. Without this clause, the following statement will not be executed until the index is fully created, or fails. In this case, the `INFO FOR INDEX` statement will return an empty object: `{}`.

```surql
CREATE |user:50000| SET name = id.id() RETURN NONE;
DEFINE INDEX unique_name ON TABLE user FIELDS name UNIQUE;
INFO FOR INDEX unique_name ON TABLE user;
```

However, when the `CONCURRENTLY` clause is used, the index will build in the background while other statements are permitted to run. In this case, the `INFO FOR INDEX` statement will provide the current status on the index. The following code sample shows such an example in which an index is defined on a large number of records. A [`SLEEP`](/docs/reference/query-language/statements/sleep.md) statement is run in between each `INFO FOR INDEX` command to show the progress after each 50 millisecond interval.

```surql
CREATE |user:50000| SET name = id.id() RETURN NONE;
DEFINE INDEX unique_name ON TABLE user FIELDS name UNIQUE CONCURRENTLY;
INFO FOR INDEX unique_name ON user;
SLEEP 50ms;
INFO FOR INDEX unique_name ON user;
SLEEP 50ms;
INFO FOR INDEX unique_name ON user;
SLEEP 50ms;
INFO FOR INDEX unique_name ON user;
```

```surql title="Possible output"
-------- Query 1 --------
{ 
    building: {
        initial: 0,
        pending: 0,
        status: 'indexing', 
        updated: 0
    }
}

-------- Query 2 --------
{ 
    building: {
        initial: 100,
        pending: 20,
        status: 'indexing', 
        updated: 0
    }
}

-------- Query 3 --------
{ 
    building: {
        initial: 100,
        pending: 4,
        status: 'indexing', 
        updated: 16
    }
}

-------- Query 4 --------
{
    building: {
        status: 'ready'
    }
}
```

### The `STRUCTURE` clause

> [!NOTE]
> This clause was created for internal use and is subject to change without notice.

Adding the `STRUCTURE` clause changes the structure of the statement from an object that contains objects into an object with fields that each contain an array and often extra info.

```surql
DEFINE TABLE user SCHEMAFULL;
DEFINE FIELD name ON user TYPE STRING;

INFO FOR TABLE user;
INFO FOR TABLE user STRUCTURE;
```

```surql title="Output"
-------- Query --------

{
	events: {},
	fields: {
		name: 'DEFINE FIELD name ON user TYPE string PERMISSIONS FULL'
	},
	indexes: {},
	lives: {},
	tables: {}
}

-------- Query --------

{
	events: [],
	fields: [
		{
			flex: false,
			kind: 'string',
			name: 'name',
			permissions: {
				create: true,
				delete: true,
				select: true,
				update: true
			},
			readonly: false,
			what: 'user'
		}
	],
	indexes: [],
	lives: [],
	tables: []
}
```

### Using the output of `INFO`

_(since v3.0.0)_

The output of an `INFO` statement, both with and without the `STRUCTURE` clause, can be used in other operations. As the output of the statement is always a single object, the SurrealQL [object functions](/docs/reference/query-language/functions/database-functions/object.md) can also be used on the output for such tasks as schema change tracking.

```surql
LET $cat = CREATE ONLY cat RETURN VALUE id;

LET $first_schema = {
    revision: rand::uuid(),
    schema: INFO FOR DB
};

$first_schema;

CREATE person SET feeds = [$cat];

LET $second_schema = {
    revision: rand::uuid(),
    schema: INFO FOR DB
};

$second_schema;

$first_schema.diff($second_schema);
```

```surql title="Output"
-------- First schema --------

{
	revision: u'019665cc-f730-75f0-8251-894e11fee7d8',
	schema: {
		accesses: {},
		analyzers: {},
		apis: {},
		buckets: {},
		configs: {},
		functions: {},
		models: {},
		params: {},
		tables: {
			cat: 'DEFINE TABLE cat TYPE ANY SCHEMALESS PERMISSIONS NONE'
		},
		users: {}
	}
}

-------- Second schema --------

{
	revision: u'019665cc-f73b-7313-807f-dd22ad1a0685',
	schema: {
		accesses: {},
		analyzers: {},
		apis: {},
		buckets: {},
		configs: {},
		functions: {},
		models: {},
		params: {},
		tables: {
			cat: 'DEFINE TABLE cat TYPE ANY SCHEMALESS PERMISSIONS NONE',
			person: 'DEFINE TABLE person TYPE ANY SCHEMALESS PERMISSIONS NONE'
		},
		users: {}
	}
}

-------- Diff --------

[
	{
		op: 'replace',
		path: '/revision',
		value: u'019665cc-f73b-7313-807f-dd22ad1a0685'
	},
	{
		op: 'add',
		path: '/schema/tables/person',
		value: 'DEFINE TABLE person TYPE ANY SCHEMALESS PERMISSIONS NONE'
	}
]
```

As `INFO` statements return an object and objects can be turned into arrays using SurrealDB's [object functions](/docs/reference/query-language/functions/database-functions/object.md), all of the statements for a schema can be constructed using `INFO` statements alone. This query for example shows each of the statements found in a single database.

```surql
LET $db = INFO FOR DB;
  $db.tables.values() +
  $db.users.values() + 
  $db.tables.keys().map(|$t| {
    LET $i = INFO FOR TABLE $t;
    $i.fields.?.values() + $i.indexes.?.values()
  }).flatten().filter(|$v| !!$v);
```

### Default namespace and database output

_(since v3.0.0)_

A namespace and database with the name of `name` are generated by default when starting a SurrealDB instance unless the `SURREAL_NO_DEFAULTS` [environment variable](/docs/reference/cli/surrealdb-cli/environment-variables.md) is set to false or the [`--no-defaults`](/docs/reference/cli/surrealdb-cli/commands/start.md) flag is used.

The output of the `INFO` statement in this case includes a comment on how these two resources were defined.

```surql
[INFO FOR ROOT.namespaces, INFO FOR NS.databases];
```

```surql title="Output"
[
	{ main: "DEFINE NAMESPACE main COMMENT 'Default namespace generated by SurrealDB'" }, 
	{ main: "DEFINE DATABASE main COMMENT 'Default database generated by SurrealDB'" }
]
```
