April 18, 2023

Introducing the Fermyon Cloud Key Value Store

The Fermyon Team

spin wasm webassembly cloud serverless

Introducing the Fermyon Cloud Key Value Store

We are excited to introduce the Fermyon Cloud Key Value Store.

Fermyon Cloud is a fully managed cloud platform for running serverless applications built with WebAssembly. With the introduction of the Fermyon Cloud Key Value Store, you can now persist non-relational data in a key/value store managed by Fermyon Cloud that is always available for your serverless application within milliseconds, with no cold starts.

The Fermyon Cloud Key Value Store is an implementation of Spin’s key/value API, which means you can deploy Spin apps that use key/value data to Fermyon Cloud without changing anything about your application!

Serverless, State, Spin

Serverless workloads often rely on external services to persist state beyond the lifespan of a single request — and Spin lets you use databases you manage (like Redis, PostgreSQL, or MySQL).

Since the launch of Spin and Fermyon Cloud, the most common piece of feedback has been around extending the ease of use and simplicity of Spin to data persistence needs. In particular, our users shared that:

  • having to manage external, stateful data services to use from Spin apps introduces additional infrastructure and operational overhead
  • changes in configuration and code between environments often introduce friction between local development and deploying to production

The Spin key/value API and the Fermyon Cloud Key Value Store address these pain points.

Spin has a general-purpose interface for handling non-relational data (based on the WASI key/value proposal), together with a configurable “default” store that is always available when running your Spin application.

Use the Spin SDK in the language of choice, and by default, when running locally, Spin will persist that data in a SQLite database; alternatively, you can configure your own Redis instance at runtime.

The Fermyon Cloud Key Value Store

When you deploy an application that uses this API to Fermyon Cloud, your data will be stored using the new Key Value Store that is managed by Fermyon Cloud, with no extra configuration or code changes!

You can use the Fermyon Cloud Key Value Store to persist any value (such as serialized application state, JSON data, or your own binary format) that would benefit from an eventual consistency model. And because the contents of the store is encrypted, you can also store access tokens or database connection strings.

Using the Fermyon Cloud Key Value Store

As we started using the Key Value Store internally, we quickly identified the need to visualize and interact with the contents of the store, regardless of where you are running your application. This is why we created a new component template, kv-explorer, which is a regular Spin WebAssembly component!

Let’s explore how to build and deploy an application that uses this new store. First, we install the template from GitHub, then create a new application based on the new template:

# the KV explorer is a Spin template
$ spin templates install --git https://github.com/radu-matei/spin-kv-explorer --update
$ spin new kv-explorer kv-spin-app
$ cd kv-spin-app

If we inspect the spin.toml , we’ll see that our components have been granted access to the key/value stored created by Spin named default:

spin_version = "1"
name = "kv-spin-app"
trigger = { type = "http", base = "/" }
version = "0.1.0"

[[component]]
source = { url = "https://github.com/radu-matei/spin-kv-explorer/releases/download/v0.8.0/spin-kv-explorer.wasm", digest = "sha256:aaa" }
id = "kv-explorer"
key_value_stores = ["default"]
[component.trigger]
route = "/internal/kv-explorer/..."

The explorer has a built-in basic authentication mechanism, so you can set your credentials when deploying the application to Fermyon Cloud — you can use the --key-value key=value flag to pre-seed pairs in the store at deployment time:

# provide your own credentials for the KV store explorer
$ export KV_CREDENTIALS="user:password"
$ spin deploy --key-value kv-credentials=$KV_CREDENTIALS
Uploading kv-spin-app version 0.1.0+re301410...
Deploying...
Waiting for application to become ready....... ready
Available Routes:
  kv-explorer: https://kv-spin-app-xxx.fermyon.app/internal/kv-explorer (wildcard)

Tip: Fermyon Cloud only supports the default Key Value Store at this time.

After accessing the URL and entering the credentials, you can now interact with the Key Value Store of your application! You can see all keys, retrieve, set, and delete pairs. Let’s add a new pair:

Adding a new key/value pair

This pair is now persisted and is always available across requests for your application.

Now let’s build a new component in TypeScript that uses the Spin SDK to persist data.

You can find the complete example on GitHub

$ spin add http-ts counter

The above command creates a new counter component in the application’s spin.toml file. This new counter component will also need access to the default key/value store, and therefore we will need to paste in the key_value_stores configuration; as demonstrated below:

[[component]]
id = "counter"
source = "counter/target/spin-http-js.wasm"
key_value_stores = ["default"]
[component.trigger]
route = "/..."
[component.build]
command = "npm run build"
workdir = "counter"

With the new component created (and given explicit permission to access the application’s default key/value data store) let’s go ahead and implement the counter in the source code:

$ cd counter

Using the Spin SDK for JavaScript and TypeScript, we can interact with the default store — below is a complete example of a component (source code for the counter application’s src/index.ts file) that increments a counter:

import { HttpRequest } from "@fermyon/spin-sdk"

const key = "executionCount";

interface Data {
  count: number,
}

export async function handler(_req:HttpRequest, res:ResponseBuilder) {
  // open the default key/value store
	let kv = spinSdk.kv.openDefault();

  // retrieve the data from the key/value store
  let data: Data;
  if (kv.exists(key)) {
    data = JSON.parse(new TextDecoder().decode(kv.get(key)))
  } else {
    data = { count: 0 };
  }

  // increment the counter and set the new value
  data.count += 1;
  kv.set(key, JSON.stringify(data));

  // return the the HTTP response
  res.status(200).body(`Count is: ${data.count}`)
}

Please note: The technical documentation has more information about managing plugins. For example, how to install js2wasm, which we use here for this key/value application.

With version 0.4.0 of the js2wasm plugin installed and the above source code in place, we can go ahead and build the application locally. The application uses the local built-in implementation of Spin’s key/value API:

$ npm install
# Change the directory back to where the spin.toml file is
$ cd ../
$ spin build --up
Executing the build command for component counter: npm run build
Successfully ran the build command for the Spin components.

Logging component stdio to ".spin/logs/"
Storing key-value data to ".spin/sqlite_key_value.db"

Serving http://127.0.0.1:3000
Available Routes:
  kv-explorer: http://127.0.0.1:3000/internal/kv-explorer (wildcard)
  counter: http://127.0.0.1:3000 (wildcard)

We can test the counter by sending requests to the application’s counter route at http://127.0.0.1:3000:

$ curl http://127.0.0.1:3000
Count is: 1

$ curl http://127.0.0.1:3000
Count is: 2

Now we’re ready to deploy to Fermyon Cloud — and there are no changes required:

$ spin deploy
Uploading kv-spin-app version 0.1.0+ra13476e...
Deploying...
Waiting for application to become ready......... ready
Available Routes:
  kv-explorer: https://kv-spin-app-xxx.fermyon.app/internal/kv-explorer (wildcard)
  counter: https://kv-spin-app-xxx.fermyon.app (wildcard)

Navigating to the Fermyon Cloud dashboard, we can see the application was successfully deployed:

Application deployed to Fermyon Cloud

Again, we can now test the counter, except this time we see that the value in the Fermyon Cloud Key Value Store is incremented as expected:

$ curl https://kv-spin-app-xxx.fermyon.app
Count is: 1
$ curl https://kv-spin-app-xxx.fermyon.app
Count is: 2
$ curl https://kv-spin-app-xxx.fermyon.app
Count is: 3
$ curl https://kv-spin-app-xxx.fermyon.app
Count is: 4

Navigating to the kv-explorer endpoint, we can see the value of the executionCount key:

Execution count

Quotas and Limits

This is the initial preview of the Fermyon Cloud Key Value Store.

As we preview and learn more about supporting this feature in the cloud, our service limits for key/value have been defined to the following; for now:

  • maximum key size: 255 bytes
  • maximum value size: 1 MB
  • maximum number of keys: 1024
  • 1 store per Spin application

Limitations:

  • Fermyon Cloud only supports default as the Key Value Store name at this time

Summary

We can’t wait to hear what you build on Fermyon Cloud using the Key Value Store! Feel free to share what you’re working on in our Discord community. We’re more than happy to chat about all things Spin and Fermyon Cloud. To provide feedback on the feature, leave us suggestions, or file a bug please reach out on our Feedback repository.


🔥 Recommended Posts


Quickstart Your Serveless Apps with Spin

Get Started