Skip to content

docs: Hydration details and concepts page - #38168

Open
kay-kim wants to merge 6 commits into
MaterializeInc:mainfrom
kay-kim:docs-hydration-updates
Open

docs: Hydration details and concepts page#38168
kay-kim wants to merge 6 commits into
MaterializeInc:mainfrom
kay-kim:docs-hydration-updates

Conversation

@kay-kim

@kay-kim kay-kim commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

https://preview.materialize.com/materialize/38168/concepts/hydration/

Part 1 of Hydration content:

  • Added a yaml file to capture the details (including when objects hydrates and the memory usage)
  • Added the concept page for hydration which mostly uses the details from the yaml file.

Once approved and merged, Part 2 will include the approved details in appropriate places.

@kay-kim
kay-kim requested a review from a team as a code owner August 11, 2026 21:09
materialized view (public preview) and replacing the existing view in
place](/transform-data/updating-materialized-views/replace-materialized-view/)
may be simpler, but briefly reduces freshness.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did not include compute_hydration_concurrency as a strategy

Hydration primarily impacts memory usage, and its speed scales with cluster
size. Some hydration-related strategies you may want to consider:

- Add an [`AUTO SCALING STRATEGY (ON HYDRATION)`](/sql/alter-cluster/) to your

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably will move it to the hydration-details.yml later on.

Comment thread doc/user/content/concepts/hydration.md Outdated
then removes it once a steady-size replica catches up. You pay for the burst
replica while it is provisioned, but not at steady state.

- Split materialized views and indexes across multiple clusters. Each cluster

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this! I'd recommend checking out what @tylerhartwig did to shard MVs well. There's a number of strategies you can employ and I think sharing more details would help

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

require a significant amount of CPU and memory.

- During hydration (both initial and subsequent rehydrations), materialized
- During hydration (both initial hydration and subsequent rehydrations), materialized

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure where to put this, but rehydration technically uses more memory! I'll let @antiguru confirm, but my understanding is:

  1. If you create a cluster for a first time with 10 MVs, you'll use X memory
  2. If you restart that cluster and have to rehydrate the 10 MVs, you'll need 2X memory

It might be worth splitting up those concepts and specifying the memory requirements for both

@kay-kim kay-kim Aug 12, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, heh .. I think I clobbered that line where we stated "materialized views require memory proportional to both the input and output." (i.e., your 2X 😄 ) But, will also wait for confirmation.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replaced with the table (with the corrected details) so that the pages are in sync.

@antiguru antiguru left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left some comments.

My main concern is that we're getting less precise about clusters and cluster replicas. Clusters are a collection of cluster replicas, but themselves have no concept of start/stop/(re)hydrate/crash etc. Cluster replicas are the concept that has the life cycle, and represent physical resources. Their properties are immutable. The text in this PR uses clusters and cluster replicas interchangeably, but they're really two distinct concepts. Keeping them separate creates clarity.

I don't think this is specific to this page, as we're causing confusion with the CREATE CLUSTER syntax that papers over this detail.

Comment thread doc/user/content/concepts/hydration.md Outdated
## Objects and hydration

Hydration is per replica. When a trigger above occurs, the objects on the
affected replicas hydrate as described below. A restart re-hydrates a cluster's

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A restart of what? Needs more specific, because only a restart of a replica causes (re)hydration, a environmentd restart causes reconciliation.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do a sweep of this page to be more precise (probably will have the update by early tomorrow morning ... as need to shift attention to a few other tasks today).

Comment on lines +36 to +40
- Add an [`AUTO SCALING STRATEGY (ON HYDRATION)`](/sql/alter-cluster/) to your
cluster. With this strategy, Materialize automatically provisions an extra,
larger replica (a burst replica) while the cluster has un-hydrated objects,
then removes it once a steady-size replica catches up. You pay for the burst
replica while it is provisioned, but not at steady state.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if the stead-size replica is in an OOM loop?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added details for this. resize ... burst will serve (had claude verify)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OLTP sources (PG, MySQL, SQL Server) don't run on multiple replicas, so there are complications. Those sources run on the replica with the lowest ID (the oldest replica).

If a hydrating object is causing an OOM loop on the steady-size replica, a burst-replica (or a second replica created by the user), will allow the hydrating export to run on the second replica, but the OLTP source(s) will stay on the OOM looping replica and not be able to make progress.

The current recommendations:

  • Avoid colocating (e.g. don't put PG and Kafka upsert on the same cluster).
  • Don't add a second replica, replace the existing replica with a larger one.

Comment thread doc/user/content/concepts/hydration.md Outdated
- Split materialized views and indexes across multiple clusters. Each cluster
hydrates its own objects independently, which distributes the memory required
for hydration, lets objects on different clusters hydrate in parallel, and
limits how much must re-hydrate when a single cluster restarts.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Precision: Clusters are resource-less objects, cluster replicas can restart.

Comment thread doc/user/content/concepts/hydration.md Outdated
Comment on lines +57 to +60
- For a single materialized view, creating and hydrating a [replacement
materialized view (public preview) and replacing the existing view in
place](/transform-data/updating-materialized-views/replace-materialized-view/)
may be simpler, but briefly reduces freshness.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I follow this part. Does it say that a replacement MV should be on the same cluster, or on a separate cluster?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can clarify that it can be on either the same/different since it's like creating any other mv ... (like people should use the same cluster judgement as they do for other objects).

Comment thread doc/user/content/concepts/hydration.md Outdated
Comment on lines +64 to +68
The burst-replica and blue/green strategies run extra replicas alongside the
existing ones, as do a resize or a zero-downtime upgrade. During the overlap,
the cluster temporarily uses additional resources, up to roughly double during a
resize or upgrade. Account for the additional cost and, on self-managed
deployments, the additional capacity required.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not double, but the sum of the replica sizes. It's billed exactly, not approximately.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just left off ", up to ..." so that if flows better "... uses additional resources. Account for the ..."

Comment thread doc/user/data/hydration-details.yml Outdated
Comment on lines +42 to +45
- **Memory Use**: Its memory scales with those arrangements, so joins and
aggregations are the memory-hungry cases while a pure map or filter view is
nearly stateless. It also holds an output-side buffer that scales with the
view's output volume and is largest during hydration.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe more precisely: Its memory use scales with the view's definition and, during hydration, with twice the output size.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you! Updated

Comment on lines +55 to +56
- **Memory Use**: Its memory is proportional to the indexed data plus those
arrangements, and is held for as long as the index exists.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to talk about retain history? It affects the indexes' size, roughly based on the update rate.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since we advise against it for indexes (and there have been discussions about its use w other objects as well), will not mention now. Can revisit in the future.

Comment thread doc/user/data/hydration-details.yml Outdated
Comment on lines +100 to +102
- **When**: On creation only. Because a subscription is transient and tied to
its session, it is not rehydrated on restart and is not reported in
`mz_hydration_statuses`.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not entirely true: Adding a new replica to a cluster will hydrate the same subscribe dataflow.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated.

Comment thread doc/user/data/hydration-details.yml Outdated
Comment thread doc/user/data/hydration-details.yml Outdated
Comment thread doc/user/data/hydration-details.yml Outdated
Comment on lines +42 to +45
- **Memory Use**: Its memory scales with those arrangements, so joins and
aggregations are the memory-hungry cases while a pure map or filter view is
nearly stateless. It also holds an output-side buffer that scales with the
view's output volume and is largest during hydration.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addendum: MVs have the property that their first startup memory cost is proportional to $$O(|\text{dataflow} + \text{output}|)$$, but any subsequent startup it's $$O(|\text{dataflow} + \text{output} + \text{previous output}|)$$, so the first startup is a special-case because the previous output is the empty set.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated.

Comment on lines +91 to +94
- **When**: Hydrates on creation and on every replica (re)start or cluster resize.

- **What**: Loads a full copy of its input snapshot into the arrangement that
feeds the sink before it can emit.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As an fyi for the sources & sinks team: Claude at first refuted this because it got confused by the comment https://github.com/MaterializeInc/materialize/blob/main/src/storage/src/sink/kafka.rs#L771-L780 (which is referring to something else). I had it double check that we're not talking about different things ... and then, it corrected itself.

Hydration behavior: '{{< include-from-yaml data="hydration-details" name="materialized-view" >}}'
- Object: "Indexes"
Hydration behavior: '{{< include-from-yaml data="hydration-details" name="index" >}}'
- Object: "Kafka **upsert** sources and associated read-only tables/subsources"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Upsert and debezium envelopes need to perform hydration, does this imply coverage for both?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. Discussed with @maheshwarip and we'll be going with upsert sources (but when talking about envelopes, we distinguish them. I could go Kafka upsert sources (including those using Debezium envelopes) or something like that.

Comment on lines +36 to +40
- Add an [`AUTO SCALING STRATEGY (ON HYDRATION)`](/sql/alter-cluster/) to your
cluster. With this strategy, Materialize automatically provisions an extra,
larger replica (a burst replica) while the cluster has un-hydrated objects,
then removes it once a steady-size replica catches up. You pay for the burst
replica while it is provisioned, but not at steady state.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OLTP sources (PG, MySQL, SQL Server) don't run on multiple replicas, so there are complications. Those sources run on the replica with the lowest ID (the oldest replica).

If a hydrating object is causing an OOM loop on the steady-size replica, a burst-replica (or a second replica created by the user), will allow the hydrating export to run on the second replica, but the OLTP source(s) will stay on the OOM looping replica and not be able to make progress.

The current recommendations:

  • Avoid colocating (e.g. don't put PG and Kafka upsert on the same cluster).
  • Don't add a second replica, replace the existing replica with a larger one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants