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

# notifyOn Filtering over WebSocket

> Skip no-op account updates in LaserStream WebSocket streams with the notifyOn option on accountSubscribe and programSubscribe — get notified only when a transaction actually writes to an account.

The `notifyOn` option on the [`accountSubscribe`](/docs/api-reference/rpc/websocket/accountsubscribe) and [`programSubscribe`](/docs/api-reference/rpc/websocket/programsubscribe) WebSocket methods lets a subscription skip updates for accounts that a transaction **write-locked but never wrote to**. The same filter is available over gRPC — see [notifyOn Filtering](/docs/laserstream/notify-on-filtering) for the gRPC version.

## The problem: write locks generate duplicate updates

On Solana, the validator emits an account update for every account a transaction write-locks — even when no instruction actually wrote to the account, so its lamports and data are unchanged. For busy accounts, that means a steady stream of duplicate "nothing changed" notifications that consume bandwidth without carrying new information.

## Filter modes

`notifyOn` takes one of two string values:

| Value     | Sends a notification when                                             | Use it for                                                                        |
| --------- | --------------------------------------------------------------------- | --------------------------------------------------------------------------------- |
| `"lock"`  | A transaction write-locks the account, whether or not it writes to it | The default — full visibility, including accounts merely touched by a transaction |
| `"write"` | A transaction actually writes to the account                          | Cutting no-op noise — most consumers lose nothing                                 |

Two details worth knowing:

* A write of **identical data still counts as a write** and is delivered. `write` filters out lock-only touches, not writes that happen to leave the same bytes. In practice these identical-data writes are rare — under 5% of updates in most cases.
* The updates `write` drops are exact duplicates of state you already received. If you rely on notifications as a "this account was locked by a transaction" signal (e.g., activity tracking), stay on `lock`.

Subscriptions that omit the field behave exactly as before, so it's safe to add to an existing subscription.

## Use it in `accountSubscribe`

Add `notifyOn` to the config object:

```javascript theme={"system"}
const ws = new WebSocket('wss://mainnet.helius-rpc.com/?api-key=<API_KEY>');

ws.on('open', () => {
  ws.send(JSON.stringify({
    jsonrpc: '2.0',
    id: 1,
    method: 'accountSubscribe',
    params: [
      '<ACCOUNT_PUBKEY>',
      {
        encoding: 'jsonParsed',
        commitment: 'confirmed',
        notifyOn: 'write' // skip no-op updates
      }
    ]
  }));
  setInterval(() => ws.ping(), 30_000);
});

ws.on('message', (data) => {
  const msg = JSON.parse(data.toString());
  if (msg.params?.result) console.log(msg.params.result);
});
```

## Use it in `programSubscribe`

The same key works in the `programSubscribe` config object, filtering no-op updates across every account the program owns:

```javascript theme={"system"}
ws.send(JSON.stringify({
  jsonrpc: '2.0',
  id: 1,
  method: 'programSubscribe',
  params: [
    '<PROGRAM_ID>',
    {
      encoding: 'jsonParsed',
      commitment: 'confirmed',
      filters: [{ dataSize: 165 }],
      notifyOn: 'write' // skip no-op updates
    }
  ]
}));
```

Parsing is fail-open: only `"write"` (case-insensitive) opts in. Anything else — absent, a typo, an unknown token — resolves to `lock`, so a mistake keeps you on the all-updates path instead of erroring or silently dropping data.

## Related

<CardGroup cols={2}>
  <Card title="accountSubscribe" icon="bolt" href="/docs/api-reference/rpc/websocket/accountsubscribe">
    Full `accountSubscribe` method reference, including `notifyOn`.
  </Card>

  <Card title="programSubscribe" icon="code" href="/docs/api-reference/rpc/websocket/programsubscribe">
    Full `programSubscribe` method reference, including `notifyOn`.
  </Card>

  <Card title="notifyOn Filtering (gRPC)" icon="filter" href="/docs/laserstream/notify-on-filtering">
    The same filter on LaserStream gRPC accounts filters.
  </Card>

  <Card title="How to Use accountSubscribe" icon="wallet" href="/docs/rpc/websocket/account-subscribe">
    Guide to streaming account updates over WebSocket.
  </Card>
</CardGroup>
