This guide provides an overview of Fauna and its key features.

What is Fauna?

Fauna is a distributed document-relational database service that combines the flexibility of documents with the power of a relational database. Features include:

You access Fauna through a client driver or directly through an HTTP API.


Every Fauna query is a transaction, submitted as an HTTP API request.

Transactions are isolated and serialized to guarantee consistency across concurrent operations.

See Transactions

Distributed service

Fauna uses a fully managed, serverless infrastructure designed for high availability and global distribution.

Region groups

You assign each top-level Fauna database a region group. Region groups give you control over where your data resides.

You can use region groups to comply with data locality legislation, such as the General Data Protection Regulation (GDPR).

See Region Groups

Intelligent routing

All Fauna transactions use a single HTTP endpoint, regardless of their region group or database.

Fauna uses intelligent routing to route requests to the right region group and database based on its authentication token. A client application can use multiple region groups or databases without code changes.

See Intelligent routing

High availability

Fauna replicates your data by default. Your data is unaffected by regional outages and is always recoverable from disasters.

See Replica distribution

Virtual private Fauna

Virtual Private Fauna lets you use Fauna in a single-tenant environment with no infrastructure management.

You can fully customize Virtual Private Fauna to meet your specific security and compliance needs. Virtual Private Fauna is available across a single region, multiple regions, or multiple clouds of your choice.

See Virtual Private Fauna

Data model

You add data to Fauna as JSON-like objects called documents. Documents are stored in collections, which group related data.

See Data model


An index stores, or covers, specific document field values for quick retrieval. Using indexes can significantly improve query performance and reduce costs, especially for large datasets.

You create indexes at the collection level. Fauna indexes support non-scalar data types, such as arrays or nested objects, and non-ID scalar fields.

See Indexes


You can use Fauna to build multitenant applications with strong isolation guarantees.

A Fauna database can have multiple child databases. Child databases can have their own child databases.

You can programmatically create databases using queries or the Fauna CLI. Databases are instantly allocated.

Each database is logically isolated from its peers, with separate access controls. Transactions run in the context of a single database and can’t access data outside the database.

Connect to Fauna

You can interact with Fauna through a client driver or directly through its HTTP API. Any client that can send and receive HTTP requests can connect to Fauna.

See HTTP API reference

Fauna drivers

Fauna has official client drivers for popular programming languages, such as JavaScript, Python, and Go.

Each driver is a lightweight, open-source wrapper for the HTTP API. The drivers are small enough for use in serverless functions, edge networks, and other resource-constrained environments.

See Client drivers

Fauna CLI and Dashboard

You manage Fauna using the Fauna CLI or the Fauna Dashboard UI. Use the CLI or Dashboard to:

  • Create and delete databases

  • Define and manage schemas

  • Run queries in an interactive shell

See Fauna CLI, Fauna Dashboard


Schemas determine the structure and behavior of your database.

See Schema

Fauna Schema Language

In Fauna, you define schemas using Fauna Schema Language (FSL). You use FSL to create and update schemas for collections, security roles, server-side user-defined functions (UDFs), and more.

See FSL reference

Document type

A collection schema can include a document type definition. The document type controls what fields are accepted in a collection’s documents.

You define a document’s type using:

  • Field definitions that predefine fields for the collection’s documents

  • A wildcard constraint that allows or disallows arbitrary ad hoc fields

  • Computed field definitions that derive their value from a user-defined function that runs on every read

Example: Customer collection schema

The following schema defines the Customer collection:

collection Customer {
  email: String
  firstName: String
  lastName: String
  purchaseCount: Number

  *: Any

  compute points:Number = doc => doc.purchaseCount * 2

  unique [.email]

  index byEmail {
    terms [.email]

The schema includes a document type made up of:

  • Field definitions for the following fields:

    • email

    • firstName

    • lastName

    • points

  • A wildcard constraint (*: Any) that allows ad hoc fields of any type

  • A computed points field definition that calculates its value by multiplying each document’s purchaseCount value by 2.

The schema also includes:

  • A unique constraint that ensures every Customer document has a unique email field value.

  • A byEmail() index definition. You use the index to run exact match searches for Customer documents based on email values.

See Document type definitions

Zero-downtime migrations

A schema migration is an update to a collection schema’s document type. In Fauna, schema migrations require no downtime or locks on your database.

You can use schema migration to progressively define and enforce a document type in a collection. For example, you can:

  • Require that new documents contain specific fields

  • Add and backfill fields in existing documents

  • Move or rename existing fields

  • Add, remove, or update the wildcard constraint

See Zero-downtime migrations

Manage schemas as FSL files

You can manage schemas as FSL files and use the Fauna CLI to push changes to Fauna. This lets you version control, review, and automate schema changes.

See Fauna CLI

Query data with FQL

Fauna Query Language (FQL) is a TypeScript-like language used to read and write data. You typically compose an FQL query by chaining methods to one or more collections. Expressions are evaluated from left to right.

// Gets the first customer with
// an email of "alice.appleseed@example.com".
let customer = Customer.byEmail("alice.appleseed@example.com").first()

// Gets orders for the customer.
  .order(desc(.creationDate)) {
    user:    .customer.firstName + ' ' + .customer.lastName,
    orderDate: .creationDate

The query declares a customer variable. To set the customer variable’s value, the query:

  • Calls the byEmail() index as a method on the Customer collection.

  • Calls the first() method on the results of the byEmail() call.

The query then:

  • Calls the byCustomer() index as a method on the Order collection. The query passes the customer variable to the index call.

  • Calls the order() method on the results of the byCustomer() call.

  • Projects the query results to a user-defined structure. This also resolves document references in the customer field.

See FQL language reference

Static typing

FQL is statically typed. Every expression has a data type that’s checked before evaluation.

Type checking helps catch errors early and consistently, saving you time during development. You can turn off type checking for any query.

See Static typing


Fauna supports one-to-one, one-to-many, and many-to-many relationships between documents in different collections.

You create relationships by including a reference to a document in another document. This lets you model complex data structures without duplicating data across collections.

Projection lets you return only the specific fields you want from queries. You can project results to dynamically resolve document relationships. This lets you traverse multiple deeply nested relationships in a single query.

See Document relationships

Event Streaming

Fauna supports Event Streaming. An event stream sends your application a real-time update when changes occur in a database. You can configure streams to only track specific collections, fields, or documents.

Fauna’s drivers provide methods for creating and connecting to streams.

See Event Streaming


Fauna prioritizes security and compliance. All Fauna connections use HTTPS. Fauna is compliant with GDPR and SOC2 Type II. Fauna can be configured to meet HIPAA requirements.

See Security


Fauna uses stateless, token-based authentication. You authenticate with Fauna using secrets that are passed to the HTTP API as bearer tokens. Every transaction is an independently secured HTTP API request.

Identity-based authentication

Fauna supports two methods for end-user authentication:

  • Credentials: A credential associates an end-user password with a document representing a user, system, or other identity. This document is called an identity document.

    Once created, you use the credential to generate a token you can use as a Fauna secret. The token is associated with the identity document and can have multiple roles.

    See Credentials
  • Access providers: Configure an external identity provider (IdP), like Amazon Cognito or Auth0, as an access provider in your Fauna database.

    When a user logs in, the access provider passes a JSON Web Token (JWT) to your application. You can use the JWT as a Fauna secret. The JWT is associated with the user and can have multiple roles.

    See Access providers

Anonymous authentication

You can also create keys that can be used as Fauna secrets. Unlike tokens and JWTs, keys are not associated with an identity and only have one role.

See Keys


Secrets are also used for authorization. Each secret has one or more roles that control access to a database’s data.

See Authorization


Fauna uses secrets for authentication and authorization. Roles determine a secret’s privileges, which control data access.

See Roles


Fauna supports attribute-based access control (ABAC), which extends traditional role-based access control (RBAC).

In Fauna, you define roles and their privileges as FSL schemas. You can conditionally grant roles or privileges using predicates.

See Attribute-based access control (ABAC)

Privilege predicates

Predicates are anonymous, read-only FQL functions that evaluate to true or false. They have access to FQL methods, collections, and server-side UDFs. Privilege predicates can also access the current token’s identity document.

Fauna evaluates privilege predicates at query time for each query. This lets you dynamically change privileges based on current state. For example, you can change access based on:

  • The user’s current location, status, or recent activity.

  • The accessed document’s current status or other attributes.

  • Date or time of day


The following schema defines the customer role and includes several predicates:

role customer {
  privileges Order {
    // If the predicate is `true`,
    // grant read access to the `Order` collection.
    read {
      predicate (doc =>
        // Check the order's `status` field.
        doc.status != "Deleted" &&
        // Check that the order belongs to the customer.
        Query.identity() == doc.customer
    // If the predicate is `true`,
    // grant write access to the `Order` collection.
    write {
      predicate ((oldDoc, newDoc) =>
        // Check the existing order's status.
        oldDoc.status != "Deleted" &&
        // Check that the existing order belongs to the customer.
        Query.identity() == oldDoc.customer &&
        // Check that customer isn't changed by the write.
        oldDoc.customer == newDoc.customer &&
        // Check that the user has a positive balance
        // using the user-defined `hasFunds` function.
        hasFunds(Query.identity()?.balance) &&
        // Check the current time.
        // Allow access after 07:00 (7 AM).
        Time.now().hour > 7 &&
        // Disallow access after 20:00 (8 PM).
        Time.now().hour < 20
See Attribute-based access control (ABAC)

Dynamic role assignment

Fauna assigns roles to tokens based on their identity document’s collection and the role’s membership property.


Tokens for Customer documents have the customer role:

role customer {
  membership Customer

You can use membership predicates to dynamically assign roles based on current state. Like privilege predicates, Fauna evaluates membership predicates at query time for each query.


Limit the customer role to Customer users with an active status:

role customer {
  membership Customer {
    predicate ((user) => user.status == "active")
See Attribute-based access control (ABAC)

Is this article helpful? 

Tell Fauna how the article can be improved:
Visit Fauna's forums or email docs@fauna.com

Thank you for your feedback!