> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sqd.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Subscriptions

> Push real-time entity updates over a websocket in OpenReader subscriptions — Squid SDK GraphQL subscriptions for live API consumers.

<Warning>
  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.
</Warning>

OpenReader supports [GraphQL subscriptions](https://www.apollographql.com/docs/react/data/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

```bash theme={"system"}
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](/en/sdk/squid-sdk/reference/openreader-server/overview#supported-queries) 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`](/en/sdk/squid-sdk/squid-cli/commands-json):

```json title="commands.json" theme={"system"}
...
  "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](/en/cloud/reference/manifest#deploy):

```yaml title="squid.yaml" theme={"system"}
# ...
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:

```graphql file=schema.graphql theme={"system"}
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

```bash theme={"system"}
npx squid-graphql-server
```

The following sample [script](https://github.com/subsquid/squid-substrate-template/blob/main/scripts/sub-client.js) will subscribe to the most recent transfers (by `timestamp`).

```typescript theme={"system"}
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!');
    },
  }
);
```
