GraphQL counter

Problem

You want to increment a counter via a GraphQL query.

Fauna provides consistent results that are globally replicated. High-volume counter updates to a single document (as shown in this solution) create contention that can slow down your queries.

We recommend alternatives such as:

  • batch your counter updates (multiple updates per query)

  • avoid counter updates faster than once or twice per second

Solution

There are several steps:

  1. Update your GraphQL schema to include:

    graphqlCopied!
    type Counter {
      counter: Int!
    }
    
    type Query {
      nextCounter: Counter! @resolver(name: "increment_counter")
    }

    This involves editing the GraphQL schema definition, wherever you have stored it, and then uploading the new schema in the Fauna Dashboard.

  2. Create a UDF to perform the counter increment:

    Copied!
    ({
      name: "increment_counter",
      body: (
        (
          [],
          (
            {
              counterRef: (("Counter"), "1"),
              counter: (("counterRef")),
              counterValue: (["data", "counter"], ("counter"))
            },
            (
              ("counterRef"),
              {
                data: {
                  counter: (("counterValue"), 1)
                }
              }
            )
          )
        )
      )
    })
    {
      ref: ("increment_counter"),
      ts: 1626466930320000,
      name: 'increment_counter',
      body: (([], ({"counterRef": (("Counter"), "1"), "counter": (("counterRef")), "counterValue": (["data", "counter"], ("counter"))}, (("counterRef"), {"data": {"counter": (("counterValue"), 1)}}))))
    }
    Query metrics:
    •    bytesIn:  401

    •   bytesOut:  501

    • computeOps:    1

    •    readOps:    0

    •   writeOps:    1

    •  readBytes:   30

    • writeBytes:  593

    •  queryTime: 22ms

    •    retries:    0

  3. Create the required Counter document:

    Copied!
    (
      (("Counter"), "1"),
      { data: { counter: 0 } }
    )
    {
      ref: (("Counter"), "1"),
      ts: 1626466931300000,
      data: { counter: 0 }
    }
    Query metrics:
    •    bytesIn:  106

    •   bytesOut:  165

    • computeOps:    1

    •    readOps:    0

    •   writeOps:    1

    •  readBytes:   14

    • writeBytes:  194

    •  queryTime: 42ms

    •    retries:    0

    Here, we have set the initial counter value to 0.

  4. Run a GraphQL query to increment the counter:

    graphqlCopied!
    {
      nextCounter {
        counter
      }
    }

    You should see the result:

    {
      "data": {
        "nextCounter": {
          "counter": 1
        }
      }
    }
  5. You can also increment the counter in FQL queries:

    Copied!
    ("increment_counter")
    {
      ref: (("Counter"), "1"),
      ts: 1626466932180000,
      data: { counter: 1 }
    }
    Query metrics:
    •    bytesIn:   43

    •   bytesOut:  165

    • computeOps:    1

    •    readOps:    1

    •   writeOps:    1

    •  readBytes:   58

    • writeBytes:   85

    •  queryTime: 29ms

    •    retries:    0

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!