From 054d4bb80b4be3af87fff13eca41c1b8ed28bc06 Mon Sep 17 00:00:00 2001 From: Tomasz Kopacki Date: Tue, 19 May 2026 10:37:41 +0200 Subject: [PATCH 1/6] Document the ENSNode scalability story --- .../starlight/sidebar-topics/self-host.ts | 4 ++ .../docs/docs/self-host/scalability.mdx | 48 +++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 docs/ensnode.io/src/content/docs/docs/self-host/scalability.mdx diff --git a/docs/ensnode.io/config/integrations/starlight/sidebar-topics/self-host.ts b/docs/ensnode.io/config/integrations/starlight/sidebar-topics/self-host.ts index b6436c6e00..b164f78a55 100644 --- a/docs/ensnode.io/config/integrations/starlight/sidebar-topics/self-host.ts +++ b/docs/ensnode.io/config/integrations/starlight/sidebar-topics/self-host.ts @@ -15,5 +15,9 @@ export const selfHostSidebarTopic = { label: "Terraform", link: "/docs/self-host/terraform", }, + { + label: "Scalability", + link: "/docs/self-host/scalability", + }, ], }; diff --git a/docs/ensnode.io/src/content/docs/docs/self-host/scalability.mdx b/docs/ensnode.io/src/content/docs/docs/self-host/scalability.mdx new file mode 100644 index 0000000000..8e63898b9b --- /dev/null +++ b/docs/ensnode.io/src/content/docs/docs/self-host/scalability.mdx @@ -0,0 +1,48 @@ +--- +title: ENSNode Scalability +description: Understand how ENSNode's architecture enables horizontal scaling through PostgreSQL replication. +sidebar: + label: Scalability + order: 3 +--- + +import { LinkCard } from '@astrojs/starlight/components'; + +ENSNode's architecture is designed for excellent scalability. By separating write and read workloads and building on PostgreSQL, you can scale your ENSNode deployment to handle high request volumes without impacting indexing performance. + +## Single Writer, Many Readers + +The ENSNode architecture naturally separates writes from reads: + +- **ENSIndexer** is the sole writer to ENSDb. It processes blockchain events and updates the database with the latest ENS state. +- **ENSApi** is a read-only service. It serves GraphQL and REST API requests by querying ENSDb, but never writes to it. + +This separation insulates ENSIndexer from high request volumes. Whether you serve 10 requests per second or 10,000, the indexing process remains unaffected because ENSApi does not compete with ENSIndexer for database write locks or indexer resources. + +## Scale ENSDb with PostgreSQL Replication + +ENSDb is built on PostgreSQL, which provides mature, production-proven mechanisms for horizontal scaling. The most common approach is **asynchronous replication**: + +1. **Primary (master)**: ENSIndexer instance writes to a single ENSDb primary instance. +2. **Replicas**: The primary ENSDb instance asynchronously replicates its data to one or more ENSDb read replicas. +3. **Read scaling**: You can connect any number of ENSApi instances to the ENSDb primary instance or to any ENSDb replica. + +Because ENSApi is read-only, it can safely connect to an ENSDb replica without risking stale writes or replication conflicts. As your query load grows, you simply add more PostgreSQL replicas for ENSDb primary instance and more ENSApi instances pointing to them. + +## Deployment Example + +A scalable ENSNode deployment might look like this: + +- **One ENSIndexer instance** → writes to the ENSDb primary instance +- **One ENSDb primary instance** → replicates asynchronously to `N` replicas +- **Multiple ENSApi instances** → each connected to the ENSDb primary instance or any ENSDb replica (often load-balanced across replicas) +- **One ENSRainbow instance** → co-located with ENSIndexer instance on the same local network for fast label healing + +This architecture lets you scale reads independently of writes, matching your infrastructure to your actual traffic patterns. + +## Further Reading + + + + + From 99bf44857b084baff97700cdc1f3424bbff42333 Mon Sep 17 00:00:00 2001 From: Tomasz Kopacki Date: Tue, 19 May 2026 11:17:15 +0200 Subject: [PATCH 2/6] Add a graphical presentation of a scalable ENSNode deployment --- docs/ensnode.io/public/ensnode-scalability.svg | 1 + .../src/content/docs/docs/self-host/scalability.mdx | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 docs/ensnode.io/public/ensnode-scalability.svg diff --git a/docs/ensnode.io/public/ensnode-scalability.svg b/docs/ensnode.io/public/ensnode-scalability.svg new file mode 100644 index 0000000000..e853b11832 --- /dev/null +++ b/docs/ensnode.io/public/ensnode-scalability.svg @@ -0,0 +1 @@ + Data producers (write layer) Data consumers (read layer) Data producers (persistence layer)ENSIndexerENSRainbowreads healed labelsENSDb Replica 1(Read-only)ENSDb Replica 2(Read-only)ENSDb Replica M(Read-only)Load balancer(Single Reader Target)readsreadsreadswritesENSDb Primary(Single Writer Target)optionally readsAsync replicationreadswriteswriteswritesENSApi Instance 1(Read-only)ENSApi Instance 2(Read-only)ENSApi Instance N(Read-only)Load balancer(Single Reader Target)readsreadsreadsreadsreadsreadsWebClient 1WebClient 2WebClient Xreadsreadsreads \ No newline at end of file diff --git a/docs/ensnode.io/src/content/docs/docs/self-host/scalability.mdx b/docs/ensnode.io/src/content/docs/docs/self-host/scalability.mdx index 8e63898b9b..54e02f1681 100644 --- a/docs/ensnode.io/src/content/docs/docs/self-host/scalability.mdx +++ b/docs/ensnode.io/src/content/docs/docs/self-host/scalability.mdx @@ -33,9 +33,11 @@ Because ENSApi is read-only, it can safely connect to an ENSDb replica without r A scalable ENSNode deployment might look like this: +![ENSNode Scalable Deployment Architecture](/ensnode-scalability.svg) + - **One ENSIndexer instance** → writes to the ENSDb primary instance -- **One ENSDb primary instance** → replicates asynchronously to `N` replicas -- **Multiple ENSApi instances** → each connected to the ENSDb primary instance or any ENSDb replica (often load-balanced across replicas) +- **One ENSDb primary instance** → replicates asynchronously to `M` replicas +- **Multiple ENSApi instances** → each of `N` instances connected to the ENSDb primary instance or any ENSDb replica (often load-balanced across replicas) - **One ENSRainbow instance** → co-located with ENSIndexer instance on the same local network for fast label healing This architecture lets you scale reads independently of writes, matching your infrastructure to your actual traffic patterns. From 4a831fa9ccca20e1e2a943b67b6e179627e25c36 Mon Sep 17 00:00:00 2001 From: Tomek Kopacki Date: Tue, 19 May 2026 16:31:43 +0200 Subject: [PATCH 3/6] Update docs/ensnode.io/src/content/docs/docs/self-host/scalability.mdx Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> --- docs/ensnode.io/src/content/docs/docs/self-host/scalability.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ensnode.io/src/content/docs/docs/self-host/scalability.mdx b/docs/ensnode.io/src/content/docs/docs/self-host/scalability.mdx index 54e02f1681..e39c9dd0c5 100644 --- a/docs/ensnode.io/src/content/docs/docs/self-host/scalability.mdx +++ b/docs/ensnode.io/src/content/docs/docs/self-host/scalability.mdx @@ -27,7 +27,7 @@ ENSDb is built on PostgreSQL, which provides mature, production-proven mechanism 2. **Replicas**: The primary ENSDb instance asynchronously replicates its data to one or more ENSDb read replicas. 3. **Read scaling**: You can connect any number of ENSApi instances to the ENSDb primary instance or to any ENSDb replica. -Because ENSApi is read-only, it can safely connect to an ENSDb replica without risking stale writes or replication conflicts. As your query load grows, you simply add more PostgreSQL replicas for ENSDb primary instance and more ENSApi instances pointing to them. +Because ENSApi is read-only, it can safely connect to an ENSDb replica without risking stale writes or replication conflicts. As your query load grows, you simply add more PostgreSQL replicas for the ENSDb primary instance and more ENSApi instances pointing to them. ## Deployment Example From 6c59d33e28bb0da840574b68343b147bd366b3ee Mon Sep 17 00:00:00 2001 From: Tomek Kopacki Date: Tue, 19 May 2026 23:00:29 +0200 Subject: [PATCH 4/6] Add temporary note on `v1.13` compatility requirements (#2150) --- .../HostedInstanceSdkVersionWarning.astro | 40 +++++++++++++++++++ .../molecules/IntegrateHostedEnsNodeTip.astro | 16 +++++++- .../docs/docs/integrate/hosted-instances.mdx | 3 ++ .../src/content/docs/docs/integrate/index.mdx | 5 +++ .../integration-options/enskit/example.mdx | 3 ++ .../integration-options/enskit/index.mdx | 6 ++- .../integration-options/enssdk/example.mdx | 5 ++- .../integration-options/enssdk/index.mdx | 6 ++- examples/enskit-react-example/README.md | 2 + examples/enssdk-example/README.md | 2 + examples/omnigraph-graphql-example/README.md | 2 + packages/enskit/README.md | 14 +++++++ packages/enssdk/README.md | 6 +++ 13 files changed, 103 insertions(+), 7 deletions(-) create mode 100644 docs/ensnode.io/src/components/molecules/HostedInstanceSdkVersionWarning.astro diff --git a/docs/ensnode.io/src/components/molecules/HostedInstanceSdkVersionWarning.astro b/docs/ensnode.io/src/components/molecules/HostedInstanceSdkVersionWarning.astro new file mode 100644 index 0000000000..f05ea3fb3e --- /dev/null +++ b/docs/ensnode.io/src/components/molecules/HostedInstanceSdkVersionWarning.astro @@ -0,0 +1,40 @@ +--- +import { Aside } from "@astrojs/starlight/components"; + +interface Props { + /** + * Which SDK(s) the warning is for. + * - "enssdk": only enssdk + * - "enskit": both enskit and enssdk (enskit depends on enssdk) + * - "both": mention both enssdk and enskit, show both install commands + */ + for?: "enssdk" | "enskit" | "both"; +} + +const { for: target = "enssdk" } = Astro.props; + +const isEnskit = target === "enskit"; +const isBoth = target === "both"; + +const sdkList = isEnskit + ? "enskit@1.13.1 and enssdk@1.13.1" + : isBoth + ? "enssdk@1.13.1 (and enskit@1.13.1 when using React)" + : "enssdk@1.13.1"; +--- + + diff --git a/docs/ensnode.io/src/components/molecules/IntegrateHostedEnsNodeTip.astro b/docs/ensnode.io/src/components/molecules/IntegrateHostedEnsNodeTip.astro index 99187a3479..ff26d999ae 100644 --- a/docs/ensnode.io/src/components/molecules/IntegrateHostedEnsNodeTip.astro +++ b/docs/ensnode.io/src/components/molecules/IntegrateHostedEnsNodeTip.astro @@ -1,13 +1,25 @@ --- import { Aside, LinkCard } from "@astrojs/starlight/components"; +import HostedInstanceSdkVersionWarning from "./HostedInstanceSdkVersionWarning.astro"; + +interface Props { + /** + * Which SDK the warning should target. Passed through to HostedInstanceSdkVersionWarning. + * - "enssdk": enssdk-only warning + * - "enskit": both enskit and enssdk warning + * - "both": mention both enssdk and enskit, show both install commands (default) + */ + for?: "enssdk" | "enskit" | "both"; +} + +const { for: target = "both" } = Astro.props; --- + - - diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/hosted-instances.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/hosted-instances.mdx index a85a83e96e..f04b4e1f64 100644 --- a/docs/ensnode.io/src/content/docs/docs/integrate/hosted-instances.mdx +++ b/docs/ensnode.io/src/content/docs/docs/integrate/hosted-instances.mdx @@ -6,6 +6,7 @@ sidebar: --- import HostedEnsNodeInstances from "@components/molecules/HostedEnsNodeInstances.astro"; +import HostedInstanceSdkVersionWarning from "@components/molecules/HostedInstanceSdkVersionWarning.astro"; ## Hosted Instances @@ -13,6 +14,8 @@ NameHash Labs provides freely available hosted instances for ENS developers look These instances are provided free of charge with no API key required, have no rate limiting, and are maintained and monitored by the NameHash Labs team. + + ### Available instance configurations Each ENSNode hosted instance is configured for a specific ENS namespace and activated ENSNode plugins. The ENS namespace is the source of truth for the data indexed by the instance, and the activated ENSNode plugins determine the specific data model produced by indexing and available for querying. diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/index.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/index.mdx index f1fee67625..f40787fb87 100644 --- a/docs/ensnode.io/src/content/docs/docs/integrate/index.mdx +++ b/docs/ensnode.io/src/content/docs/docs/integrate/index.mdx @@ -7,6 +7,7 @@ sidebar: --- import { LinkCard, CardGrid, Aside } from "@astrojs/starlight/components"; +import HostedInstanceSdkVersionWarning from "@components/molecules/HostedInstanceSdkVersionWarning.astro"; import OmnigraphAPIExample from "@components/organisms/OmnigraphAPIExample.astro"; ## What is ENSv2? @@ -44,6 +45,8 @@ Here's a summary of some popular integration strategies: With `enskit`, leverage ENSNode and the Omnigraph to power your React components using `useOmnigraphQuery`. `enskit` comes with built-in type-safety, Omnigraph-specific cache directives, easy infinite pagination, and much much more. + + ```tsx // this is fully typechecked and supports editor autocomplete! @@ -138,6 +141,8 @@ export function RenderDomainAndSubdomains({ name }: { name: InterpretedName }) { With `enssdk`, leverage ENSNode and the Omnigraph from any JavaScript runtime to power your frontend or backend apps. `enssdk` comes with built-in type-safety and editor autocomplete for Omnigraph queries. + + ```ts // create and extend an EnsNodeClient with Omnigraph API support diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/integration-options/enskit/example.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/integration-options/enskit/example.mdx index 047ed203cf..fd527308df 100644 --- a/docs/ensnode.io/src/content/docs/docs/integrate/integration-options/enskit/example.mdx +++ b/docs/ensnode.io/src/content/docs/docs/integrate/integration-options/enskit/example.mdx @@ -8,9 +8,12 @@ sidebar: --- import EnskitExampleInteractivePlayground from "@components/organisms/EnskitExampleInteractivePlayground"; +import HostedInstanceSdkVersionWarning from "@components/molecules/HostedInstanceSdkVersionWarning.astro"; This playground loads the same source as [`enskit-react-example`](https://github.com/namehash/ensnode/tree/main/examples/enskit-react-example): a Vite + React app with routing, domain and account browsers, registry cache, and search — powered by [`enskit`](/docs/integrate/integration-options/enskit) and the [ENS Omnigraph API](/docs/integrate/omnigraph). + + :::note[First load may take a moment] The editor runs entirely in your browser. Downloading of **enskit**, **enssdk** and their heavy dependencies may take 30-60 seconds. ::: diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/integration-options/enskit/index.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/integration-options/enskit/index.mdx index 101dd4bec0..cabf6cef2d 100644 --- a/docs/ensnode.io/src/content/docs/docs/integrate/integration-options/enskit/index.mdx +++ b/docs/ensnode.io/src/content/docs/docs/integrate/integration-options/enskit/index.mdx @@ -10,7 +10,7 @@ import IntegrateHostedEnsNodeTip from '@components/molecules/IntegrateHostedEnsN This guide walks you from an empty directory to a working React component that renders an [ENS Domain](/docs/concepts/the-ens-protocol) and a paginated list of its subdomains — the same flow as the [`DomainView`](https://github.com/namehash/ensnode/blob/main/examples/enskit-react-example/src/DomainView.tsx) in our example app. - + ## 1. Scaffold a React app @@ -31,8 +31,10 @@ npm install npm install enskit@1.13.1 enssdk@1.13.1 ``` -:::tip[Pin exact versions] +:::caution[Pin exact versions — hosted instance compatibility] Always pin **exact** versions (no `^` or `~`) of `enskit` and `enssdk`, and keep them on the same version. The Omnigraph GraphQL schema is bundled inside `enssdk` and consumed by the `gql.tada` TypeScript plugin to type your queries — a minor or patch bump can change the schema and silently drift your generated types away from your queries. Locking exact versions keeps types and runtime in sync. + +**Important:** Our hosted ENSNode instances currently run ENSNode v1.13. The latest published versions of `enskit` and `enssdk` are `1.14.0+`, which contain breaking changes in the Omnigraph API data model not yet deployed to our hosted infrastructure. If you are querying a hosted instance from your own app, you **must** use `enskit@1.13.1` and `enssdk@1.13.1` to avoid type errors and runtime mismatches. This notice will be removed once the hosted instances are upgraded. ::: ## 3. Configure the `gql.tada` TypeScript plugin diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/integration-options/enssdk/example.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/integration-options/enssdk/example.mdx index 3028bcae7c..e26c1d2015 100644 --- a/docs/ensnode.io/src/content/docs/docs/integrate/integration-options/enssdk/example.mdx +++ b/docs/ensnode.io/src/content/docs/docs/integrate/integration-options/enssdk/example.mdx @@ -8,11 +8,14 @@ sidebar: --- import EnssdkExampleInteractivePlayground from "@components/organisms/EnssdkExampleInteractivePlayground"; +import HostedInstanceSdkVersionWarning from "@components/molecules/HostedInstanceSdkVersionWarning.astro"; This playground loads the same source as [`enssdk-example`](https://github.com/namehash/ensnode/tree/main/examples/enssdk-example): a TypeScript script that queries the `eth` domain and lists its first 20 subdomains via [`enssdk`](/docs/integrate/integration-options/enssdk) and the [ENS Omnigraph API](/docs/integrate/omnigraph). + + :::note[First load may take a moment] -The editor runs entirely in your browser. The editor runs entirely in your browser. Downloading of **enssdk** and heavy dependencies may take 30-60 seconds. +The editor runs entirely in your browser. Downloading of **enssdk** and heavy dependencies may take 30-60 seconds. ::: You can edit the script and run **`npm start`** in the terminal to run it again. diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/integration-options/enssdk/index.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/integration-options/enssdk/index.mdx index 7d632d3600..530485e100 100644 --- a/docs/ensnode.io/src/content/docs/docs/integrate/integration-options/enssdk/index.mdx +++ b/docs/ensnode.io/src/content/docs/docs/integrate/integration-options/enssdk/index.mdx @@ -12,7 +12,7 @@ import IntegrateHostedEnsNodeTip from '@components/molecules/IntegrateHostedEnsN This guide walks you from an empty directory to a working TypeScript script that queries the `eth` Domain and queries its subdomains — the same flow as our [enssdk-example](https://github.com/namehash/ensnode/tree/main/examples/enssdk-example). - + ## 1. Scaffold a TypeScript project @@ -35,8 +35,10 @@ npm install enssdk@1.13.1 npm install -D tsx typescript @types/node ``` -:::tip[Pin exact versions] +:::caution[Pin exact versions — hosted instance compatibility] Always pin an **exact** version (no `^` or `~`) of `enssdk`. The Omnigraph GraphQL schema is bundled inside `enssdk` and consumed by the `gql.tada` TypeScript plugin to type your queries — a minor or patch bump can change the schema and silently drift your generated types away from your queries. Locking the exact version keeps types and runtime in sync. + +**Important:** Our hosted ENSNode instances currently run ENSNode v1.13. The latest published version of `enssdk` is `1.14.0+`, which contains breaking changes in the Omnigraph API data model not yet deployed to our hosted infrastructure. If you are querying a hosted instance from your own app, you **must** use `enssdk@1.13.1` to avoid type errors and runtime mismatches. This notice will be removed once the hosted instances are upgraded. ::: diff --git a/examples/enskit-react-example/README.md b/examples/enskit-react-example/README.md index b17b534ada..894c6b5efc 100644 --- a/examples/enskit-react-example/README.md +++ b/examples/enskit-react-example/README.md @@ -8,6 +8,8 @@ This app is hosted at [https://enskit-react-example.ensnode.io/](https://enskit- ## Usage (with NameHash Hosted Instance) +> **Version compatibility:** Our hosted ENSNode instances currently run ENSNode v1.13. If you are querying them from your own app, you **must** use `enskit@1.13.1` and `enssdk@1.13.1`. The latest published versions (`1.14.0+`) contain breaking changes in the Omnigraph API data model not yet deployed to our hosted infrastructure. This notice will be removed once the hosted instances are upgraded. + ```sh # from the ENSNode monorepo root pnpm install diff --git a/examples/enssdk-example/README.md b/examples/enssdk-example/README.md index ff75d02fd6..217f5c084f 100644 --- a/examples/enssdk-example/README.md +++ b/examples/enssdk-example/README.md @@ -6,6 +6,8 @@ Companion to the [enssdk integration guide](https://ensnode.io/docs/integrate/in ## Usage (with NameHash Hosted Instance) +> **Version compatibility:** Our hosted ENSNode instances currently run ENSNode v1.13. If you are querying them from your own app, you **must** use `enssdk@1.13.1`. The latest published version (`1.14.0+`) contains breaking changes in the Omnigraph API data model not yet deployed to our hosted infrastructure. This notice will be removed once the hosted instances are upgraded. + ```sh # from the ENSNode monorepo root pnpm install diff --git a/examples/omnigraph-graphql-example/README.md b/examples/omnigraph-graphql-example/README.md index 8b49e0afdc..80b4365d70 100644 --- a/examples/omnigraph-graphql-example/README.md +++ b/examples/omnigraph-graphql-example/README.md @@ -8,6 +8,8 @@ Companion to the [ENS Omnigraph GraphQL API integration guide](https://ensnode.i ## Usage (with NameHash Hosted Instance) +> **Version compatibility:** Our hosted ENSNode instances currently run ENSNode v1.13. If you are querying them from your own app, you **must** use `enssdk@1.13.1` (and `enskit@1.13.1` when using React). The latest published versions (`1.14.0+`) contain breaking changes in the Omnigraph API data model not yet deployed to our hosted infrastructure. This notice will be removed once the hosted instances are upgraded. + ```sh # from the ENSNode monorepo root pnpm install diff --git a/packages/enskit/README.md b/packages/enskit/README.md index 12214ac9d2..a1fa5dbdb1 100644 --- a/packages/enskit/README.md +++ b/packages/enskit/README.md @@ -1,5 +1,19 @@ # enskit +The React toolkit for ENSv2 development. Provides typed Omnigraph API hooks, providers, and utilities powered by [`urql`](https://nearform.com/open-source/urql/) and [`gql.tada`](https://gql-tada.0no.co/). + This package name is reserved for the [ENSNode](https://ensnode.io) project by [NameHash Labs](https://namehashlabs.org). For more information, visit [ensnode.io](https://ensnode.io). + +## Installation + +```bash +npm install enskit enssdk +``` + +> **Version compatibility:** Our hosted ENSNode instances currently run ENSNode v1.13. If you are querying them from your own app, you **must** use `enskit@1.13.1` and `enssdk@1.13.1`. The latest published versions (`1.14.0+`) contain breaking changes in the Omnigraph API data model not yet deployed to our hosted infrastructure. This notice will be removed once the hosted instances are upgraded. +> +> ```bash +> npm install enskit@1.13.1 enssdk@1.13.1 +> ``` diff --git a/packages/enssdk/README.md b/packages/enssdk/README.md index 75e840ef4e..9a35a2a72b 100644 --- a/packages/enssdk/README.md +++ b/packages/enssdk/README.md @@ -10,6 +10,12 @@ Learn more about [ENSNode](https://ensnode.io/) from [the ENSNode docs](https:// npm install enssdk ``` +> **Version compatibility:** Our hosted ENSNode instances currently run ENSNode v1.13. If you are querying them from your own app, you **must** use `enssdk@1.13.1`. The latest published version (`1.14.0+`) contains breaking changes in the Omnigraph API data model not yet deployed to our hosted infrastructure. This notice will be removed once the hosted instances are upgraded. +> +> ```bash +> npm install enssdk@1.13.1 +> ``` + ## Usage ### Core Client From 3a4b1d3a1f9b5d85b534e3a2d3af4b5bb9086a71 Mon Sep 17 00:00:00 2001 From: Tomek Kopacki Date: Wed, 20 May 2026 07:06:53 +0200 Subject: [PATCH 5/6] Apply suggestions from code review Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Co-authored-by: lightwalker.eth <126201998+lightwalker-eth@users.noreply.github.com> --- .../docs/docs/self-host/scalability.mdx | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/ensnode.io/src/content/docs/docs/self-host/scalability.mdx b/docs/ensnode.io/src/content/docs/docs/self-host/scalability.mdx index e39c9dd0c5..05cb0e9952 100644 --- a/docs/ensnode.io/src/content/docs/docs/self-host/scalability.mdx +++ b/docs/ensnode.io/src/content/docs/docs/self-host/scalability.mdx @@ -1,6 +1,6 @@ --- title: ENSNode Scalability -description: Understand how ENSNode's architecture enables horizontal scaling through PostgreSQL replication. +description: Understand how ENSNode's architecture enables horizontal scaling. sidebar: label: Scalability order: 3 @@ -8,9 +8,9 @@ sidebar: import { LinkCard } from '@astrojs/starlight/components'; -ENSNode's architecture is designed for excellent scalability. By separating write and read workloads and building on PostgreSQL, you can scale your ENSNode deployment to handle high request volumes without impacting indexing performance. +ENSNode's architecture achieves effectively limitless horizontal scalability, no matter how large your query demands might be. By separating read / write workloads and making use of PostgreSQL's async replication you can scale your ENSNode deployment to handle any request volumes while continuing to index the latest ENS data without impact to indexing performance. -## Single Writer, Many Readers +## Horizontally scale ENSApi The ENSNode architecture naturally separates writes from reads: @@ -19,19 +19,19 @@ The ENSNode architecture naturally separates writes from reads: This separation insulates ENSIndexer from high request volumes. Whether you serve 10 requests per second or 10,000, the indexing process remains unaffected because ENSApi does not compete with ENSIndexer for database write locks or indexer resources. -## Scale ENSDb with PostgreSQL Replication +## Horizontally Scale ENSDb ENSDb is built on PostgreSQL, which provides mature, production-proven mechanisms for horizontal scaling. The most common approach is **asynchronous replication**: -1. **Primary (master)**: ENSIndexer instance writes to a single ENSDb primary instance. -2. **Replicas**: The primary ENSDb instance asynchronously replicates its data to one or more ENSDb read replicas. -3. **Read scaling**: You can connect any number of ENSApi instances to the ENSDb primary instance or to any ENSDb replica. +1. **Primary ENSDb**: ENSIndexer writes to your single ENSDb primary instance. You can fully isolate this ENSDb primary instance from any incoming API requests coming through ENSApi. +2. **Replica ENSDb**: Configure the asynchronous replication of your primary ENSDb instance to one or more ENSDb read replica instances. +3. **Read scaling**: Connect your horizontally scaled ENSApi instances exclusively to your ENSDb read replica instances if you wish to fully isolate extreme levels of API request volumes from indexing. -Because ENSApi is read-only, it can safely connect to an ENSDb replica without risking stale writes or replication conflicts. As your query load grows, you simply add more PostgreSQL replicas for the ENSDb primary instance and more ENSApi instances pointing to them. +Because ENSApi is read-only, it can safely connect to an ENSDb replica without write-routing or write-conflict concerns. The tradeoff is that, with asynchronous replication, replica reads may briefly lag behind the primary. As your query load grows, you simply add more PostgreSQL replicas for the ENSDb primary instance and more ENSApi instances pointing to them. -## Deployment Example +## Going Massive -A scalable ENSNode deployment might look like this: +An ENSNode deployment with _massive_ horizontal scaling might look like this: ![ENSNode Scalable Deployment Architecture](/ensnode-scalability.svg) @@ -40,7 +40,7 @@ A scalable ENSNode deployment might look like this: - **Multiple ENSApi instances** → each of `N` instances connected to the ENSDb primary instance or any ENSDb replica (often load-balanced across replicas) - **One ENSRainbow instance** → co-located with ENSIndexer instance on the same local network for fast label healing -This architecture lets you scale reads independently of writes, matching your infrastructure to your actual traffic patterns. +Only the largest ENSNode deployments will need such a complex setup. Still, it's good to know that if you need massive scalability, we have you covered! The ENSNode architecture lets you scale reads independently of writes, matching your infrastructure to your actual traffic patterns. ## Further Reading From a645814a5582c0ebad944585b6910b3712ee9b84 Mon Sep 17 00:00:00 2001 From: Tomasz Kopacki Date: Wed, 20 May 2026 08:16:45 +0200 Subject: [PATCH 6/6] Update ENSNode Scalability chart --- .../ensnode.io/public/ensnode-scalability.svg | 5 ++++- .../src/content/docs/docs/self-host/index.mdx | 11 +++++++++- .../docs/docs/self-host/scalability.mdx | 22 +++++++++---------- 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/docs/ensnode.io/public/ensnode-scalability.svg b/docs/ensnode.io/public/ensnode-scalability.svg index e853b11832..58ce088f1c 100644 --- a/docs/ensnode.io/public/ensnode-scalability.svg +++ b/docs/ensnode.io/public/ensnode-scalability.svg @@ -1 +1,4 @@ - Data producers (write layer) Data consumers (read layer) Data producers (persistence layer)ENSIndexerENSRainbowreads healed labelsENSDb Replica 1(Read-only)ENSDb Replica 2(Read-only)ENSDb Replica M(Read-only)Load balancer(Single Reader Target)readsreadsreadswritesENSDb Primary(Single Writer Target)optionally readsAsync replicationreadswriteswriteswritesENSApi Instance 1(Read-only)ENSApi Instance 2(Read-only)ENSApi Instance N(Read-only)Load balancer(Single Reader Target)readsreadsreadsreadsreadsreadsWebClient 1WebClient 2WebClient Xreadsreadsreads \ No newline at end of file + + + +

ENSIndexer layer

No horizontal scalability needed

ENSRainbow
heals unknown labels
writes
ENSIndexer
async replication
ENSDb
(Single Writer Target)

Horizontally scale
ENSDb

ENSDb Replica 1
ENSDb Replica 2
ENSDb Replica M
reads
Load balancer
(Single Reader Target)

Horizontally scale
ENSApi

ENSApi Instance 1
ENSApi Instance 2
reads
ENSApi Instance N
reads
Load balancer
(Single Reader Target)
Web Client 1
Web Client 2
Web Client X
Web Client 3
reads
Web Client 4
\ No newline at end of file diff --git a/docs/ensnode.io/src/content/docs/docs/self-host/index.mdx b/docs/ensnode.io/src/content/docs/docs/self-host/index.mdx index 741904cad0..971a529737 100644 --- a/docs/ensnode.io/src/content/docs/docs/self-host/index.mdx +++ b/docs/ensnode.io/src/content/docs/docs/self-host/index.mdx @@ -24,7 +24,7 @@ Running your own ENSNode instance is helpful for those that wish to: Note that because ENSNode makes many label healing requests to ENSRainbow while indexing, it's _imperative_ that they be on the same local network to minimize request time. ::: -## Bootstrap from a snapshot (coming soon) +### Bootstrap from a snapshot (coming soon) Self-hosting today means standing up a fresh ENSNode instance from zero and waiting on an initial backfill - including the RPC bill that comes with it. **[ENSDb snapshots and `ensdb-cli`](/docs/integrate/integration-options/ensdb-cli)** flatten that ramp. @@ -38,6 +38,15 @@ The headline value props for self-hosters: href="/docs/integrate/integration-options/ensdb-cli" /> +### Massive scalability + + + + ### Deploying with Docker The Docker deployment option provides the easiest way to run the full ENSNode suite of services both locally and in the cloud. diff --git a/docs/ensnode.io/src/content/docs/docs/self-host/scalability.mdx b/docs/ensnode.io/src/content/docs/docs/self-host/scalability.mdx index 05cb0e9952..0069d77fef 100644 --- a/docs/ensnode.io/src/content/docs/docs/self-host/scalability.mdx +++ b/docs/ensnode.io/src/content/docs/docs/self-host/scalability.mdx @@ -1,6 +1,6 @@ --- title: ENSNode Scalability -description: Understand how ENSNode's architecture enables horizontal scaling. +description: Understand how ENSNode's architecture enables horizontal scaling. sidebar: label: Scalability order: 3 @@ -8,9 +8,9 @@ sidebar: import { LinkCard } from '@astrojs/starlight/components'; -ENSNode's architecture achieves effectively limitless horizontal scalability, no matter how large your query demands might be. By separating read / write workloads and making use of PostgreSQL's async replication you can scale your ENSNode deployment to handle any request volumes while continuing to index the latest ENS data without impact to indexing performance. +ENSNode's architecture achieves effectively limitless horizontal scalability, no matter how large your query demands might be. By separating read / write workloads and making use of PostgreSQL's async replication you can scale your ENSNode deployment to handle any request volumes while continuing to index the latest ENS data without impact to indexing performance. -## Horizontally scale ENSApi +## Horizontally scale ENSApi The ENSNode architecture naturally separates writes from reads: @@ -19,28 +19,28 @@ The ENSNode architecture naturally separates writes from reads: This separation insulates ENSIndexer from high request volumes. Whether you serve 10 requests per second or 10,000, the indexing process remains unaffected because ENSApi does not compete with ENSIndexer for database write locks or indexer resources. -## Horizontally Scale ENSDb +## Horizontally Scale ENSDb ENSDb is built on PostgreSQL, which provides mature, production-proven mechanisms for horizontal scaling. The most common approach is **asynchronous replication**: -1. **Primary ENSDb**: ENSIndexer writes to your single ENSDb primary instance. You can fully isolate this ENSDb primary instance from any incoming API requests coming through ENSApi. -2. **Replica ENSDb**: Configure the asynchronous replication of your primary ENSDb instance to one or more ENSDb read replica instances. -3. **Read scaling**: Connect your horizontally scaled ENSApi instances exclusively to your ENSDb read replica instances if you wish to fully isolate extreme levels of API request volumes from indexing. +1. **Primary ENSDb**: ENSIndexer writes to your single ENSDb primary instance. You can fully isolate this ENSDb primary instance from any incoming API requests coming through ENSApi. +2. **Replica ENSDb**: Configure the asynchronous replication of your primary ENSDb instance to one or more ENSDb read replica instances. +3. **Read scaling**: Connect your horizontally scaled ENSApi instances exclusively to your ENSDb read replica instances if you wish to fully isolate extreme levels of API request volumes from indexing. Because ENSApi is read-only, it can safely connect to an ENSDb replica without write-routing or write-conflict concerns. The tradeoff is that, with asynchronous replication, replica reads may briefly lag behind the primary. As your query load grows, you simply add more PostgreSQL replicas for the ENSDb primary instance and more ENSApi instances pointing to them. -## Going Massive +## Going Massive -An ENSNode deployment with _massive_ horizontal scaling might look like this: +An ENSNode deployment with _massive_ horizontal scaling might look like this: ![ENSNode Scalable Deployment Architecture](/ensnode-scalability.svg) - **One ENSIndexer instance** → writes to the ENSDb primary instance - **One ENSDb primary instance** → replicates asynchronously to `M` replicas -- **Multiple ENSApi instances** → each of `N` instances connected to the ENSDb primary instance or any ENSDb replica (often load-balanced across replicas) +- **Multiple ENSApi instances** → each of `N` instances connected to one of the ENSDb replicas (often load-balanced across replicas) - **One ENSRainbow instance** → co-located with ENSIndexer instance on the same local network for fast label healing -Only the largest ENSNode deployments will need such a complex setup. Still, it's good to know that if you need massive scalability, we have you covered! The ENSNode architecture lets you scale reads independently of writes, matching your infrastructure to your actual traffic patterns. +Only the largest ENSNode deployments will need such a complex setup. Still, it's good to know that if you need massive scalability, we have you covered! The ENSNode architecture lets you scale reads independently of writes, matching your infrastructure to your actual traffic patterns. ## Further Reading