npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

sequelize-rds

v0.1.0-alpha.0

Published

Dynamic RDS/Aurora reader pool synchronization for Sequelize.

Downloads

108

Readme

sequelize-rds

Dynamic RDS/Aurora reader pool synchronization for Sequelize.

Alpha software: sequelize-rds is published as 0.1.0-alpha.0 and should be validated in your staging environment before production use. Sequelize v7 support is experimental because Sequelize v7 is still alpha.

sequelize-rds keeps Sequelize read traffic aligned with the current members of an AWS RDS/Aurora cluster. It polls RDS cluster topology, routes reads to active reader instance endpoints, adds new readers without recreating Sequelize, and drains readers that AWS reports as removed or unavailable.

It does not create, delete, or scale RDS resources.

Install

npm install sequelize-rds @aws-sdk/client-rds sequelize-pool

Use one Sequelize peer dependency:

npm install sequelize

or:

npm install @sequelize/core

Test status

The package includes two test layers:

npm run test:unit
npm run test:integration

test:unit runs the fast mocked RDS and pool tests. test:integration uses Testcontainers and Docker to run real Sequelize v6 and Sequelize v7 alpha instances against Postgres and MySQL containers. Integration tests skip automatically when Docker is unavailable.

CI runs:

npm ci
npm run typecheck
npm run test:unit
npm run build
npm run test:integration

Basic usage

import { Sequelize } from "sequelize";
import { attachRdsReplicaBalancer } from "sequelize-rds";

const sequelize = new Sequelize(process.env.DATABASE_URL!, {
  dialect: "postgres",
  pool: { max: 20, min: 0 },
});

const balancer = attachRdsReplicaBalancer(sequelize, {
  clusterIdentifier: "app-cluster",
  region: "us-east-1",
  autoStart: true,
});

await balancer.syncNow();

If autoStart is not enabled, call balancer.start() after the first sync. createRdsAwareSequelize() performs an initial sync and starts monitoring automatically.

How monitoring works

The balancer polls AWS RDS with DescribeDBClusters and DescribeDBInstances.

  • Readers are active only when they are cluster members, are not the writer, have DBInstanceStatus === "available", and have an instance endpoint address.
  • New active readers are added to read routing.
  • Removed or unavailable readers are immediately removed from scheduling.
  • In-flight connections to removed readers are allowed to release, then the reader pool is drained.
  • Writes continue through Sequelize's write pool.
  • If no active readers exist, reads fall back to the writer by default. Set fallbackToWriter: false to throw NoActiveReadersError instead.

Default polling interval is 30_000 ms. Override it with pollIntervalMs.

AWS credentials

By default, the package uses the standard AWS SDK credential chain. This supports AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN, AWS_PROFILE, and role credentials from Lambda, ECS, EKS, or EC2.

If your app uses custom environment variable names, pass credentials directly:

attachRdsReplicaBalancer(sequelize, {
  clusterIdentifier: "app-cluster",
  region: process.env.APP_AWS_REGION ?? "us-east-1",
  awsCredentials: {
    accessKeyId: process.env.APP_AWS_ACCESS_KEY_ID!,
    secretAccessKey: process.env.APP_AWS_SECRET_ACCESS_KEY!,
    sessionToken: process.env.APP_AWS_SESSION_TOKEN,
  },
  autoStart: true,
});

For advanced AWS SDK options, pass awsClientConfig:

attachRdsReplicaBalancer(sequelize, {
  clusterIdentifier: "app-cluster",
  region: "us-east-1",
  awsClientConfig: {
    maxAttempts: 5,
  },
});

For full control, pass a preconfigured rdsClient. A provided rdsClient takes precedence over awsCredentials and awsClientConfig.

import { RDSClient } from "@aws-sdk/client-rds";

const rdsClient = new RDSClient({
  region: "us-east-1",
  credentials: {
    accessKeyId: process.env.CUSTOM_ACCESS_KEY_ID!,
    secretAccessKey: process.env.CUSTOM_SECRET_ACCESS_KEY!,
  },
});

attachRdsReplicaBalancer(sequelize, {
  clusterIdentifier: "app-cluster",
  region: "us-east-1",
  rdsClient,
});

Minimum IAM permissions can be scoped to the cluster and the DB instances that belong to it:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "rds:DescribeDBClusters",
      "Resource": "arn:aws:rds:us-east-1:123456789012:cluster:app-cluster"
    },
    {
      "Effect": "Allow",
      "Action": "rds:DescribeDBInstances",
      "Resource": [
        "arn:aws:rds:us-east-1:123456789012:db:app-cluster-writer-1",
        "arn:aws:rds:us-east-1:123456789012:db:app-cluster-reader-*"
      ]
    }
  ]
}

The reader instance resource can be an exact list, a naming-pattern ARN, or a tag-scoped policy that matches how your autoscaling process creates readers. If new readers can have arbitrary names, the IAM policy must already cover those future DB instance ARNs or the package won't be able to describe them when they appear in the cluster.

Options

interface RdsReplicaBalancerOptions {
  clusterIdentifier: string;
  region: string;
  rdsClient?: RdsClientLike;
  awsCredentials?: RDSClientConfig["credentials"];
  awsClientConfig?: Omit<RDSClientConfig, "credentials" | "region">;
  pollIntervalMs?: number;
  drainTimeoutMs?: number;
  fallbackToWriter?: boolean;
  includePromotionTiers?: number[];
  excludeInstanceIdentifiers?: string[];
  keepExistingWriteHost?: boolean;
  autoStart?: boolean;
  logger?: RdsReplicaBalancerLogger;
  onTopologyChange?: (topology: RdsClusterTopology) => void | Promise<void>;
}

Defaults:

  • pollIntervalMs: 30000
  • drainTimeoutMs: 30000
  • fallbackToWriter: true
  • keepExistingWriteHost: false
  • autoStart: false

keepExistingWriteHost: false updates Sequelize's writer host from the RDS cluster writer endpoint when topology sync runs. Set it to true if your app intentionally uses an existing writer host, RDS Proxy, or a custom endpoint.

Controller API

const balancer = attachRdsReplicaBalancer(sequelize, options);

await balancer.syncNow();
balancer.start();
balancer.stop();
const topology = balancer.getTopology();
await balancer.destroy();

destroy() stops polling, restores the original Sequelize pool, and destroys plugin-managed reader pools.

Helper constructor

import { createRdsAwareSequelize } from "sequelize-rds";

const { sequelize, balancer } = await createRdsAwareSequelize(
  Sequelize,
  [process.env.DATABASE_URL!, { dialect: "postgres", pool: { max: 20 } }],
  {
    clusterIdentifier: "app-cluster",
    region: "us-east-1",
  },
);

The helper constructs Sequelize, performs an initial syncNow(), starts polling, and returns both objects.