01 Tutorials

Languages:

Introduction

FaunaDB’s quality of service system enables teams to use a single cluster for multiple, competing workloads. QoS works by assigning a key or database a priority. Priorities are relative to sibling objects. Database priorities affect the keys and sub-databases within their scope.

This tutorial will walk through a scenario where an e-commerce company needs to simultaneously serve its customers and run analytics on its data. A common solution for this is to run two separate systems. Data gets periodically duplicated from the on-line system to the analytics system. This protects the on-line system from being consumed by the analytics workload, but requires a duplication of data, a separate system to maintained, and means the data being analyzed is always out of date.

FaunaDB’s priority settings eliminate the need for redundant systems. A key for on-line transactions can be created with a high priority and another for analytics with a low priority. If the cluster becomes saturated, the production key’s work is guaranteed to be given a higher priority than the analytics work. When the cluster is not saturated, the analytics work will be allowed to consume resources the production work is not using.

In this tutorial, we’ll create two databases: production and analytics. The production database will be used for customer data (customers, shopping carts, etc). The analytics database will be used to store results of our analysis. We’ll also create three keys: two for the production database – one for the app to use, the other for the analytics team – and another key for the analytics database that that team will use to store their results.

Create Databases

First we’ll create the two databases. We’ll give our production database a priority of 50 and our analytics database a priority of 5. This gives us room to adjust as needed, but ensures that customer queries are prioritized over analytics.


curl https://db.fauna.com/ \
    -u kqnPAi3Kj3ZgAAC0Hu51Ng2dtn0JcgP7Fb-Q_uzLGZE: \
    -d '[
          {
            "create_database": { "object": { "name": "production", "priority": 50 } }
          },
          {
            "create_database": { "object": { "name": "analytics", "priority": 5 } }
          }
        ]'

FaunaClient adminClient = FaunaClient.builder()
  .withSecret(adminKey)
  .build();

adminClient.query(
  Arr(
    CreateDatabase(
      Obj("name", Value("production"), "priority", Value(50))),
    CreateDatabase(
      Obj("name", Value("analytics"), "priority", Value(5)))
  ));

var adminClient = new faunadb.Client({
  secret: adminKey
});

adminClient.query(
  [
    q.CreateDatabase({ name: "production", priority: 50 }),
    q.CreateDatabase({ name: "analytics", priority: 5 })
  ]);

val adminClient = FaunaClient(secret = adminKey)

adminClient.query(
  Arr(
    CreateDatabase(Obj("name" -> "production", "priority" -> 50)),
    CreateDatabase(Obj("name" -> "analytics", "priority" -> 5))
  ))

$admin_client = Fauna::Client.new(secret: adminKey)

$admin_client.query do
  [
    create_database(name: 'production', priority: 50),
    create_database(name: 'analytics', priority: 5)
  ]
end

var adminClient = new FaunaClient(secret: adminKey);

adminClient.Query(
  Arr(
    CreateDatabase(Obj("name", "production", "priority", 50)),
    CreateDatabase(Obj("name", "analytics", "priority", 5))
  ));

adminClient = FaunaClient(secret=adminKey)

adminClient.query(
  [
    q.create_database({"name": "production", "priority": 50}),
    q.create_database({"name": "analytics", "priority": 5})
  ])

adminClient = f.NewFaunaClient(adminKey)

adminClient.Query(
    f.Arr{
        f.CreateDatabase(
            f.Obj{"name": "production", "priority": 50},
        ),
        f.CreateDatabase(f.Obj{"name": "analytics", "priority": 5}),
    },
)

let adminClient = FaunaDB.Client(secret: adminKey)

adminClient.query(
    Arr(
        CreateDatabase(
            Obj("name" => "production", "priority" => 50)
        ),
        CreateDatabase(
            Obj("name" => "analytics", "priority" => 5)
        )
    )
)

HTTP/1.1 200 OK
{
  "resource": [
    {
      "ref": { "@ref": "databases/production" },
      "class": { "@ref": "databases" },
      "ts": 1436375112141542,
      "name": "production",
      "priority": 50
    },
    {
      "ref": { "@ref": "databases/analytics" },
      "class": { "@ref": "databases" },
      "ts": 1436375112141542,
      "name": "analytics",
      "priority": 5
    }
  ]
}

=> [
  {
    "ref": { "@ref": "databases/production" },
    "class": { "@ref": "databases" },
    "ts": 1436375112141542,
    "name": "production",
    "priority": 50
  },
  {
    "ref": { "@ref": "databases/analytics" },
    "class": { "@ref": "databases" },
    "ts": 1436375112141542,
    "name": "analytics",
    "priority": 5
  }
]

=> [
  {
    "ref": { "@ref": "databases/production" },
    "class": { "@ref": "databases" },
    "ts": 1436375112141542,
    "name": "production",
    "priority": 50
  },
  {
    "ref": { "@ref": "databases/analytics" },
    "class": { "@ref": "databases" },
    "ts": 1436375112141542,
    "name": "analytics",
    "priority": 5
  }
]

=> [
  {
    "ref": { "@ref": "databases/production" },
    "class": { "@ref": "databases" },
    "ts": 1436375112141542,
    "name": "production",
    "priority": 50
  },
  {
    "ref": { "@ref": "databases/analytics" },
    "class": { "@ref": "databases" },
    "ts": 1436375112141542,
    "name": "analytics",
    "priority": 5
  }
]

=> [
  {
    "ref": { "@ref": "databases/production" },
    "class": { "@ref": "databases" },
    "ts": 1436375112141542,
    "name": "production",
    "priority": 50
  },
  {
    "ref": { "@ref": "databases/analytics" },
    "class": { "@ref": "databases" },
    "ts": 1436375112141542,
    "name": "analytics",
    "priority": 5
  }
]

=> [
  {
    "ref": { "@ref": "databases/production" },
    "class": { "@ref": "databases" },
    "ts": 1436375112141542,
    "name": "production",
    "priority": 50
  },
  {
    "ref": { "@ref": "databases/analytics" },
    "class": { "@ref": "databases" },
    "ts": 1436375112141542,
    "name": "analytics",
    "priority": 5
  }
]

=> [
  {
    "ref": { "@ref": "databases/production" },
    "class": { "@ref": "databases" },
    "ts": 1436375112141542,
    "name": "production",
    "priority": 50
  },
  {
    "ref": { "@ref": "databases/analytics" },
    "class": { "@ref": "databases" },
    "ts": 1436375112141542,
    "name": "analytics",
    "priority": 5
  }
]

=> [
  {
    "ref": { "@ref": "databases/production" },
    "class": { "@ref": "databases" },
    "ts": 1436375112141542,
    "name": "production",
    "priority": 50
  },
  {
    "ref": { "@ref": "databases/analytics" },
    "class": { "@ref": "databases" },
    "ts": 1436375112141542,
    "name": "analytics",
    "priority": 5
  }
]

=> [
  {
    "ref": { "@ref": "databases/production" },
    "class": { "@ref": "databases" },
    "ts": 1436375112141542,
    "name": "production",
    "priority": 50
  },
  {
    "ref": { "@ref": "databases/analytics" },
    "class": { "@ref": "databases" },
    "ts": 1436375112141542,
    "name": "analytics",
    "priority": 5
  }
]

Create Keys

Now we can create the three keys we’ll need. Our production system will need a high priority key for the production database. The analytics team will need a low priority key for the production database and key for the analytics database. The key for the analytics database can have the default priority as the database itself has a priority.

We’ll add extra metadata to the production keys that will make it easier to remember which is which.


curl https://db.fauna.com/ \
    -u kqnPAi3Kj3ZgAAC0Hu51Ng2dtn0JcgP7Fb-Q_uzLGZE: \
    -d '[
          {
            "create_key": {
              "object": {
                "role": "server",
                "database": { "database": "production" },
                "data": { "object": { "name": "production" } },
                "priority": 50
              }
            }
          },
          {
            "create_key": {
              "object": {
                "role": "server",
                "database": { "database": "production" },
                "data": { "object": { "name": "analytics" } },
                "priority": 5
              }
            }
          },
          {
            "create_key": {
              "object": {
                "role": "server",
                "database": { "database": "analytics" }
              }
            }
          }
        ]'

FaunaClient amdinKey = FaunaClient.builder()
  .withSecret(adminKey)
  .build();

amdinKey.query(
  Arr(
    CreateKey(
      Obj(
        "role", Value("server"),
        "database", Database(Value("production")),
        "data", Obj("name", Value("production")),
        "priority", Value(50)
      )),
    CreateKey(
      Obj(
        "role", Value("server"),
        "database", Database(Value("production")),
        "data", Obj("name", Value("analytics")),
        "priority", Value(5)
      )),
    CreateKey(
      Obj(
        "role", Value("server"),
        "database", Database(Value("analytics"))
      ))
  ));

var amdinKey = new faunadb.Client({
  secret: adminKey
});

amdinKey.query(
  [
    q.CreateKey(
      {
        role: "server",
        database: q.Database("production"),
        data: { name: "production" },
        priority: 50
      }),
    q.CreateKey(
      {
        role: "server",
        database: q.Database("production"),
        data: { name: "analytics" },
        priority: 5
      }),
    q.CreateKey(
      { role: "server", database: q.Database("analytics") })
  ]);

val amdinKey = FaunaClient(secret = adminKey)

amdinKey.query(
  Arr(
    CreateKey(
      Obj(
        "role" -> "server",
        "database" -> Database("production"),
        "data" -> Obj("name" -> "production"),
        "priority" -> 50
      )),
    CreateKey(
      Obj(
        "role" -> "server",
        "database" -> Database("production"),
        "data" -> Obj("name" -> "analytics"),
        "priority" -> 5
      )),
    CreateKey(
      Obj("role" -> "server", "database" -> Database("analytics")))
  ))

$amdin_key = Fauna::Client.new(secret: adminKey)

$amdin_key.query do
  [
    create_key(role: 'server',
               database: database('production'),
               data: { name: 'production' },
               priority: 50),
    create_key(role: 'server',
               database: database('production'),
               data: { name: 'analytics' },
               priority: 5),
    create_key(role: 'server', database: database('analytics'))
  ]
end

var amdinKey = new FaunaClient(secret: adminKey);

amdinKey.Query(
  Arr(
    CreateKey(
      Obj(
        "role", "server",
        "database", Database("production"),
        "data", Obj("name", "production"),
        "priority", 50
      )),
    CreateKey(
      Obj(
        "role", "server",
        "database", Database("production"),
        "data", Obj("name", "analytics"),
        "priority", 5
      )),
    CreateKey(
      Obj("role", "server", "database", Database("analytics")))
  ));

amdinKey = FaunaClient(secret=adminKey)

amdinKey.query(
  [
    q.create_key(
      {
        "role": "server",
        "database": q.database("production"),
        "data": {"name": "production"},
        "priority": 50
      }
    ),
    q.create_key(
      {
        "role": "server",
        "database": q.database("production"),
        "data": {"name": "analytics"},
        "priority": 5
      }
    ),
    q.create_key(
      {"role": "server", "database": q.database("analytics")}
    )
  ])

amdinKey = f.NewFaunaClient(adminKey)

amdinKey.Query(
    f.Arr{
        f.CreateKey(
            f.Obj{
                "role": "server",
                "database": f.Database("production"),
                "data": f.Obj{"name": "production"},
                "priority": 50,
            },
        ),
        f.CreateKey(
            f.Obj{
                "role": "server",
                "database": f.Database("production"),
                "data": f.Obj{"name": "analytics"},
                "priority": 5,
            },
        ),
        f.CreateKey(
            f.Obj{"role": "server", "database": f.Database("analytics")},
        ),
    },
)

let amdinKey = FaunaDB.Client(secret: adminKey)

amdinKey.query(
    Arr(
        CreateKey(
            Obj(
                "role" => "server",
                "database" => Database("production"),
                "data" => Obj("name" => "production"),
                "priority" => 50
            )
        ),
        CreateKey(
            Obj(
                "role" => "server",
                "database" => Database("production"),
                "data" => Obj("name" => "analytics"),
                "priority" => 5
            )
        ),
        CreateKey(
            Obj(
                "role" => "server",
                "database" => Database("analytics")
            )
        )
    )
)

HTTP/1.1 200 OK
{
  "resource": [
    {
      "ref": { "@ref": "keys/104979509692858368" },
      "class": { "@ref": "keys" },
      "ts": 1436375112199704,
      "role": "server",
      "database": { "@ref": "databases/production" },
      "data": { "name": "production" },
      "priority": 50,
      "secret": "kqnPAi4gDivAAAC0i5t-a9YCcRnljtU2SfMJ-kWSRYI",
      "hashed_secret": "$2a$05$.saZ/E/JSuEEkbIfTU/GN.7iKEBBpBGePtWe/mZyL/rmf4uXeZ5oi"
    },
    {
      "ref": { "@ref": "keys/104979509693618791" },
      "class": { "@ref": "keys" },
      "ts": 1436375112199704,
      "role": "server",
      "database": { "@ref": "databases/production" },
      "data": { "name": "analytics" },
      "priority": 5,
      "secret": "kqnPAi3KlXEgAAC0OHSIyrIITuOMRfwre9owibw4nPU",
      "hashed_secret": "$2a$05$/FgxoctNLXMBjYAcea/dwOeyYLJtQLGiEdf2S/Lu6ZN7e6Gps6WF6"
    },
    {
      "ref": { "@ref": "keys/104979509694379214" },
      "class": { "@ref": "keys" },
      "ts": 1436375112199704,
      "role": "server",
      "database": { "@ref": "databases/analytics" },
      "secret": "kqnPAi4gE97wAAC0sl11pF8QcY_1w_am0-FX_hR3HEU",
      "hashed_secret": "$2a$05$wEQ1p82hrSGAQUVH6uzLEuCVqQCrhqOjvRkNx/P78TGm9rhA4qS9a"
    }
  ]
}

=> [
  {
    "ref": { "@ref": "keys/104979509692858368" },
    "class": { "@ref": "keys" },
    "ts": 1436375112199704,
    "role": "server",
    "database": { "@ref": "databases/production" },
    "data": { "name": "production" },
    "priority": 50,
    "secret": "kqnPAi4gDivAAAC0i5t-a9YCcRnljtU2SfMJ-kWSRYI",
    "hashed_secret": "$2a$05$.saZ/E/JSuEEkbIfTU/GN.7iKEBBpBGePtWe/mZyL/rmf4uXeZ5oi"
  },
  {
    "ref": { "@ref": "keys/104979509693618791" },
    "class": { "@ref": "keys" },
    "ts": 1436375112199704,
    "role": "server",
    "database": { "@ref": "databases/production" },
    "data": { "name": "analytics" },
    "priority": 5,
    "secret": "kqnPAi3KlXEgAAC0OHSIyrIITuOMRfwre9owibw4nPU",
    "hashed_secret": "$2a$05$/FgxoctNLXMBjYAcea/dwOeyYLJtQLGiEdf2S/Lu6ZN7e6Gps6WF6"
  },
  {
    "ref": { "@ref": "keys/104979509694379214" },
    "class": { "@ref": "keys" },
    "ts": 1436375112199704,
    "role": "server",
    "database": { "@ref": "databases/analytics" },
    "secret": "kqnPAi4gE97wAAC0sl11pF8QcY_1w_am0-FX_hR3HEU",
    "hashed_secret": "$2a$05$wEQ1p82hrSGAQUVH6uzLEuCVqQCrhqOjvRkNx/P78TGm9rhA4qS9a"
  }
]

=> [
  {
    "ref": { "@ref": "keys/104979509692858368" },
    "class": { "@ref": "keys" },
    "ts": 1436375112199704,
    "role": "server",
    "database": { "@ref": "databases/production" },
    "data": { "name": "production" },
    "priority": 50,
    "secret": "kqnPAi4gDivAAAC0i5t-a9YCcRnljtU2SfMJ-kWSRYI",
    "hashed_secret": "$2a$05$.saZ/E/JSuEEkbIfTU/GN.7iKEBBpBGePtWe/mZyL/rmf4uXeZ5oi"
  },
  {
    "ref": { "@ref": "keys/104979509693618791" },
    "class": { "@ref": "keys" },
    "ts": 1436375112199704,
    "role": "server",
    "database": { "@ref": "databases/production" },
    "data": { "name": "analytics" },
    "priority": 5,
    "secret": "kqnPAi3KlXEgAAC0OHSIyrIITuOMRfwre9owibw4nPU",
    "hashed_secret": "$2a$05$/FgxoctNLXMBjYAcea/dwOeyYLJtQLGiEdf2S/Lu6ZN7e6Gps6WF6"
  },
  {
    "ref": { "@ref": "keys/104979509694379214" },
    "class": { "@ref": "keys" },
    "ts": 1436375112199704,
    "role": "server",
    "database": { "@ref": "databases/analytics" },
    "secret": "kqnPAi4gE97wAAC0sl11pF8QcY_1w_am0-FX_hR3HEU",
    "hashed_secret": "$2a$05$wEQ1p82hrSGAQUVH6uzLEuCVqQCrhqOjvRkNx/P78TGm9rhA4qS9a"
  }
]

=> [
  {
    "ref": { "@ref": "keys/104979509692858368" },
    "class": { "@ref": "keys" },
    "ts": 1436375112199704,
    "role": "server",
    "database": { "@ref": "databases/production" },
    "data": { "name": "production" },
    "priority": 50,
    "secret": "kqnPAi4gDivAAAC0i5t-a9YCcRnljtU2SfMJ-kWSRYI",
    "hashed_secret": "$2a$05$.saZ/E/JSuEEkbIfTU/GN.7iKEBBpBGePtWe/mZyL/rmf4uXeZ5oi"
  },
  {
    "ref": { "@ref": "keys/104979509693618791" },
    "class": { "@ref": "keys" },
    "ts": 1436375112199704,
    "role": "server",
    "database": { "@ref": "databases/production" },
    "data": { "name": "analytics" },
    "priority": 5,
    "secret": "kqnPAi3KlXEgAAC0OHSIyrIITuOMRfwre9owibw4nPU",
    "hashed_secret": "$2a$05$/FgxoctNLXMBjYAcea/dwOeyYLJtQLGiEdf2S/Lu6ZN7e6Gps6WF6"
  },
  {
    "ref": { "@ref": "keys/104979509694379214" },
    "class": { "@ref": "keys" },
    "ts": 1436375112199704,
    "role": "server",
    "database": { "@ref": "databases/analytics" },
    "secret": "kqnPAi4gE97wAAC0sl11pF8QcY_1w_am0-FX_hR3HEU",
    "hashed_secret": "$2a$05$wEQ1p82hrSGAQUVH6uzLEuCVqQCrhqOjvRkNx/P78TGm9rhA4qS9a"
  }
]

=> [
  {
    "ref": { "@ref": "keys/104979509692858368" },
    "class": { "@ref": "keys" },
    "ts": 1436375112199704,
    "role": "server",
    "database": { "@ref": "databases/production" },
    "data": { "name": "production" },
    "priority": 50,
    "secret": "kqnPAi4gDivAAAC0i5t-a9YCcRnljtU2SfMJ-kWSRYI",
    "hashed_secret": "$2a$05$.saZ/E/JSuEEkbIfTU/GN.7iKEBBpBGePtWe/mZyL/rmf4uXeZ5oi"
  },
  {
    "ref": { "@ref": "keys/104979509693618791" },
    "class": { "@ref": "keys" },
    "ts": 1436375112199704,
    "role": "server",
    "database": { "@ref": "databases/production" },
    "data": { "name": "analytics" },
    "priority": 5,
    "secret": "kqnPAi3KlXEgAAC0OHSIyrIITuOMRfwre9owibw4nPU",
    "hashed_secret": "$2a$05$/FgxoctNLXMBjYAcea/dwOeyYLJtQLGiEdf2S/Lu6ZN7e6Gps6WF6"
  },
  {
    "ref": { "@ref": "keys/104979509694379214" },
    "class": { "@ref": "keys" },
    "ts": 1436375112199704,
    "role": "server",
    "database": { "@ref": "databases/analytics" },
    "secret": "kqnPAi4gE97wAAC0sl11pF8QcY_1w_am0-FX_hR3HEU",
    "hashed_secret": "$2a$05$wEQ1p82hrSGAQUVH6uzLEuCVqQCrhqOjvRkNx/P78TGm9rhA4qS9a"
  }
]

=> [
  {
    "ref": { "@ref": "keys/104979509692858368" },
    "class": { "@ref": "keys" },
    "ts": 1436375112199704,
    "role": "server",
    "database": { "@ref": "databases/production" },
    "data": { "name": "production" },
    "priority": 50,
    "secret": "kqnPAi4gDivAAAC0i5t-a9YCcRnljtU2SfMJ-kWSRYI",
    "hashed_secret": "$2a$05$.saZ/E/JSuEEkbIfTU/GN.7iKEBBpBGePtWe/mZyL/rmf4uXeZ5oi"
  },
  {
    "ref": { "@ref": "keys/104979509693618791" },
    "class": { "@ref": "keys" },
    "ts": 1436375112199704,
    "role": "server",
    "database": { "@ref": "databases/production" },
    "data": { "name": "analytics" },
    "priority": 5,
    "secret": "kqnPAi3KlXEgAAC0OHSIyrIITuOMRfwre9owibw4nPU",
    "hashed_secret": "$2a$05$/FgxoctNLXMBjYAcea/dwOeyYLJtQLGiEdf2S/Lu6ZN7e6Gps6WF6"
  },
  {
    "ref": { "@ref": "keys/104979509694379214" },
    "class": { "@ref": "keys" },
    "ts": 1436375112199704,
    "role": "server",
    "database": { "@ref": "databases/analytics" },
    "secret": "kqnPAi4gE97wAAC0sl11pF8QcY_1w_am0-FX_hR3HEU",
    "hashed_secret": "$2a$05$wEQ1p82hrSGAQUVH6uzLEuCVqQCrhqOjvRkNx/P78TGm9rhA4qS9a"
  }
]

=> [
  {
    "ref": { "@ref": "keys/104979509692858368" },
    "class": { "@ref": "keys" },
    "ts": 1436375112199704,
    "role": "server",
    "database": { "@ref": "databases/production" },
    "data": { "name": "production" },
    "priority": 50,
    "secret": "kqnPAi4gDivAAAC0i5t-a9YCcRnljtU2SfMJ-kWSRYI",
    "hashed_secret": "$2a$05$.saZ/E/JSuEEkbIfTU/GN.7iKEBBpBGePtWe/mZyL/rmf4uXeZ5oi"
  },
  {
    "ref": { "@ref": "keys/104979509693618791" },
    "class": { "@ref": "keys" },
    "ts": 1436375112199704,
    "role": "server",
    "database": { "@ref": "databases/production" },
    "data": { "name": "analytics" },
    "priority": 5,
    "secret": "kqnPAi3KlXEgAAC0OHSIyrIITuOMRfwre9owibw4nPU",
    "hashed_secret": "$2a$05$/FgxoctNLXMBjYAcea/dwOeyYLJtQLGiEdf2S/Lu6ZN7e6Gps6WF6"
  },
  {
    "ref": { "@ref": "keys/104979509694379214" },
    "class": { "@ref": "keys" },
    "ts": 1436375112199704,
    "role": "server",
    "database": { "@ref": "databases/analytics" },
    "secret": "kqnPAi4gE97wAAC0sl11pF8QcY_1w_am0-FX_hR3HEU",
    "hashed_secret": "$2a$05$wEQ1p82hrSGAQUVH6uzLEuCVqQCrhqOjvRkNx/P78TGm9rhA4qS9a"
  }
]

=> [
  {
    "ref": { "@ref": "keys/104979509692858368" },
    "class": { "@ref": "keys" },
    "ts": 1436375112199704,
    "role": "server",
    "database": { "@ref": "databases/production" },
    "data": { "name": "production" },
    "priority": 50,
    "secret": "kqnPAi4gDivAAAC0i5t-a9YCcRnljtU2SfMJ-kWSRYI",
    "hashed_secret": "$2a$05$.saZ/E/JSuEEkbIfTU/GN.7iKEBBpBGePtWe/mZyL/rmf4uXeZ5oi"
  },
  {
    "ref": { "@ref": "keys/104979509693618791" },
    "class": { "@ref": "keys" },
    "ts": 1436375112199704,
    "role": "server",
    "database": { "@ref": "databases/production" },
    "data": { "name": "analytics" },
    "priority": 5,
    "secret": "kqnPAi3KlXEgAAC0OHSIyrIITuOMRfwre9owibw4nPU",
    "hashed_secret": "$2a$05$/FgxoctNLXMBjYAcea/dwOeyYLJtQLGiEdf2S/Lu6ZN7e6Gps6WF6"
  },
  {
    "ref": { "@ref": "keys/104979509694379214" },
    "class": { "@ref": "keys" },
    "ts": 1436375112199704,
    "role": "server",
    "database": { "@ref": "databases/analytics" },
    "secret": "kqnPAi4gE97wAAC0sl11pF8QcY_1w_am0-FX_hR3HEU",
    "hashed_secret": "$2a$05$wEQ1p82hrSGAQUVH6uzLEuCVqQCrhqOjvRkNx/P78TGm9rhA4qS9a"
  }
]

=> [
  {
    "ref": { "@ref": "keys/104979509692858368" },
    "class": { "@ref": "keys" },
    "ts": 1436375112199704,
    "role": "server",
    "database": { "@ref": "databases/production" },
    "data": { "name": "production" },
    "priority": 50,
    "secret": "kqnPAi4gDivAAAC0i5t-a9YCcRnljtU2SfMJ-kWSRYI",
    "hashed_secret": "$2a$05$.saZ/E/JSuEEkbIfTU/GN.7iKEBBpBGePtWe/mZyL/rmf4uXeZ5oi"
  },
  {
    "ref": { "@ref": "keys/104979509693618791" },
    "class": { "@ref": "keys" },
    "ts": 1436375112199704,
    "role": "server",
    "database": { "@ref": "databases/production" },
    "data": { "name": "analytics" },
    "priority": 5,
    "secret": "kqnPAi3KlXEgAAC0OHSIyrIITuOMRfwre9owibw4nPU",
    "hashed_secret": "$2a$05$/FgxoctNLXMBjYAcea/dwOeyYLJtQLGiEdf2S/Lu6ZN7e6Gps6WF6"
  },
  {
    "ref": { "@ref": "keys/104979509694379214" },
    "class": { "@ref": "keys" },
    "ts": 1436375112199704,
    "role": "server",
    "database": { "@ref": "databases/analytics" },
    "secret": "kqnPAi4gE97wAAC0sl11pF8QcY_1w_am0-FX_hR3HEU",
    "hashed_secret": "$2a$05$wEQ1p82hrSGAQUVH6uzLEuCVqQCrhqOjvRkNx/P78TGm9rhA4qS9a"
  }
]

Adjusting Priorities

After our systems run for a few weeks we start to realize that the analytics work is still getting in the way of our production work. We need to adjust the priorities to give our production work more room.


curl https://db.fauna.com/ \
    -u kqnPAi3Kj3ZgAAC0Hu51Ng2dtn0JcgP7Fb-Q_uzLGZE: \
    -d '[
          {
            "update": { "database": "production" },
            "params": { "object": { "priority": 80 } }
          },
          {
            "update": { "@ref": "keys/104979509692858368" },
            "params": { "object": { "priority": 80 } }
          }
        ]'

FaunaClient adminKey = FaunaClient.builder()
  .withSecret(adminKey)
  .build();

adminKey.query(
  Arr(
    Update(
      Database(Value("production")),
      Obj("priority", Value(80))),
    Update(
      Ref("keys/104979509692858368"),
      Obj("priority", Value(80)))
  ));

var adminKey = new faunadb.Client({
  secret: adminKey
});

adminKey.query(
  [
    q.Update(q.Database("production"), { priority: 80 }),
    q.Update(Ref("keys/104979509692858368"), { priority: 80 })
  ]);

val adminKey = FaunaClient(secret = adminKey)

adminKey.query(
  Arr(
    Update(Database("production"), Obj("priority" -> 80)),
    Update(Ref("keys/104979509692858368"), Obj("priority" -> 80))
  ))

$admin_key = Fauna::Client.new(secret: adminKey)

$admin_key.query do
  [
    update(database('production'), priority: 80),
    update(ref('keys/104979509692858368'), priority: 80)
  ]
end

var adminKey = new FaunaClient(secret: adminKey);

adminKey.Query(
  Arr(
    Update(Database("production"), Obj("priority", 80)),
    Update(Ref("keys/104979509692858368"), Obj("priority", 80))
  ));

adminKey = FaunaClient(secret=adminKey)

adminKey.query(
  [
    q.update(q.database("production"), {"priority": 80}),
    q.update(Ref("keys/104979509692858368"), {"priority": 80})
  ])

adminKey = f.NewFaunaClient(adminKey)

adminKey.Query(
    f.Arr{
        f.Update(f.Database("production"), f.Obj{"priority": 80}),
        f.Update(
            f.Ref("keys/104979509692858368"),
            f.Obj{"priority": 80},
        ),
    },
)

let adminKey = FaunaDB.Client(secret: adminKey)

adminKey.query(
    Arr(
        Update(
            ref: Database("production"),
            to: Obj("priority" => 80)
        ),
        Update(
            ref: Ref("keys/104979509692858368"),
            to: Obj("priority" => 80)
        )
    )
)

HTTP/1.1 200 OK
{
  "resource": [
    {
      "ref": { "@ref": "databases/production" },
      "class": { "@ref": "databases" },
      "ts": 1436375112257866,
      "name": "production",
      "priority": 80
    },
    {
      "ref": { "@ref": "keys/104979509692858368" },
      "class": { "@ref": "keys" },
      "ts": 1436375112257866,
      "role": "server",
      "database": { "@ref": "databases/production" },
      "data": { "name": "production" },
      "priority": 80,
      "hashed_secret": "$2a$05$.saZ/E/JSuEEkbIfTU/GN.7iKEBBpBGePtWe/mZyL/rmf4uXeZ5oi"
    }
  ]
}

=> [
  {
    "ref": { "@ref": "databases/production" },
    "class": { "@ref": "databases" },
    "ts": 1436375112257866,
    "name": "production",
    "priority": 80
  },
  {
    "ref": { "@ref": "keys/104979509692858368" },
    "class": { "@ref": "keys" },
    "ts": 1436375112257866,
    "role": "server",
    "database": { "@ref": "databases/production" },
    "data": { "name": "production" },
    "priority": 80,
    "hashed_secret": "$2a$05$.saZ/E/JSuEEkbIfTU/GN.7iKEBBpBGePtWe/mZyL/rmf4uXeZ5oi"
  }
]

=> [
  {
    "ref": { "@ref": "databases/production" },
    "class": { "@ref": "databases" },
    "ts": 1436375112257866,
    "name": "production",
    "priority": 80
  },
  {
    "ref": { "@ref": "keys/104979509692858368" },
    "class": { "@ref": "keys" },
    "ts": 1436375112257866,
    "role": "server",
    "database": { "@ref": "databases/production" },
    "data": { "name": "production" },
    "priority": 80,
    "hashed_secret": "$2a$05$.saZ/E/JSuEEkbIfTU/GN.7iKEBBpBGePtWe/mZyL/rmf4uXeZ5oi"
  }
]

=> [
  {
    "ref": { "@ref": "databases/production" },
    "class": { "@ref": "databases" },
    "ts": 1436375112257866,
    "name": "production",
    "priority": 80
  },
  {
    "ref": { "@ref": "keys/104979509692858368" },
    "class": { "@ref": "keys" },
    "ts": 1436375112257866,
    "role": "server",
    "database": { "@ref": "databases/production" },
    "data": { "name": "production" },
    "priority": 80,
    "hashed_secret": "$2a$05$.saZ/E/JSuEEkbIfTU/GN.7iKEBBpBGePtWe/mZyL/rmf4uXeZ5oi"
  }
]

=> [
  {
    "ref": { "@ref": "databases/production" },
    "class": { "@ref": "databases" },
    "ts": 1436375112257866,
    "name": "production",
    "priority": 80
  },
  {
    "ref": { "@ref": "keys/104979509692858368" },
    "class": { "@ref": "keys" },
    "ts": 1436375112257866,
    "role": "server",
    "database": { "@ref": "databases/production" },
    "data": { "name": "production" },
    "priority": 80,
    "hashed_secret": "$2a$05$.saZ/E/JSuEEkbIfTU/GN.7iKEBBpBGePtWe/mZyL/rmf4uXeZ5oi"
  }
]

=> [
  {
    "ref": { "@ref": "databases/production" },
    "class": { "@ref": "databases" },
    "ts": 1436375112257866,
    "name": "production",
    "priority": 80
  },
  {
    "ref": { "@ref": "keys/104979509692858368" },
    "class": { "@ref": "keys" },
    "ts": 1436375112257866,
    "role": "server",
    "database": { "@ref": "databases/production" },
    "data": { "name": "production" },
    "priority": 80,
    "hashed_secret": "$2a$05$.saZ/E/JSuEEkbIfTU/GN.7iKEBBpBGePtWe/mZyL/rmf4uXeZ5oi"
  }
]

=> [
  {
    "ref": { "@ref": "databases/production" },
    "class": { "@ref": "databases" },
    "ts": 1436375112257866,
    "name": "production",
    "priority": 80
  },
  {
    "ref": { "@ref": "keys/104979509692858368" },
    "class": { "@ref": "keys" },
    "ts": 1436375112257866,
    "role": "server",
    "database": { "@ref": "databases/production" },
    "data": { "name": "production" },
    "priority": 80,
    "hashed_secret": "$2a$05$.saZ/E/JSuEEkbIfTU/GN.7iKEBBpBGePtWe/mZyL/rmf4uXeZ5oi"
  }
]

=> [
  {
    "ref": { "@ref": "databases/production" },
    "class": { "@ref": "databases" },
    "ts": 1436375112257866,
    "name": "production",
    "priority": 80
  },
  {
    "ref": { "@ref": "keys/104979509692858368" },
    "class": { "@ref": "keys" },
    "ts": 1436375112257866,
    "role": "server",
    "database": { "@ref": "databases/production" },
    "data": { "name": "production" },
    "priority": 80,
    "hashed_secret": "$2a$05$.saZ/E/JSuEEkbIfTU/GN.7iKEBBpBGePtWe/mZyL/rmf4uXeZ5oi"
  }
]

=> [
  {
    "ref": { "@ref": "databases/production" },
    "class": { "@ref": "databases" },
    "ts": 1436375112257866,
    "name": "production",
    "priority": 80
  },
  {
    "ref": { "@ref": "keys/104979509692858368" },
    "class": { "@ref": "keys" },
    "ts": 1436375112257866,
    "role": "server",
    "database": { "@ref": "databases/production" },
    "data": { "name": "production" },
    "priority": 80,
    "hashed_secret": "$2a$05$.saZ/E/JSuEEkbIfTU/GN.7iKEBBpBGePtWe/mZyL/rmf4uXeZ5oi"
  }
]

Conclusion

In this tutorial we walked through using FaunaDB’s QoS system to allow competing workloads access to the same, live data. We also adjusted priorities based on changing workload requirements. This ability eliminates the need to maintain a separate, out-of-date, system for analytics.