mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-12-14 17:02:49 +03:00
docs: subscription observability and performance
PR-URL: https://github.com/hasura/graphql-engine-mono/pull/9254 GitOrigin-RevId: 464ae1c7b67ff8bcacdea899d2612d57ad8bf443
This commit is contained in:
parent
e7f0a521b8
commit
3e3e73b81f
@ -573,7 +573,7 @@ If both JWT Secret and JWT Secrets are set, then JWT Secrets will be used.
|
||||
|
||||
When utilizing live queries, updated results - if any - will be sent, at most, once during this interval - measured in
|
||||
milliseconds - for any
|
||||
[live queries which can be multiplexed](/subscriptions/postgres/livequery/execution-and-performance.mdx#parameters).
|
||||
[live queries which can be multiplexed](/subscriptions/observability-and-performance.mdx#parameters).
|
||||
|
||||
| | |
|
||||
| ------------------- | -------------------------------------------------------------- |
|
||||
|
@ -55,45 +55,15 @@ than 10000).
|
||||
|
||||
The following metrics are exported by Hasura GraphQL Engine:
|
||||
|
||||
### Hasura active subscriptions
|
||||
### Subscription Metrics
|
||||
|
||||
Current number of active subscriptions, representing the subscription load on the server.
|
||||
The following metrics can be used to monitor the performance of subscriptions:
|
||||
|
||||
| | |
|
||||
| ------ | ------------------------------------------------------------------------------------------ |
|
||||
| Name | `hasura_active_subscriptions` |
|
||||
| Type | Gauge |
|
||||
| Labels | `subscription_kind`: streaming \| live-query, `operation_name`, `parameterized_query_hash` |
|
||||
|
||||
### Hasura active subscription pollers
|
||||
|
||||
Current number of active subscription pollers. A subscription poller
|
||||
[multiplexes](https://github.com/hasura/graphql-engine/blob/master/architecture/live-queries.md#idea-3-batch-multiple-live-queries-into-one-sql-query)
|
||||
similar subscriptions together. The value of this metric should be proportional to the number of uniquely parameterized
|
||||
subscriptions (i.e., subscriptions with the same selection set, but with different input arguments and session variables
|
||||
are multiplexed on the same poller). If this metric is high then it may be an indication that there are too many
|
||||
uniquely parameterized subscriptions which could be optimized for better performance.
|
||||
|
||||
| | |
|
||||
| ------ | -------------------------------------------- |
|
||||
| Name | `hasura_active_subscription_pollers` |
|
||||
| Type | Gauge |
|
||||
| Labels | `subscription_kind`: streaming \| live-query |
|
||||
|
||||
### Hasura active subscription pollers in error state
|
||||
|
||||
Current number of active subscription pollers that are in the error state. A subscription poller
|
||||
[multiplexes](https://github.com/hasura/graphql-engine/blob/master/architecture/live-queries.md#idea-3-batch-multiple-live-queries-into-one-sql-query)
|
||||
similar subscriptions together. A non-zero value of this metric indicates that there are runtime errors in atleast one
|
||||
of the subscription pollers that are running in Hasura. In most of the cases, runtime errors in subscriptions are caused
|
||||
due to the changes at the data model layer and fixing the issue at the data model layer should automatically fix the
|
||||
runtime errors.
|
||||
|
||||
| | |
|
||||
| ------ | --------------------------------------------------- |
|
||||
| Name | `hasura_active_subscription_pollers_in_error_state` |
|
||||
| Type | Gauge |
|
||||
| Labels | `subscription_kind`: streaming \| live-query |
|
||||
- [`hasura_active_subscriptions`](/subscriptions/observability-and-performance.mdx#active-subscriptions)
|
||||
- [`hasura_active_subscription_pollers`](/subscriptions/observability-and-performance.mdx#active-subscription-pollers)
|
||||
- [`hasura_active_subscription_pollers_in_error_state`](/subscriptions/observability-and-performance.mdx#active-subscription-pollers-in-error-state)
|
||||
- [`hasura_subscription_db_execution_time_seconds`](/subscriptions/observability-and-performance.mdx#subscription-database-execution-time)
|
||||
- [`hasura_subscription_total_time_seconds`](/subscriptions/observability-and-performance.mdx#subscription-total-time)
|
||||
|
||||
### Hasura cache request count
|
||||
|
||||
@ -226,7 +196,7 @@ buckets, you should consider [tuning the performance](/deployment/performance-tu
|
||||
| ------ | -------------------------------------------------------------- |
|
||||
| Name | `hasura_graphql_execution_time_seconds` |
|
||||
| Type | Histogram<br /><br />Buckets: 0.01, 0.03, 0.1, 0.3, 1, 3, 10 |
|
||||
| Labels | `operation_type`: query \| mutation \| subscription \| unknown |
|
||||
| Labels | `operation_type`: query \| mutation |
|
||||
|
||||
### Hasura GraphQL requests total
|
||||
|
||||
@ -297,75 +267,6 @@ for details.
|
||||
| Type | Gauge |
|
||||
| Labels | `source_name`: name of the database |
|
||||
|
||||
### Hasura subscription database execution time
|
||||
|
||||
The time taken to run the subscription's multiplexed query in the database for a single batch.
|
||||
|
||||
A subscription poller
|
||||
[multiplexes](https://github.com/hasura/graphql-engine/blob/master/architecture/live-queries.md#idea-3-batch-multiple-live-queries-into-one-sql-query)
|
||||
similar subscriptions together. During every run (every 1 second by default), the poller splits the different variables
|
||||
for the multiplexed query into batches (by default 100) and execute the batches. This metric observes the time taken for
|
||||
each batch to execute on the database.
|
||||
|
||||
If this metric is high, then it may be an indication that the database is not performing as expected, you should
|
||||
consider investigating the subscription query and see if indexes can help improve performance.
|
||||
|
||||
| | |
|
||||
| ------ | ------------------------------------------------------------------------------------------ |
|
||||
| Name | `hasura_subscription_db_execution_time_seconds` |
|
||||
| Type | Histogram<br /><br />Buckets: 0.000001, 0.0001, 0.01, 0.1, 0.3, 1, 3, 10, 30, 100 |
|
||||
| Labels | `subscription_kind`: streaming \| live-query, `operation_name`, `parameterized_query_hash` |
|
||||
|
||||
### Hasura subscription total time
|
||||
|
||||
The time taken to complete running of one subscription poller.
|
||||
|
||||
A subscription poller
|
||||
[multiplexes](https://github.com/hasura/graphql-engine/blob/master/architecture/live-queries.md#idea-3-batch-multiple-live-queries-into-one-sql-query)
|
||||
similar subscriptions together. This subscription poller runs every 1 second by default and queries the database with
|
||||
the multiplexed query to fetch the latest data. In a polling instance, the poller not only queries the database but does
|
||||
other operations like splitting similar queries into batches (by default 100) before fetching their data from the
|
||||
database, etc. **This metric is the total time taken to complete all the operations in a single poll.**
|
||||
|
||||
If the value of this metric is high, then it may be an indication that the multiplexed query is taking longer to execute
|
||||
in the database, verify with
|
||||
[`hasura_subscription_db_execution_time_seconds`](/enterprise/metrics.mdx/#hasura-subscription-database-execution-time)
|
||||
metric.
|
||||
|
||||
In a single poll, the subscription poller splits the different variables for the multiplexed query into batches (by
|
||||
default 100) and executes the batches. We use the `hasura_subscription_db_execution_time_seconds` metric to observe the
|
||||
time taken for each batch to execute on the database. This means for a single poll there can be multiple values for
|
||||
`hasura_subscription_db_execution_time_seconds` metric.
|
||||
|
||||
Let's look at an example to understand these metrics better:
|
||||
|
||||
Say we have 650 subscriptions with the same selection set but different input arguments. These 650 subscriptions will be
|
||||
grouped to form one multiplexed query. A single poller would be created to run this multiplexed query. This poller will
|
||||
run every 1 second.
|
||||
|
||||
The default batch size in hasura is 100, so the 650 subscriptions will be split into 7 batches for execution during a
|
||||
single poll.
|
||||
|
||||
During a single poll:
|
||||
|
||||
- Batch 1: `hasura_subscription_db_execution_time_seconds` = 0.002 seconds
|
||||
- Batch 2: `hasura_subscription_db_execution_time_seconds` = 0.001 seconds
|
||||
- Batch 3: `hasura_subscription_db_execution_time_seconds` = 0.003 seconds
|
||||
- Batch 4: `hasura_subscription_db_execution_time_seconds` = 0.001 seconds
|
||||
- Batch 5: `hasura_subscription_db_execution_time_seconds` = 0.002 seconds
|
||||
- Batch 6: `hasura_subscription_db_execution_time_seconds` = 0.001 seconds
|
||||
- Batch 7: `hasura_subscription_db_execution_time_seconds` = 0.002 seconds
|
||||
|
||||
The `hasura_subscription_total_time_seconds` would be sum of all the database execution times shown in the batches, plus
|
||||
some extra process time for other tasks the poller does during a single poll. In this case, it would be approximately
|
||||
0.013 seconds.
|
||||
|
||||
| | |
|
||||
| ------ | ------------------------------------------------------------------------------------------ |
|
||||
| Name | `hasura_subscription_total_time_seconds` |
|
||||
| Type | Histogram<br /><br />Buckets: 0.000001, 0.0001, 0.01, 0.1, 0.3, 1, 3, 10, 30, 100 |
|
||||
| Labels | `subscription_kind`: streaming \| live-query, `operation_name`, `parameterized_query_hash` |
|
||||
|
||||
### Hasura WebSocket connections
|
||||
|
||||
Current number of active WebSocket connections, representing the WebSocket load on the server.
|
||||
|
@ -1,4 +1,4 @@
|
||||
{
|
||||
"label": "MS SQL Server",
|
||||
"position": 4
|
||||
"position": 5
|
||||
}
|
||||
|
260
docs/docs/subscriptions/observability-and-performance.mdx
Normal file
260
docs/docs/subscriptions/observability-and-performance.mdx
Normal file
@ -0,0 +1,260 @@
|
||||
---
|
||||
description: Observability & Performance Tuning
|
||||
title: Observability & Performance Tuning
|
||||
keywords:
|
||||
- hasura
|
||||
- docs
|
||||
- subscriptions
|
||||
- observability
|
||||
- prometheus
|
||||
- metrics
|
||||
- performance
|
||||
- tuning
|
||||
|
||||
sidebar_label: Observability & Performance
|
||||
sidebar_position: 6
|
||||
---
|
||||
|
||||
import Thumbnail from '@site/src/components/Thumbnail';
|
||||
import ProductBadge from '@site/src/components/ProductBadge';
|
||||
|
||||
## Subscription Execution
|
||||
For serving subscription requests, Hasura optimizes the subscription execution to ensure it is as fast as possible while
|
||||
not overloading the database with concurrent queries.
|
||||
|
||||
To achieve this, Hasura uses a combination of the following techniques:
|
||||
- **Grouping same queries into "cohorts" **: Hasura groups subscriptions with the same set of query and session
|
||||
variables into a single cohort. The subscribers in a cohort are updated simultaneously.
|
||||
- **Diff-checking**: On receiving response from the database, Hasura checks the diff between the old and new values
|
||||
and sends the response only to the subscribers whose values have changed.
|
||||
- **Multiplexing**: Hasura groups similar "parameterized" subscriptions together and additionally splits them into
|
||||
batches for efficient performance on the database. The batch size can be configured using the
|
||||
[`HASURA_GRAPHQL_LIVE_QUERIES_MULTIPLEXED_BATCH_SIZE`](deployment/graphql-engine-flags/reference.mdx#multiplexed-batch-size)
|
||||
environment variable. You can read more about multiplexing
|
||||
[here](subscriptions/postgres/livequery/execution.mdx#subscription-multiplexing). For example, in the image below, we
|
||||
are grouping the three subscriptions into a single multiplexed query.
|
||||
|
||||
<Thumbnail
|
||||
src='/img/databases/postgres/subscriptions/subscription-multiplexing.png'
|
||||
alt='Hasura subscription multiplexing AST'
|
||||
width='900px'
|
||||
className='no-shadow'
|
||||
/>
|
||||
|
||||
For more details on how Hasura executes subscriptions, refer to the [live
|
||||
query](/subscriptions/postgres/livequery/execution.mdx) or [streaming
|
||||
subscription](/subscriptions/postgres/streaming/index.mdx) documentation.
|
||||
|
||||
## Observability
|
||||
|
||||
<ProductBadge self />
|
||||
|
||||
Hasura exposes a set of Prometheus Metrics that can be used to monitor the subscriptions system and help diagnose
|
||||
performance issues.
|
||||
|
||||
### Active Subscriptions
|
||||
|
||||
Current number of active subscriptions, representing the subscription load on the server.
|
||||
|
||||
| | |
|
||||
| ------ | ------------------------------------------------------------------------------------------ |
|
||||
| Name | `hasura_active_subscriptions` |
|
||||
| Type | Gauge |
|
||||
| Labels | `subscription_kind`: streaming \| live-query, `operation_name`, `parameterized_query_hash` |
|
||||
|
||||
### Active Subscription Pollers
|
||||
|
||||
Current number of active subscription pollers. A subscription poller
|
||||
[multiplexes](https://github.com/hasura/graphql-engine/blob/master/architecture/live-queries.md#idea-3-batch-multiple-live-queries-into-one-sql-query)
|
||||
similar subscriptions together. The value of this metric should be proportional to the number of uniquely parameterized
|
||||
subscriptions (i.e., subscriptions with the same selection set, but with different input arguments and session variables
|
||||
are multiplexed on the same poller). If this metric is high then it may be an indication that there are too many
|
||||
uniquely parameterized subscriptions which could be optimized for better performance.
|
||||
|
||||
| | |
|
||||
| ------ | -------------------------------------------- |
|
||||
| Name | `hasura_active_subscription_pollers` |
|
||||
| Type | Gauge |
|
||||
| Labels | `subscription_kind`: streaming \| live-query |
|
||||
|
||||
### Active Subscription Pollers in Error State
|
||||
|
||||
Current number of active subscription pollers that are in the error state. A subscription poller
|
||||
[multiplexes](https://github.com/hasura/graphql-engine/blob/master/architecture/live-queries.md#idea-3-batch-multiple-live-queries-into-one-sql-query)
|
||||
similar subscriptions together. A non-zero value of this metric indicates that there are runtime errors in atleast one
|
||||
of the subscription pollers that are running in Hasura. In most of the cases, runtime errors in subscriptions are caused
|
||||
due to the changes at the data model layer and fixing the issue at the data model layer should automatically fix the
|
||||
runtime errors.
|
||||
|
||||
| | |
|
||||
| ------ | --------------------------------------------------- |
|
||||
| Name | `hasura_active_subscription_pollers_in_error_state` |
|
||||
| Type | Gauge |
|
||||
| Labels | `subscription_kind`: streaming \| live-query |
|
||||
|
||||
### Subscription Total Time
|
||||
|
||||
The time taken to complete running of one subscription poller.
|
||||
|
||||
A subscription poller
|
||||
[multiplexes](https://github.com/hasura/graphql-engine/blob/master/architecture/live-queries.md#idea-3-batch-multiple-live-queries-into-one-sql-query)
|
||||
similar subscriptions together. This subscription poller runs every 1 second by default and queries the database with
|
||||
the multiplexed query to fetch the latest data. In a polling instance, the poller not only queries the database but does
|
||||
other operations like splitting similar queries into batches (by default 100) before fetching their data from the
|
||||
database, etc. **This metric is the total time taken to complete all the operations in a single poll.**
|
||||
|
||||
In a single poll, the subscription poller splits the different variables for the multiplexed query into batches (by
|
||||
default 100) and executes the batches. We use the `hasura_subscription_db_execution_time_seconds` metric to observe the
|
||||
time taken for each batch to execute on the database. This means for a single poll there can be multiple values for
|
||||
`hasura_subscription_db_execution_time_seconds` metric.
|
||||
|
||||
Let's look at an example to understand these metrics better:
|
||||
|
||||
Say we have 650 subscriptions with the same selection set but different input arguments. These 650 subscriptions will be
|
||||
grouped to form one multiplexed query. A single poller would be created to run this multiplexed query. This poller will
|
||||
run every 1 second.
|
||||
|
||||
The default batch size in hasura is 100, so the 650 subscriptions will be split into 7 batches for execution during a
|
||||
single poll.
|
||||
|
||||
During a single poll:
|
||||
|
||||
- Batch 1: `hasura_subscription_db_execution_time_seconds` = 0.002 seconds
|
||||
- Batch 2: `hasura_subscription_db_execution_time_seconds` = 0.001 seconds
|
||||
- Batch 3: `hasura_subscription_db_execution_time_seconds` = 0.003 seconds
|
||||
- Batch 4: `hasura_subscription_db_execution_time_seconds` = 0.001 seconds
|
||||
- Batch 5: `hasura_subscription_db_execution_time_seconds` = 0.002 seconds
|
||||
- Batch 6: `hasura_subscription_db_execution_time_seconds` = 0.001 seconds
|
||||
- Batch 7: `hasura_subscription_db_execution_time_seconds` = 0.002 seconds
|
||||
|
||||
The `hasura_subscription_total_time_seconds` would be sum of all the database execution times shown in the batches, plus
|
||||
some extra process time for other tasks the poller does during a single poll. In this case, it would be approximately
|
||||
0.013 seconds.
|
||||
|
||||
| | |
|
||||
| ------ | ------------------------------------------------------------------------------------------ |
|
||||
| Name | `hasura_subscription_total_time_seconds` |
|
||||
| Type | Histogram<br /><br />Buckets: 0.000001, 0.0001, 0.01, 0.1, 0.3, 1, 3, 10, 30, 100 |
|
||||
| Labels | `subscription_kind`: streaming \| live-query, `operation_name`, `parameterized_query_hash` |
|
||||
|
||||
|
||||
### Subscription Database Execution Time
|
||||
|
||||
The time taken to run the subscription's multiplexed query in the database for a single batch.
|
||||
|
||||
A subscription poller
|
||||
[multiplexes](https://github.com/hasura/graphql-engine/blob/master/architecture/live-queries.md#idea-3-batch-multiple-live-queries-into-one-sql-query)
|
||||
similar subscriptions together. During every run (every 1 second by default), the poller splits the different variables
|
||||
for the multiplexed query into batches (by default 100) and execute the batches. This metric observes the time taken for
|
||||
each batch to execute on the database.
|
||||
|
||||
If this metric is high, then it may be an indication that the database is not performing as expected, you should
|
||||
consider investigating the subscription query and see if indexes can help improve performance.
|
||||
|
||||
| | |
|
||||
| ------ | ------------------------------------------------------------------------------------------ |
|
||||
| Name | `hasura_subscription_db_execution_time_seconds` |
|
||||
| Type | Histogram<br /><br />Buckets: 0.000001, 0.0001, 0.01, 0.1, 0.3, 1, 3, 10, 30, 100 |
|
||||
| Labels | `subscription_kind`: streaming \| live-query, `operation_name`, `parameterized_query_hash` |
|
||||
|
||||
## Golden Signals for subscriptions
|
||||
|
||||
You can perform [Golden
|
||||
Signals-based](https://sre.google/sre-book/monitoring-distributed-systems/#xref_monitoring_golden-signals) system
|
||||
monitoring with Hasura's exported metrics. The following are the golden signals for subscriptions:
|
||||
|
||||
### Latency
|
||||
|
||||
The latency of a subscription is defined as the time taken to complete one fetch cycle for the subscription. To monitor
|
||||
latency, you can monitor the [`hasura_subscription_total_time_seconds`](#subscription-total-time) metric.
|
||||
|
||||
If the value of this metric is high, then it may be an indication that the multiplexed query is taking longer to execute
|
||||
in the database, verify this with
|
||||
[`hasura_subscription_db_execution_time_seconds`](#subscription-database-execution-time)
|
||||
metric. If the value of this metric is high as well, you can do the following:
|
||||
- Check if any database index can help improve the performance of the query, [analyzing the GraphQL query](#analyze)
|
||||
will show the generated multiplexed query.
|
||||
- Avoid querying unnecessary fields that translate to joins or function calls in the GraphQL query.
|
||||
- Consider adding more read replicas to the database and running subscriptions on them.
|
||||
|
||||
### Traffic
|
||||
|
||||
The traffic of a subscription is defined as the number of subscriptions that are active at any given point of time. To
|
||||
monitor traffic, you can monitor the [`hasura_active_subscriptions`](#active-subscriptions) metric.
|
||||
|
||||
If the value of this metric is high (and above your established baseline), then you may want to consider increasing the
|
||||
number of Hasura instances to handle the load.
|
||||
|
||||
### Errors
|
||||
|
||||
Errors in subscriptions can be monitored using the following metrics
|
||||
- [`hasura_graphql_requests_total{type="subscription",response_status="error"}`](/enterprise/metrics.mdx#hasura-graphql-requests-total):
|
||||
Total number of errors that happen before the subscription is started (i.e. validation, parsing and authorization
|
||||
errors).
|
||||
- [`hasura_active_subscription_pollers_in_error_state`](#active-subscription-pollers-in-error-state): Number of
|
||||
subscription pollers that are in error state.
|
||||
|
||||
If the value of the [`hasura_active_subscription_pollers_in_error_state`](#active-subscription-pollers-in-error-state)
|
||||
is non-zero, you should consider investigating the `livequery-poller-log` logs (this will include the error message) to
|
||||
debug the failing subscription.
|
||||
|
||||
### Saturation
|
||||
|
||||
Saturation is the threshold until which the subscriptions can run smoothly; once this threshold is crossed, you may see
|
||||
performance issues, and abrupt disconnections of the connected subscribers.
|
||||
|
||||
To monitor the saturation for subscriptions, you can monitor the following:
|
||||
- CPU and memory usage of Hasura instances.
|
||||
- For postgres backends, you can monitor the
|
||||
[`hasura_postgres_connections`](/enterprise/metrics.mdx#hasura-postgres-connections) metric to see the number of
|
||||
connections opened by Hasura with the database.
|
||||
- P99 of the [`hasura_subscription_total_time_seconds`](#subscription-total-time) metric.
|
||||
|
||||
If the number of database connections is high, you can consider increasing the `max_connections` of the database.
|
||||
|
||||
You can also consider scaling the Hasura instances horizontally and vertically to handle the load.
|
||||
|
||||
## Tuning subscription performance
|
||||
|
||||
Hasura GraphQL Engine is designed to scale to handle millions of concurrent subscriptions. However, due to
|
||||
misconfigurations or inefficient queries, the performance of subscriptions can be impacted. This section describes how
|
||||
to analyze and tune the performance of subscriptions.
|
||||
|
||||
### Analyze
|
||||
|
||||
Using the `Analyze` button on GraphiQL API Explorer of the Hasura Console, you can see the generated
|
||||
multiplexed SQL and its query plan. The query plan can reveal the bottlenecks in query execution and appropriate indexes
|
||||
can be added to improve performance.
|
||||
|
||||
In addition to these, simplifying the subscription to avoid unnecessary joins or avoiding fetching fields which are not
|
||||
going to change can also help improve performance.
|
||||
|
||||
### Performance tuning
|
||||
|
||||
The parameters governing the performance of subscriptions in terms of throughput, latency and resource utilization are:
|
||||
|
||||
- `HASURA_GRAPHQL_LIVE_QUERIES_MULTIPLEXED_REFETCH_INTERVAL`
|
||||
- Time interval between Hasura multiplexed queries to the DB for fetching changes in subscriptions data, default = 1
|
||||
sec
|
||||
- Increasing this reduces the frequency of queries to the DB, thereby reducing its load and improving throughput
|
||||
while increasing the latency of updates to the clients.
|
||||
- `HASURA_GRAPHQL_LIVE_QUERIES_MULTIPLEXED_BATCH_SIZE`
|
||||
- Number of similar subscriptions batched into a single SQL query to the DB, default = 100
|
||||
- Increasing this reduces the number of SQL statements fired to the DB, thereby reducing its load and improving
|
||||
throughput while increasing individual SQL execution times and latency.
|
||||
- You should reduce this value if the execution time of the SQL generated by Hasura after multiplexing is more
|
||||
than the refetch interval.
|
||||
- `max_connections` of the source
|
||||
- Max number of connections Hasura opens with the DB, default = 50 (configurable via [update source metadata
|
||||
API](api-reference/metadata-api/source.mdx))
|
||||
- Increasing this increases the number of connections Hasura can open with the DB to execute queries, thereby
|
||||
improving concurrency **but adding load to the database**. A very high number of concurrent connections can result in poor
|
||||
DB performance.
|
||||
|
||||
:::info Note
|
||||
|
||||
The default values offer a reasonable trade-off between resource utilization and performance for most use cases. For
|
||||
scenarios with heavy queries and a high number of active subscriptions, you need to benchmark the setup and these
|
||||
parameters need to be iterated upon to achieve optimal performance.
|
||||
|
||||
:::
|
@ -1,4 +1,4 @@
|
||||
{
|
||||
"label": "Postgres",
|
||||
"position": 3
|
||||
"position": 4
|
||||
}
|
||||
|
@ -1,18 +1,18 @@
|
||||
---
|
||||
sidebar_label: Execution and performance
|
||||
sidebar_label: Execution
|
||||
sidebar_position: 2
|
||||
description: Tuning Hasura for High-performance Subscriptions
|
||||
description: Understanding Subscription execution in Hasura
|
||||
keywords:
|
||||
- hasura
|
||||
- docs
|
||||
- subscriptions
|
||||
- performance
|
||||
- tuning
|
||||
- subscription architecture
|
||||
- subscription execution
|
||||
---
|
||||
|
||||
import Thumbnail from '@site/src/components/Thumbnail';
|
||||
|
||||
# Subscriptions Execution and Performance
|
||||
# Subscriptions Execution
|
||||
|
||||
## Introduction
|
||||
|
||||
@ -182,6 +182,8 @@ and
|
||||
}
|
||||
```
|
||||
|
||||
The subscriptions will get multiplexed together because the arguments have the same input object fields.
|
||||
|
||||
:::info Boolean expressions
|
||||
|
||||
If boolean expressions are used as values in subscription queries, they will be multiplexed only if they differ in scalar values.
|
||||
@ -204,9 +206,14 @@ subscription {
|
||||
}
|
||||
```
|
||||
|
||||
Even though identical subscription requests are made, **they are not muliplexed** together because the Hasura role is
|
||||
Even though identical subscription requests are made, **they are not multiplexed** together because the Hasura role is
|
||||
different.
|
||||
|
||||
### Subscription Cohorts
|
||||
|
||||
Hasura Graphql Engine further optimizes subscriptions by grouping same subscriptions into "cohorts". Cohorts are
|
||||
groups of subscriptions that are multiplexed together and share the same session and query variables.
|
||||
|
||||
### Example
|
||||
|
||||
A practical use of subscriptions can be for tracking the live locations of delivery agents carrying food orders in a
|
||||
@ -228,45 +235,19 @@ batched into one SQL:
|
||||
In this case, all 3 subscriptions are multiplexed into 1 batch resulting in 1 SQL query which is run every 1 second. If
|
||||
there is an update in the location, the appropriate client gets sent the updated data.
|
||||
|
||||
## Tuning subscription performance
|
||||
Now, let's say `user1` starts tracking the order on 2 other devices (logged in with same account). So, now there are 3
|
||||
clients subscribed to the exact same subscription (with same session and query variables). These 3 subscriptions will
|
||||
form a [cohort](#subscription-cohorts). The result of the subscription will be sent to all 3 clients using the same part
|
||||
of the SQL response. Thus, adding more clients to the cohort will not increase the database execution time.
|
||||
|
||||
### Analyze
|
||||
:::info Adding new subscribers to existing cohorts
|
||||
|
||||
Subscriptions can be 'Analyzed' (from the Analyze button in GraphiQl window of Hasura Console) to see the generated
|
||||
multiplexed SQL and its query plan. The query plan can reveal the bottlenecks in query execution and appropriate indexes
|
||||
can be added to improve performance.
|
||||
When a new subscriber is added to an existing cohort, the SQL query doesn't change. This optimization helps Hasura to
|
||||
avoid re-fetching the data from the database for the existing subscriptions in the cohort. The new subscriber will get
|
||||
the result of the subscription from the existing SQL response.
|
||||
|
||||
In addition to these, simplifying the subscription to avoid unnecessary joins or avoiding fetching fields which are not
|
||||
going to change can also help improve performance.
|
||||
|
||||
### Parameters
|
||||
|
||||
The parameters governing the performance of subscriptions in terms of throughput, latency and resource utilization are:
|
||||
|
||||
- `HASURA_GRAPHQL_LIVE_QUERIES_MULTIPLEXED_REFETCH_INTERVAL`
|
||||
- Time interval between Hasura multiplexed queries to the DB for fetching changes in subscriptions data, default = 1
|
||||
sec
|
||||
- Increasing this reduces frequency of queries to the DB thereby reducing the load on it and improving throughput
|
||||
while increasing the latency of updates to the clients.
|
||||
- `HASURA_GRAPHQL_LIVE_QUERIES_MULTIPLEXED_BATCH_SIZE`
|
||||
- Number of similar subscriptions batched into a single SQL query to the DB, default = 100
|
||||
- Increasing this reduces the number of SQL statements fired to the DB thereby reducing the load on it and improving
|
||||
throughput while increasing individual SQL execution times and hence latency.
|
||||
- This value should be reduced in case the execution time of the SQL generated by Hasura after multiplexing is more
|
||||
than the refetch interval.
|
||||
- `HASURA_GRAPHQL_PG_CONNECTIONS`
|
||||
- Max number of connection Hasura opens with the DB, default = 50
|
||||
- Increasing this increases the number of connections that can be opened with the DB to execute queries thereby
|
||||
improving concurrency but adding load to the database. Very high number of concurrent connections can result in poor
|
||||
DB performance.
|
||||
|
||||
:::info Note
|
||||
|
||||
- Tuning these parameters have no impact on the resource utilization of Hasura. Hasura's CPU and memory utilization
|
||||
depends on the number of requests being served.
|
||||
- For most use cases, the default values offer reasonable trade-off between resource utilization and performance. For
|
||||
scenarios with heavy queries and high number of active subscriptions, the setup needs to be benchmarked and these
|
||||
parameters need to be iterated upon to achieve optimal performance.
|
||||
Due to the above optimization, the database execution time for the SQL query will not increase with the increase in the
|
||||
number of subscribers in the cohort.
|
||||
|
||||
:::
|
||||
|
@ -20,7 +20,7 @@ events leading up to the result.
|
||||
By default, updates are delivered to clients every **1 sec**.
|
||||
|
||||
See more details on
|
||||
[subscriptions execution and performance](/subscriptions/postgres/livequery/execution-and-performance.mdx).
|
||||
[subscriptions execution](/subscriptions/postgres/livequery/execution.mdx).
|
||||
|
||||
## Convert a query to a subscription
|
||||
|
||||
|
@ -33,7 +33,7 @@ is sent exactly once to a subscriber.
|
||||
Streaming subscriptions work well with other Hasura features like
|
||||
[permissions](/auth/authorization/permissions/row-level-permissions.mdx) and
|
||||
[relationships](/schema/postgres/table-relationships/index.mdx#table-relationships) and also leverage the power of
|
||||
[subscriptions multiplexing](/subscriptions/postgres/livequery/execution-and-performance.mdx#subscription-multiplexing).
|
||||
[subscriptions multiplexing](/subscriptions/postgres/livequery/execution.mdx#subscription-multiplexing).
|
||||
|
||||
:::info Note
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user