Skip to main content

Subscriptions

danger

RAM usage of subscriptions scales poorly under high load, making the feature unsuitable for most production uses. There are currently no plans to fix this issue.

OpenReader supports GraphQL subscriptions via live queries. To use these, a client opens a websocket connection to the server and sends a subscription query there. The query body is then repeatedly executed (every 5 seconds by default) and the results are sent to the client whenever they change.

To enable subscriptions, add the additional --subscriptions flag to the squid-graphql-server startup command. The poll interval is configured with the --subscription-poll-interval flag. For details and a full list of available options, run

npx squid-graphql-server --help

For each entity types, the following queries are supported for subscriptions:

  • ${EntityName}ById -- query a single entity
  • ${EntityName}s -- query multiple entities with a where filter Note that despite being deprecated from the regular query set, ${EntityName}s queries will continue to be available for subscriptions going forward.

Local runs

To enable subscriptions, add the --subscriptions flag to serve and serve:prod commands at commands.json:

commands.json
...
"serve": {
"description": "Start the GraphQL API server",
"cmd": ["squid-graphql-server", "--subscriptions"]
},
"serve:prod": {
"description": "Start the GraphQL API server in prod",
"cmd": ["squid-graphql-server", "--subscriptions", "--dumb-cache", "in-memory"]
},
...

A ws endpoint will be available the usual localhost:<GQL_PORT>/graphql URL.

SQD Cloud deployments

For SQD Cloud deployments, make sure to use the updated serve:prod command in the deployment manifest:

squid.yaml
# ...
deploy:
# other services ...
api:
cmd: [ "sqd", "serve:prod" ]

The subscription wss endpoint will be available at the canonical API endpoint wss://{org}.subsquid.io/{name}/v/v{version}/graphql.

Example

Let's take the following simple schema with account and transfer entities:

type Account @entity {
"Account address"
id: ID!
transfersTo: [Transfer!] @derivedFrom(field: "to")
transfersFrom: [Transfer!] @derivedFrom(field: "from")
}

type Transfer @entity {
id: ID!
timestamp: DateTime! @index
from: Account!
to: Account!
amount: BigInt! @index
}

After modifying commands.json start the GraphQL server with subscriptions with

npx squid-graphql-server

The following sample script will subscribe to the most recent transfers (by timestamp).

const WebSocket = require('ws')
const { createClient } = require('graphql-ws');

const port = process.env.GQL_PORT || 4350
const host = process.env.GQL_HOST || 'localhost'
const proto = process.env.GQL_PROTO || 'ws'


const client = createClient({
webSocketImpl: WebSocket,
url: `${proto}://${host}:${port}/graphql`,
});

client.subscribe(
{
query: `
subscription {
transfers(limit: 5, orderBy: timestamp_DESC) {
amount
blockNumber
from {
id
}
to {
id
}
}
}
`,
},
{
next: (data) => {
console.log(`New transfers: ${JSON.stringify(data)}`);
},
error: (error) => {
console.error('error', error);
},
complete: () => {
console.log('done!');
},
}
);