The project is in a healthy, maintained state
Stores graphql-anycable subscription state in PostgreSQL.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies

Development

>= 2.0
>= 12.3.3
~> 3.0

Runtime

>= 1.3, < 3
>= 1.2
 Project Readme

GraphQL AnyCable PostgreSQL Store

Tests

PostgreSQL subscription store for graphql-anycable.

This gem stores GraphQL subscription state in PostgreSQL. It does not deliver AnyCable broadcasts itself; delivery still goes through the AnyCable broadcast adapter configured by the application.

This gem requires a graphql-anycable version that supports custom subscription stores and store-backed cleanup.

Installation

Add this line to your application's Gemfile:

gem "graphql-anycable_postgresql-store"

Then configure graphql-anycable to use the store:

GraphQL::AnyCable.configure do |config|
  config.subscription_store = :postgresql
end

The gem also registers :postgres as an alias for :postgresql.

Configuration

Configure the PostgreSQL connection and table names with environment variables:

GRAPHQL_ANYCABLE_POSTGRESQL_STORE_POSTGRES_URL=postgres://localhost:5432/postgres
GRAPHQL_ANYCABLE_POSTGRESQL_STORE_SUBSCRIPTIONS_TABLE=graphql_anycable_subscriptions
GRAPHQL_ANYCABLE_POSTGRESQL_STORE_SUBSCRIPTION_EVENTS_TABLE=graphql_anycable_subscription_events
GRAPHQL_ANYCABLE_POSTGRESQL_STORE_CHANNEL_SUBSCRIPTIONS_TABLE=graphql_anycable_channel_subscriptions

Or configure the gem from application code:

GraphQL::AnyCable::PostgreSQLStore.configure do |config|
  config.postgres_url = ENV["DATABASE_URL"]
  config.subscriptions_table = "graphql_anycable_subscriptions"
  config.subscription_events_table = "graphql_anycable_subscription_events"
  config.channel_subscriptions_table = "graphql_anycable_channel_subscriptions"
end

If postgres_url is not configured, the store falls back to AnyCable.config.postgres_url when available, then to DATABASE_URL. If none are set, PG.connect uses libpq defaults.

Database schema

Rails applications with ActiveRecord can install the migration:

bin/rails generate graphql:anycable:postgresql_store:install
bin/rails db:migrate

The generator skips migration creation when ActiveRecord generator support is not available.

Applications can also create the tables directly:

CREATE TABLE graphql_anycable_subscriptions (
  id text PRIMARY KEY,
  query_string text NOT NULL,
  variables text NOT NULL,
  context text NOT NULL,
  operation_name text NOT NULL,
  events jsonb NOT NULL DEFAULT '{}',
  expires_at timestamptz,
  created_at timestamptz NOT NULL DEFAULT CURRENT_TIMESTAMP,
  updated_at timestamptz NOT NULL DEFAULT CURRENT_TIMESTAMP
);

CREATE TABLE graphql_anycable_subscription_events (
  subscription_id text NOT NULL REFERENCES graphql_anycable_subscriptions(id) ON DELETE CASCADE,
  topic text NOT NULL,
  fingerprint text NOT NULL,
  created_at timestamptz NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (subscription_id, topic, fingerprint)
);

CREATE INDEX index_graphql_anycable_subscription_events_topic_fingerprint
  ON graphql_anycable_subscription_events (topic, fingerprint);

CREATE INDEX index_graphql_anycable_subscription_events_fingerprint
  ON graphql_anycable_subscription_events (fingerprint);

CREATE TABLE graphql_anycable_channel_subscriptions (
  channel_id text NOT NULL,
  subscription_id text NOT NULL REFERENCES graphql_anycable_subscriptions(id) ON DELETE CASCADE,
  created_at timestamptz NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (channel_id, subscription_id)
);

Stats

GraphQL::AnyCable.stats delegates to this store when subscription_store is configured as :postgresql or :postgres. The store reports active subscriptions, topics, fingerprints, and channels with SQL aggregate queries; scan_count is accepted for graphql-anycable interface compatibility and is not used by PostgreSQL.

Cleanup

GraphQL::AnyCable::Cleaner delegates to this store when subscription_store is configured as :postgresql or :postgres. The cleaner removes expired subscription rows; PostgreSQL foreign keys with ON DELETE CASCADE remove associated event and channel rows.

Development

Install dependencies and run tests:

GRAPHQL_ANYCABLE_PATH=../graphql-anycable bundle exec rspec

Set POSTGRES_URL or DATABASE_URL to run the store integration spec against PostgreSQL.

CI runs the spec suite against a PostgreSQL service and checks out the graphql-anycable interface branch until the custom store API is released.

Release

Release notes are kept in CHANGELOG.md. Follow RELEASE.md for the full RubyGems plus GitHub Releases workflow.

version=$(ruby -Ilib -rgraphql/anycable/postgresql_store/version -e 'puts GraphQL::AnyCable::PostgreSQLStore::VERSION')
bundle exec rake build
gem push "pkg/graphql-anycable_postgresql-store-${version}.gem"
gh release create "v${version}" "pkg/graphql-anycable_postgresql-store-${version}.gem"