### Setup Dependencies and Start Server Source: https://github.com/supabase/realtime/blob/main/DEVELOPERS.md After the database is running, set up dependencies and start the Realtime server. This requires mise to be active. ```bash mix setup mise run dev ``` -------------------------------- ### Start Local Realtime Server Source: https://github.com/supabase/realtime/blob/main/DEVELOPERS.md Use this command to start the Postgres databases required by Realtime. Ensure mise is installed and activated. ```bash mise run db-start ``` -------------------------------- ### Realtime Application Configuration Source: https://github.com/supabase/realtime/blob/main/_autodocs/configuration.md Example of application configuration in `config/runtime.exs`. This covers database connection details, JWT secrets, tenant limits, extension setup, and janitor settings. ```elixir config :realtime, # Database db_host: System.get_env("DB_HOST"), db_port: Realtime.Env.get_integer("DB_PORT", 5432), db_name: System.get_env("DB_NAME"), db_enc_key: System.get_env("DB_ENC_KEY") |> String.to_charlist(), # Authentication api_jwt_secret: System.get_env("API_JWT_SECRET"), # Defaults tenant_max_concurrent_users: Realtime.Env.get_integer("TENANT_MAX_CONCURRENT_USERS", 200), tenant_max_events_per_second: Realtime.Env.get_integer("TENANT_MAX_EVENTS_PER_SECOND", 100), # Features extensions: %{ "postgres_cdc_rls" => %{ supervisor: Extensions.PostgresCdcRls.Supervisor, worker: Extensions.PostgresCdcRls.Worker } }, # Monitoring run_janitor: Realtime.Env.get_boolean("RUN_JANITOR", true) ``` -------------------------------- ### Start Realtime Stack with Docker Compose Source: https://github.com/supabase/realtime/blob/main/DEVELOPERS.md Run the entire Realtime stack in containers using Docker Compose. This is an alternative to installing Elixir locally. ```bash mise run realtime-start ``` -------------------------------- ### Start Forum.Census in Supervision Tree Source: https://github.com/supabase/realtime/blob/main/forum/README.md Configure and start the Forum.Census process under your application's supervision tree. This example specifies the group name as `:users`, sets 8 partitions for concurrency, and a broadcast interval of 5000 milliseconds. ```elixir children = [ {Forum.Census, [:users, partitions: 8, broadcast_interval_in_ms: 5_000]} ] ``` -------------------------------- ### Start Additional Local Node Source: https://github.com/supabase/realtime/blob/main/DEVELOPERS.md Optional command to start another node in the local Realtime cluster. ```bash mise run dev-orange ``` -------------------------------- ### Configuration Options Source: https://github.com/supabase/realtime/blob/main/_autodocs/MANIFEST.txt Comprehensive guide to environment variables and configuration settings for Supabase Realtime. ```APIDOC ## Configuration ### Description Details over 120 environment variables and configuration parameters used to customize Supabase Realtime's behavior, including connection, database, authentication, and cluster settings. ### Configuration Areas - **Connection & Database**: Settings for establishing and managing database connections. - **Authentication**: Configuration related to user authentication and JWT handling. - **Cluster & GenRPC**: Settings for multi-node deployments and inter-service communication. - **Tenant & Rate Limiting**: Parameters for managing tenants and controlling request rates. - **Broadcast, Presence, WebSocket**: Specific configurations for real-time features. - **Monitoring & Logging**: Settings for observability, including metrics and OpenTelemetry. - **Tenant Schema & Extensions**: Configuration for tenant-specific schemas and custom extensions. ``` -------------------------------- ### Build and Run Tests with Bun Source: https://github.com/supabase/realtime/blob/main/test/e2e/README.md Build the executable binary using Bun and then run the tests. Requires Bun to be installed. ```bash bun install bun run build ./realtime-check --project --publishable-key --secret-key --db-password ``` -------------------------------- ### Complete CDC Connection Setup Source: https://github.com/supabase/realtime/blob/main/_autodocs/modules.md Finalizes the CDC connection setup process with the given module, response, settings, changes, and tenant ID. ```elixir def after_connect(module, response, settings, changes, tenant_id) ``` -------------------------------- ### Run Local Project Tests Source: https://github.com/supabase/realtime/blob/main/test/e2e/README.md Execute tests against a local Supabase project. Ensure 'supabase start' is run beforehand. ```bash supabase start ./realtime-check --env local --publishable-key --secret-key ``` -------------------------------- ### Join a Channel Source: https://github.com/supabase/realtime/blob/main/_autodocs/websocket-api.md This example demonstrates how to join a realtime channel using the `phx_join` event. It includes configurations for broadcast, presence, and postgres changes. ```APIDOC ## Join a Channel ### Description This operation allows a client to join a specific realtime channel. The payload includes configuration options for how the client wishes to receive updates. ### Event `phx_join` ### Topic `realtime:` ### Payload ```json { "config": { "broadcast": { "self": true, "ack": false, "replay": "latest_message", "replication_ready": false }, "presence": { "key": "user_id" }, "postgres_changes": [ { "event": "*", "schema": "public", "table": "users" } ] } } ``` ### Configuration Object Details: #### Broadcast Configuration - **self** (boolean) - Optional - Whether to receive your own broadcast messages. Defaults to `false`. - **ack** (boolean) - Optional - Whether to acknowledge broadcast messages. Defaults to `false`. - **replay** (string) - Optional - Message replay mode. Can be `latest_message` (default) or `all_messages` (requires `replay_from_ms`). - **replay_from_ms** (number) - Optional - Unix timestamp in milliseconds to replay messages from. Used with `all_messages` replay mode. - **replication_ready** (boolean) - Optional - Whether to wait for replication connection establishment before considering join successful. Defaults to `false`. #### Presence Configuration - **key** (string) - Required - Unique identifier for tracking presence state of this user. #### Postgres Changes Configuration An array of objects, each specifying a table and event to subscribe to: - **event** (string) - Required - Event type filter: `INSERT`, `UPDATE`, `DELETE`, or `*` for all. - **schema** (string) - Required - PostgreSQL schema name (e.g., `public`). - **table** (string) - Required - PostgreSQL table name. - **filter** (string) - Optional - RLS policy filter expression. - **columns** (array) - Optional - List of columns to include in changes. ``` -------------------------------- ### Example WebSocket Connection URL Source: https://github.com/supabase/realtime/blob/main/_autodocs/modules.md Illustrates the format for connecting to the WebSocket endpoint, including query parameters for authentication and logging. ```text ws://localhost:8000/socket?apikey=abc123&log_level=info ``` -------------------------------- ### Get or Start Tenant Database Connection Source: https://github.com/supabase/realtime/blob/main/_autodocs/modules.md Retrieves an existing database connection for a given tenant ID or establishes a new one if none exists. Connections are cached for reuse. Handles various connection errors like rate limiting or unavailability. ```elixir def lookup_or_start_connection(tenant_id) ``` -------------------------------- ### Conventional Commit Examples Source: https://github.com/supabase/realtime/blob/main/CONTRIBUTING.md Examples of correctly formatted commit messages following the Conventional Commits specification. Use 'fix' for bug fixes and 'feat' for new features. ```text fix: properly clean up subscriptions when oids changed ``` ```text feat: split gen rpc pools for calls vs casts ``` ```text fix stuff ``` ```text updates ``` -------------------------------- ### Run Tests with Bun (No Build) Source: https://github.com/supabase/realtime/blob/main/test/e2e/README.md Execute tests directly using Bun without building the binary. Requires Bun to be installed. ```bash bun install bun run check -- --project --publishable-key --secret-key --db-password ``` -------------------------------- ### List All Tenants API Response Source: https://github.com/supabase/realtime/blob/main/_autodocs/http-api.md Example JSON response when listing all tenants. It includes detailed configuration and metadata for each tenant. ```json [ { "id": "uuid", "name": "Project Name", "external_id": "proj_123abc", "jwt_secret": "encrypted_secret", "jwt_jwks": null, "postgres_cdc_default": "postgres_cdc_rls", "max_concurrent_users": 200, "max_events_per_second": 1000, "max_presence_events_per_second": 1000, "max_payload_size_in_kb": 3000, "max_bytes_per_second": null, "max_channels_per_client": 100, "max_joins_per_second": 100, "suspend": false, "private_only": false, "migrations_ran": 2, "broadcast_adapter": "gen_rpc", "max_client_presence_events_per_window": null, "client_presence_window_ms": null, "presence_enabled": false, "feature_flags": {}, "inserted_at": "2024-01-01T00:00:00Z", "updated_at": "2024-01-01T00:00:00Z" } ] ``` -------------------------------- ### Example JWT Claim Validators Source: https://github.com/supabase/realtime/blob/main/DEVELOPERS.md Example configuration for JWT claim validators. These are used to verify specific claims within JWTs for authorization. ```text e.g. {'iss': 'Issuer', 'nbf': 1610078130} ``` -------------------------------- ### Run Local Project Tests with Tracing Source: https://github.com/supabase/realtime/blob/main/test/e2e/README.md Configure tests to send tracing data to an OTLP endpoint. Requires 'supabase start' and 'docker compose up -d' for Jaeger. ```bash supabase start docker compose up -d # starts Jaeger at http://localhost:16686 ./realtime-check --env local --publishable-key --secret-key --otel http://localhost:4318 ``` ```bash ./realtime-check --env local --publishable-key --secret-key \ --otel https://otlp.example.com --otel-token ``` -------------------------------- ### Module Reference Source: https://github.com/supabase/realtime/blob/main/_autodocs/MANIFEST.txt Detailed reference for core Elixir modules within Supabase Realtime, including function signatures and usage examples. ```APIDOC ## Modules ### Description Provides detailed documentation for the core Elixir modules of Supabase Realtime, including function signatures, parameter types, return values, and usage examples. ### Key Modules - **Realtime.Messages**: Functions for message replay and cleanup. - **Realtime.Crypto**: Encryption and decryption utilities. - **Realtime.Env**: Environment variable parsing logic. - **Realtime.Database**: Database connection configuration and management. - **RealtimeWeb**: Channel and socket handlers for the WebSocket interface. - **Realtime.Tenants**: Cache and connection management for tenants. ### Function Signatures Includes exact type signatures for exported functions, ensuring clarity on usage and expected inputs/outputs. ``` -------------------------------- ### Get Tenant Source: https://github.com/supabase/realtime/blob/main/_autodocs/http-api.md Retrieves details for a specific tenant using its external ID. ```APIDOC ## Get Tenant ### Description Retrieves details for a specific tenant. ### Method GET ### Endpoint /api/tenants/ ### Parameters #### Path Parameters - **tenant_id** (string) - Required - External tenant ID ### Response #### Success Response (200) Returns a single tenant object with the same structure as the list response. #### Error Response (404) Tenant not found. ``` -------------------------------- ### Join Realtime Channel Source: https://github.com/supabase/realtime/blob/main/_autodocs/modules.md Use this function to join a channel and establish subscriptions. Ensure the topic starts with 'realtime:'. The params map configures broadcast, presence, and postgres_changes. ```elixir def join("realtime:" <> sub_topic, params, socket) ``` -------------------------------- ### Get environment variable as binary string Source: https://github.com/supabase/realtime/blob/main/_autodocs/modules.md Retrieves an environment variable as a binary string, supporting a default value or a lazy-evaluated function for the default. ```elixir db_host = Realtime.Env.get_binary("DB_HOST", "localhost") app_name = Realtime.Env.get_binary("APP_NAME", fn -> "realtime-" <> Node.self() end) ``` -------------------------------- ### Get Tenant by External ID (Raises on Error) Source: https://github.com/supabase/realtime/blob/main/_autodocs/modules.md Retrieves tenant configuration by external ID. This function will raise an error if the tenant is not found, unlike `fetch_tenant_by_external_id` which returns an error tuple. ```elixir def get_tenant_by_external_id(external_id) ``` -------------------------------- ### Get Region Metrics Source: https://github.com/supabase/realtime/blob/main/_autodocs/http-api.md Get Prometheus-formatted metrics for a specific region. Requires JWT authentication. ```APIDOC ## GET /metrics/ ### Description Get metrics for a specific region. ### Method GET ### Endpoint /metrics/ ### Parameters #### Path Parameters - **region** (string) - Required - Region identifier ### Response #### Success Response (200) - **Body** (text/plain) - Region-specific Prometheus metrics in text format ``` -------------------------------- ### Build and Run Tests with Nix Source: https://github.com/supabase/realtime/blob/main/test/e2e/README.md Build the executable using Nix and run the tests. Requires Nix with flakes enabled. ```bash bun run nix ./result/bin/realtime-check --project --publishable-key --secret-key --db-password ``` -------------------------------- ### Get Metrics Source: https://github.com/supabase/realtime/blob/main/_autodocs/http-api.md Retrieve Prometheus-formatted metrics for the Realtime service. Requires JWT authentication. ```APIDOC ## GET /metrics ### Description Retrieve Prometheus-formatted metrics. ### Method GET ### Endpoint /metrics ### Headers - **Authorization** (string) - Required - Bearer ### Response #### Success Response (200) - **Body** (text/plain) - Prometheus metrics in text format ``` -------------------------------- ### Create Tenant Source: https://github.com/supabase/realtime/blob/main/_autodocs/http-api.md Creates a new tenant with the specified configuration. Requires authentication and a JSON content type. ```APIDOC ## Create Tenant ### Description Creates a new tenant. ### Method POST ### Endpoint /api/tenants ### Headers - **Authorization** (string) - Required - Bearer - **Content-Type** (string) - Required - application/json ### Request Body - **name** (string) - Required - Name of the new project. - **external_id** (string) - Required - Unique identifier for the tenant. - **jwt_secret** (string) - Required - JWT secret for authentication. - **max_concurrent_users** (integer) - Optional - Maximum concurrent users. - **max_events_per_second** (integer) - Optional - Maximum events per second. - **postgres_cdc_default** (string) - Optional - Default CDC configuration. - **max_bytes_per_second** (null) - Optional - Maximum bytes per second. - **max_channels_per_client** (integer) - Optional - Maximum channels per client. - **max_joins_per_second** (integer) - Optional - Maximum joins per second. - **max_presence_events_per_second** (integer) - Optional - Maximum presence events per second. - **max_payload_size_in_kb** (integer) - Optional - Maximum payload size in KB. - **suspend** (boolean) - Optional - Whether to suspend the tenant upon creation. - **private_only** (boolean) - Optional - Whether the tenant is private only. - **broadcast_adapter** (string) - Optional - Broadcast adapter to use. - **presence_enabled** (boolean) - Optional - Whether presence is enabled. - **extensions** (array) - Optional - List of extensions to configure. - **type** (string) - Type of the extension (e.g., "postgres_cdc_rls"). - **settings** (object) - Configuration settings for the extension. ### Request Example ```json { "name": "New Project", "external_id": "unique_project_id", "jwt_secret": "your-secret", "max_concurrent_users": 200, "max_events_per_second": 1000, "postgres_cdc_default": "postgres_cdc_rls", "max_bytes_per_second": null, "max_channels_per_client": 100, "max_joins_per_second": 100, "max_presence_events_per_second": 1000, "max_payload_size_in_kb": 3000, "suspend": false, "private_only": false, "broadcast_adapter": "gen_rpc", "presence_enabled": false, "extensions": [ { "type": "postgres_cdc_rls", "settings": { "db_host": "encrypted_host", "db_name": "db_name", "db_port": "encrypted_port", "db_user": "encrypted_user", "db_password": "encrypted_password" } } ] } ``` ### Response #### Success Response (201) Returns the newly created tenant object. ``` -------------------------------- ### Realtime.Database.from_tenant/3 Source: https://github.com/supabase/realtime/blob/main/_autodocs/modules.md Creates a database connection struct from a tenant. This function is used to configure the database connection details based on tenant-specific information. ```APIDOC ## from_tenant/3 ### Description Creates a database connection struct from a tenant. ### Signature ```elixir @spec from_tenant(Tenant.t(), binary(), :stop | :exp | :rand | :rand_exp) :: {:ok, t()} | {:error, :nxdomain} ``` ### Parameters #### Path Parameters - **tenant** (Tenant.t()) - Required - Tenant record - **application_name** (binary) - Required - Application name for connection - **backoff** (:stop | :exp | :rand | :rand_exp) - Optional - Backoff strategy (defaults to :rand_exp) ### Returns `{:ok, Database.t()}` or `{:error, :nxdomain}` ### Backoff Types - `:stop` - Stop retrying on connection failure - `:exp` - Exponential backoff - `:rand` - Random backoff - `:rand_exp` - Randomized exponential backoff ### Example ```elixir {:ok, db_config} = Realtime.Database.from_tenant(tenant, "realtime") {:ok, conn} = Postgrex.start_link(Map.from_struct(db_config)) ``` ``` -------------------------------- ### Tenant Health Check Response Source: https://github.com/supabase/realtime/blob/main/_autodocs/http-api.md Example JSON response for a tenant health check. Indicates the operational status and provides a message. ```json { "status": "ok" | "error", "message": "Tenant is healthy" | error message } ``` -------------------------------- ### Add a New Tenant to Realtime Server Source: https://github.com/supabase/realtime/blob/main/DEVELOPERS.md Create a new tenant by making a POST request to the Realtime API. Ensure 'name' and 'external_id' are unique. The Authorization token is signed with the API_JWT_SECRET from the local compose environment. ```bash curl -X POST \ -H 'Content-Type: application/json' \ -H 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiIiLCJpYXQiOjE2NzEyMzc4NzMsImV4cCI6MTcwMjc3Mzk5MywiYXVkIjoiIiwic3ViIjoiIn0._ARixa2KFUVsKBf3UGR90qKLCpGjxhKcXY4akVbmeNQ' \ -d $'{\n "tenant" : {\n "name": "realtime-dev",\n "external_id": "realtime-dev",\n "jwt_secret": "a1d99c8b-91b6-47b2-8f3c-aa7d9a9ad20f",\n "extensions": [\n {\n "type": "postgres_cdc_rls",\n "settings": {\n "db_name": "postgres",\n "db_host": "host.docker.internal",\n "db_user": "postgres",\n "db_password": "postgres",\n "db_port": "5432",\n "region": "us-west-1",\n "poll_interval_ms": 100,\n "poll_max_record_bytes": 1048576,\n "ssl_enforced": false\n }\n }\n ]\n }\n }' \ http://localhost:4000/api/tenants ``` -------------------------------- ### Create Database Connection from Tenant Source: https://github.com/supabase/realtime/blob/main/_autodocs/modules.md Use this function to create a database connection struct from tenant information. It requires a tenant record and an application name, and supports configurable backoff strategies for connection attempts. ```elixir {:ok, db_config} = Realtime.Database.from_tenant(tenant, "realtime") {:ok, conn} = Postgrex.start_link(Map.from_struct(db_config)) ``` -------------------------------- ### Create Database Connection from Settings Source: https://github.com/supabase/realtime/blob/main/_autodocs/modules.md This function creates a database connection struct from a map of settings, which are expected to be encrypted. It requires database host, port, name, user, and password within the settings map, along with an application name and backoff strategy. ```elixir settings = %{ "db_host" => "ENC(...)", "db_port" => "ENC(5432)", "db_name" => "ENC(postgres)", "db_user" => "ENC(postgres)", "db_password" => "ENC(password)" } {:ok, db_config} = Realtime.Database.from_settings(settings, "realtime") ``` -------------------------------- ### List All Tenants Source: https://github.com/supabase/realtime/blob/main/_autodocs/http-api.md Retrieves a list of all tenants configured in the system. Requires authentication. ```APIDOC ## List All Tenants ### Description Retrieves a list of all tenants. ### Method GET ### Endpoint /api/tenants ### Headers - **Authorization** (string) - Required - Bearer ### Response #### Success Response (200) - **id** (uuid) - Unique identifier for the tenant. - **name** (string) - Name of the project/tenant. - **external_id** (string) - Unique external identifier for the tenant. - **jwt_secret** (string) - Encrypted JWT secret. - **jwt_jwks** (null) - JWKS endpoint for JWT validation. - **postgres_cdc_default** (string) - Default CDC configuration. - **max_concurrent_users** (integer) - Maximum concurrent users allowed. - **max_events_per_second** (integer) - Maximum events per second. - **max_presence_events_per_second** (integer) - Maximum presence events per second. - **max_payload_size_in_kb** (integer) - Maximum payload size in KB. - **max_bytes_per_second** (null) - Maximum bytes per second. - **max_channels_per_client** (integer) - Maximum channels per client. - **max_joins_per_second** (integer) - Maximum joins per second. - **suspend** (boolean) - Whether the tenant is suspended. - **private_only** (boolean) - Whether the tenant is private only. - **migrations_ran** (integer) - Number of migrations run. - **broadcast_adapter** (string) - Broadcast adapter used. - **max_client_presence_events_per_window** (null) - Max client presence events per window. - **client_presence_window_ms** (null) - Client presence window in milliseconds. - **presence_enabled** (boolean) - Whether presence is enabled. - **feature_flags** (object) - Feature flags for the tenant. - **inserted_at** (string) - Timestamp of creation. - **updated_at** (string) - Timestamp of last update. ### Response Example ```json [ { "id": "uuid", "name": "Project Name", "external_id": "proj_123abc", "jwt_secret": "encrypted_secret", "jwt_jwks": null, "postgres_cdc_default": "postgres_cdc_rls", "max_concurrent_users": 200, "max_events_per_second": 1000, "max_presence_events_per_second": 1000, "max_payload_size_in_kb": 3000, "max_bytes_per_second": null, "max_channels_per_client": 100, "max_joins_per_second": 100, "suspend": false, "private_only": false, "migrations_ran": 2, "broadcast_adapter": "gen_rpc", "max_client_presence_events_per_window": null, "client_presence_window_ms": null, "presence_enabled": false, "feature_flags": {}, "inserted_at": "2024-01-01T00:00:00Z", "updated_at": "2024-01-01T00:00:00Z" } ] ``` ``` -------------------------------- ### Realtime.Env Source: https://github.com/supabase/realtime/blob/main/_autodocs/modules.md Utilities for loading and parsing environment variables. ```APIDOC ## get_integer/2 Parses an environment variable as an integer. ### Description Retrieves the value of an environment variable and attempts to parse it as an integer. If the variable is not set, it returns the provided default value. Raises an `ArgumentError` if the variable's value cannot be parsed as an integer. ### Signature ```elixir @spec get_integer(binary(), integer() | nil) :: integer() | nil ``` ### Parameters - **env** (binary) - Required - The name of the environment variable. - **default** (integer | nil) - Optional - The default value to return if the environment variable is not set. ### Returns The parsed integer value of the environment variable or the default value. ### Raises `ArgumentError` if the environment variable's value cannot be parsed as an integer. ### Example ```elixir port = Realtime.Env.get_integer("PORT", 8000) max_connections = Realtime.Env.get_integer("MAX_CONNECTIONS") ``` ``` ```APIDOC ## get_boolean/2 Parses an environment variable as a boolean. ### Description Retrieves the value of an environment variable and parses it as a boolean. It accepts "true", "1" as truthy values and "false", "0" as falsy values. If the variable is not set, it returns the provided default value. Raises an `ArgumentError` for any other invalid values. ### Signature ```elixir @spec get_boolean(binary(), boolean()) :: boolean() ``` ### Parameters - **env** (binary) - Required - The name of the environment variable. - **default** (boolean) - Required - The default boolean value if the environment variable is not set. ### Returns `true` or `false` based on the environment variable's value or the default. ### Accepts "true", "1" (truthy), "false", "0" (falsy). ### Raises `ArgumentError` for invalid values. ### Example ```elixir run_janitor = Realtime.Env.get_boolean("RUN_JANITOR", true) ``` ``` ```APIDOC ## get_binary/2 Gets an environment variable as a string. ### Description Retrieves the value of an environment variable as a binary string. If the variable is not set, it returns the provided default value, which can be a binary string or a function that lazily evaluates to a binary string. ### Signature ```elixir @spec get_binary(binary(), binary() | (-> binary())) :: binary() ``` ### Parameters - **env** (binary) - Required - The name of the environment variable. - **default** (binary | function) - Required - The default value or a lazy evaluation function. ### Returns The environment variable's string value or the default value. ### Example ```elixir db_host = Realtime.Env.get_binary("DB_HOST", "localhost") app_name = Realtime.Env.get_binary("APP_NAME", fn -> "realtime-" <> Atom.to_list(Node.self()) end) ``` ``` ```APIDOC ## get_list/2 Parses a comma-separated environment variable as a list. ### Description Retrieves a comma-separated string from an environment variable and parses it into a list of trimmed strings. If the variable is not set, it returns the provided default list. ### Signature ```elixir @spec get_list(binary(), [binary()]) :: [binary()] ``` ### Parameters - **env** (binary) - Required - The name of the environment variable. - **default** (list) - Required - The default list to return if the environment variable is not set. ### Returns A list of trimmed strings parsed from the environment variable or the default list. ### Example ```elixir blocklist = Realtime.Env.get_list("API_TOKEN_BLOCKLIST", []) # ENV: API_TOKEN_BLOCKLIST="token1, token2, token3" # => ["token1", "token2", "token3"] ``` ``` ```APIDOC ## get_charlist/2 Converts an environment variable to a charlist. ### Description Retrieves the value of an environment variable and converts it into a charlist. If the variable is not set, it returns the provided default charlist. ### Signature ```elixir @spec get_charlist(binary(), charlist()) :: charlist() ``` ### Parameters - **env** (binary) - Required - The name of the environment variable. - **default** (charlist) - Required - The default charlist to return if the environment variable is not set. ### Returns The charlist representation of the environment variable's value or the default charlist. ### Example ```elixir encoding = Realtime.Env.get_charlist("ENCODING", 'utf8') ``` ``` -------------------------------- ### Get PostgreSQL CDC Driver Module Source: https://github.com/supabase/realtime/blob/main/_autodocs/modules.md Returns the appropriate CDC driver module based on the specified CDC type. Currently supports 'postgres_cdc_rls' for CDC with RLS. ```elixir def driver(cdc_type) ``` -------------------------------- ### Realtime.Database.from_settings/3 Source: https://github.com/supabase/realtime/blob/main/_autodocs/modules.md Creates a database connection struct from settings. This function is useful when you have database connection details stored as settings, potentially encrypted. ```APIDOC ## from_settings/3 ### Description Creates a database connection struct from settings. ### Signature ```elixir @spec from_settings(map(), binary(), :stop | :exp | :rand | :rand_exp) :: {:ok, t()} | {:error, :nxdomain} ``` ### Parameters #### Path Parameters - **settings** (map) - Required - Database settings (encrypted) - **application_name** (binary) - Required - Application name for connection - **backoff** (:stop | :exp | :rand | :rand_exp) - Optional - Backoff strategy (defaults to :rand_exp) ### Returns Connection struct or error ### Required Settings - `db_host` (encrypted) - `db_port` (encrypted) - `db_name` (encrypted) - `db_user` (encrypted) - `db_password` (encrypted) ### Example ```elixir settings = %{ "db_host" => "ENC(...)", "db_port" => "ENC(5432)", "db_name" => "ENC(postgres)", "db_user" => "ENC(postgres)", "db_password" => "ENC(password)" } {:ok, db_config} = Realtime.Database.from_settings(settings, "realtime") ``` ``` -------------------------------- ### Realtime Channel Join Source: https://github.com/supabase/realtime/blob/main/_autodocs/modules.md Joins a channel and establishes subscriptions for broadcast, presence, and PostgreSQL changes. ```APIDOC ## join/3 Joins a channel and establishes subscriptions. ### Method `join(topic, params, socket)` ### Parameters #### Path Parameters - **topic** (string) - Required - Channel topic (must start with `realtime:`) #### Request Body - **params** (map) - Required - Join configuration. See `Params Structure` for details. - **socket** (Phoenix.Socket.t()) - Required - WebSocket socket. ### Params Structure ```elixir %{ "config" => %{ "broadcast" => %{ "self" => boolean(), "ack" => boolean(), "replay" => %{"since" => integer(), "limit" => integer()} }, "presence" => %{ "key" => string(), "enabled" => boolean() }, "postgres_changes" => [ %{ "event" => "INSERT|UPDATE|DELETE|*", "schema" => "public", "table" => "users" } ] }, "access_token" => "jwt_token", "user_token" => "jwt_token" } ``` ### Response #### Success Response (200) - `{:ok, state, socket}` - Successfully joined. #### Error Response - `{:error, reason}` - Join failed with error reason. ### Error Reasons - `unauthorized` - JWT validation failed. - `too_many_channels` - Channel limit exceeded. - `too_many_connections` - User limit exceeded. - `unable_to_set_policies` - RLS setup failed. - `tenant_not_found` - Tenant ID invalid. ``` -------------------------------- ### Realtime.Api.Tenant Source: https://github.com/supabase/realtime/blob/main/_autodocs/modules.md Tenant database schema and validation. ```APIDOC ## changeset/2 ### Description Validate tenant data for create/update. ### Signature def changeset(tenant, attrs) ### Validates - `external_id` required and unique - Either `jwt_secret` or `jwt_jwks` required - All integer fields are within valid ranges - Encryption of `jwt_secret` ``` ```APIDOC ## encrypt_jwt_secret/1 ### Description Encrypt JWT secret before storing. ### Behavior - Uses Realtime.Crypto.encrypt!/1 - Only runs on valid changesets ``` -------------------------------- ### Interact with Forum.Census Source: https://github.com/supabase/realtime/blob/main/forum/README.md Demonstrates how to join a process to a census group, check local member count, retrieve cluster-wide member count, and get a map of all member counts for a given group. Use these functions to manage and query group membership. ```elixir iex> Forum.Census.join(:users, {:tenant, 123}, self()) :ok iex> Forum.Census.local_member_count(:users, {:tenant, 123}) 1 iex> Forum.Census.member_count(:users, {:tenant, 123}) # cluster-wide 3 iex> Forum.Census.member_counts(:users) %{{:tenant, 123} => 3, {:tenant, 456} => 1} ``` -------------------------------- ### List All Available Mise Tasks Source: https://github.com/supabase/realtime/blob/main/DEVELOPERS.md Display all tasks available through the mise task runner for managing the Realtime development environment. ```bash mise task ls ``` -------------------------------- ### Cleanup Realtime Development Environment Source: https://github.com/supabase/realtime/blob/main/DEVELOPERS.md Commands to remove the database and Realtime resources created during local development. ```bash mise run db-rm mise run realtime-rm ``` -------------------------------- ### Architecture Overview Source: https://github.com/supabase/realtime/blob/main/_autodocs/MANIFEST.txt High-level overview of the Supabase Realtime architecture, components, and data flows. ```APIDOC ## Architecture ### Description Explains the high-level architecture of Supabase Realtime, detailing its core components, data flows, and design decisions. ### Core Components - **WebSocket Transport**: Manages client connections. - **Channels**: Abstractions for data streams. - **Tenancy**: Multi-tenancy support. - **Database Layer**: Interaction with PostgreSQL, including connection pools. - **Pub/Sub & Cluster Communication**: Use of GenRPC for inter-node communication. - **PostgreSQL CDC Integration**: Real-time data capture from PostgreSQL. ### Data Flows Describes how data flows for broadcast, presence, and Postgres changes through the system. ### Design Decisions Covers key design choices related to performance, memory optimization, failure handling, and deployment. ``` -------------------------------- ### Connect WebSocket with Parameters Source: https://github.com/supabase/realtime/blob/main/_autodocs/modules.md Handles WebSocket connection requests, accepting query parameters like `apikey` and `log_level`. Ensure correct parameters are provided for authentication and logging. ```elixir def connect(params, socket, opts) ``` -------------------------------- ### Join a Channel with Configuration Source: https://github.com/supabase/realtime/blob/main/_autodocs/websocket-api.md Use this JSON payload to join a realtime channel and configure broadcast, presence, and postgres changes. The `config` object allows fine-grained control over message reception and data filtering. ```json { "topic": "realtime:", "event": "phx_join", "payload": { "config": { "broadcast": { "self": true, "ack": false, "replay": "latest_message", "replication_ready": false }, "presence": { "key": "user_id" }, "postgres_changes": [ { "event": "*", "schema": "public", "table": "users" } ] } }, "ref": 1 } ``` -------------------------------- ### Establish CDC Connection Source: https://github.com/supabase/realtime/blob/main/_autodocs/modules.md Initiates a CDC connection using the provided driver module and arguments. Returns the connection response or an error reason. ```elixir def connect(module, args) ``` -------------------------------- ### Run Remote Project Tests Source: https://github.com/supabase/realtime/blob/main/test/e2e/README.md Execute tests against a remote Supabase project using project reference and keys. Database password is required for staging/prod environments. ```bash ./realtime-check --project --publishable-key \ --secret-key --db-password ``` -------------------------------- ### Realtime Tenant Configuration Table Schema Source: https://github.com/supabase/realtime/blob/main/_autodocs/architecture.md Defines the schema for the `_realtime.tenants` table, which stores configuration for each tenant. This includes JWT secrets, rate limits, and feature flags. ```sql _realtime.tenants table: ├─ id: UUID (primary key) ├─ external_id: string (unique) ├─ jwt_secret: encrypted string ├─ max_concurrent_users: integer ├─ max_events_per_second: integer ├─ max_channels_per_client: integer ├─ feature_flags: JSON └─ extensions: relation to _realtime.extensions ``` -------------------------------- ### Realtime.Tenants.Connect Source: https://github.com/supabase/realtime/blob/main/_autodocs/modules.md Manages database connections to tenant databases. Connections are reused across operations for the same tenant. ```APIDOC ## lookup_or_start_connection/1 ### Description Get or create a database connection for a tenant. ### Signature def lookup_or_start_connection(tenant_id) ### Returns `{:ok, conn}` or `{:error, reason}` ### Error Reasons - `:unable_to_set_policies` - RLS policy setup failed - `:tenant_database_unavailable` - Cannot connect - `:connect_rate_limit_reached` - Too many connection attempts - `:initializing` - Connection being established ``` -------------------------------- ### Swagger UI Source: https://github.com/supabase/realtime/blob/main/_autodocs/http-api.md Access the Swagger UI for interactive API documentation. ```APIDOC ## GET /swaggerui/ ### Description Access the Swagger UI for interactive API documentation. ### Method GET ### Endpoint /swaggerui/ ``` -------------------------------- ### Channel Joining Source: https://github.com/supabase/realtime/blob/main/_autodocs/websocket-api.md Information on how to join channels after establishing a WebSocket connection. Channels are used for real-time data synchronization. ```APIDOC ## Channel Joining ### Description Clients join channels using the topic pattern `realtime:` to subscribe to specific events or data streams. ### Channel Format ``` realtime: ``` where `` is any string that identifies the channel (e.g., channel name, database table name, custom topic). ### Channel Types - **Public channels**: Prefixed with `realtime:public-*`. Open to all authenticated users. - **Private channels**: Prefixed with `realtime:private-*` or other custom prefixes. Require authorization and support message replay. ``` -------------------------------- ### Realtime.PostgresCdc Source: https://github.com/supabase/realtime/blob/main/_autodocs/modules.md Manages PostgreSQL CDC extensions and drivers. ```APIDOC ## driver/1 ### Description Get the CDC driver module. ### Signature def driver(cdc_type) ### Returns `{:ok, module}` or `:error` ### Supported Types - `postgres_cdc_rls` - CDC extension with RLS support ``` ```APIDOC ## connect/2 ### Description Establish CDC connection. ### Signature def connect(module, args) ### Returns `{:ok, response}` or `{:error, reason}` ``` ```APIDOC ## after_connect/5 ### Description Complete CDC connection setup. ### Signature def after_connect(module, response, settings, changes, tenant_id) ``` -------------------------------- ### HTTP API Reference Source: https://github.com/supabase/realtime/blob/main/_autodocs/MANIFEST.txt Documentation for the Supabase Realtime HTTP API, covering RESTful endpoints for tenant management, broadcasting, and health checks. ```APIDOC ## HTTP API ### Description Details the RESTful API endpoints available for interacting with Supabase Realtime, including authentication, tenant management, and message broadcasting. ### Endpoints - **Tenant Management (CRUD)**: Operations for creating, reading, updating, and deleting tenants. - **Broadcast Messages**: Endpoints for sending messages to specific channels or tenants. - **Health Check**: Endpoint to verify the status of the Realtime service. - **Metrics**: Endpoints to retrieve operational metrics. ### Authentication Information on how to authenticate requests to the HTTP API. ### Rate Limiting Details on rate limiting policies and how they are applied to API requests. ### OpenAPI Specification Reference to the OpenAPI specification for a machine-readable definition of the HTTP API. ``` -------------------------------- ### WebSocket API Reference Source: https://github.com/supabase/realtime/blob/main/_autodocs/MANIFEST.txt Documentation for the Supabase Realtime WebSocket API, including connection details, channel operations, and event formats. ```APIDOC ## WebSocket API ### Description Provides details on establishing WebSocket connections, joining channels, and handling Realtime events like Broadcast, Presence, and Postgres Changes. ### Endpoints - **WebSocket Connection**: Establishes a persistent connection for real-time data synchronization. - **Channel Operations**: Joining, leaving, and subscribing to channels for specific data streams. ### Events - **Broadcast**: For sending and receiving arbitrary messages. - **Presence**: For tracking user presence within channels. - **Postgres Changes**: For subscribing to real-time changes in PostgreSQL tables. ### Message Formats Details on the structure of messages exchanged over the WebSocket connection, including system messages and event payloads. ### Error Handling Information on potential errors, their codes, and guidance for client-side error handling. ``` -------------------------------- ### Handle Channel Join Errors Source: https://github.com/supabase/realtime/blob/main/_autodocs/errors.md This callback is used to manage errors encountered when joining a channel. Reasons like 'ChannelRateLimitReached', 'ClientJoinRateLimitReached', 'Unauthorized', and 'RealtimeDisabledForConfiguration' indicate specific issues that need to be addressed by adjusting subscriptions, checking authentication, or verifying configuration. ```javascript channel.subscribe((status, reason) => { if (status === 'error') { // Handle channel join error switch (reason) { case 'ChannelRateLimitReached': case 'ClientJoinRateLimitReached': // Rate limited, reduce channel subscriptions break; case 'Unauthorized': // Check JWT and permissions break; case 'RealtimeDisabledForConfiguration': // Check Postgres Changes configuration break; } } }); ``` -------------------------------- ### WebSocket Connection Source: https://github.com/supabase/realtime/blob/main/_autodocs/websocket-api.md Details on how to establish a WebSocket connection to the Supabase Realtime API, including the endpoint URL and required parameters. ```APIDOC ## WebSocket Connection ### Description Establishes a WebSocket connection to the Supabase Realtime API. ### Endpoint ``` ws:///socket?apikey=&log_level= or wss:///socket?apikey=&log_level= ``` ### Parameters #### Query Parameters - **apikey** (string) - Required - API key for authentication. Can be passed as `x-api-key` header or `apikey` query parameter. - **log_level** (string) - Optional - Logging level. Accepts: `error`, `warning`, `info`. Defaults to `error`. ``` -------------------------------- ### RealtimeWeb.UserSocket.connect/3 Source: https://github.com/supabase/realtime/blob/main/_autodocs/modules.md Handles WebSocket connections to the Realtime server. Supports authentication via API key and configurable logging levels. ```APIDOC ## RealtimeWeb.UserSocket.connect/3 ### Description Handle WebSocket connection. Allows authentication using an API key and setting a logging level. ### Method connect ### Parameters #### Query Parameters - **apikey** (string) - Required - API key for authentication - **log_level** (string) - Optional - Logging level: `error`, `warning`, `info` #### Headers - **x-api-key** (string) - Alternative to apikey query param ### Request Example ``` ws://localhost:8000/socket?apikey=abc123&log_level=info ``` ### Response #### Success Response - **socket** (Phoenix.Socket.t()) - The established WebSocket socket #### Error Response - **reason** - The reason for connection failure ``` -------------------------------- ### Metrics Endpoints Source: https://github.com/supabase/realtime/blob/main/OBSERVABILITY_METRICS.md Supabase Realtime exposes metrics through two main endpoints: `/metrics` for high-priority system-level metrics and `/tenant-metrics` for lower-priority per-tenant metrics. Regional scoped endpoints are also available. ```APIDOC ## GET /metrics ### Description Retrieves high-priority metrics including BEAM/VM, OS, Phoenix, distributed infrastructure, and global aggregated tenant totals. These metrics do not have a `tenant` label. ### Method GET ### Endpoint /metrics ### Parameters #### Query Parameters None #### Request Body None ### Request Example None ### Response #### Success Response (200) Prometheus-formatted metrics. #### Response Example None ## GET /tenant-metrics ### Description Retrieves low-priority, per-tenant labeled metrics such as connection counts, channel events, replication, and authorization. ### Method GET ### Endpoint /tenant-metrics ### Parameters #### Query Parameters None #### Request Body None ### Request Example None ### Response #### Success Response (200) Prometheus-formatted metrics with per-tenant labels. #### Response Example None ## GET /metrics/:region ### Description Retrieves high-priority metrics scoped to a specific region. This includes BEAM/VM, OS, Phoenix, distributed infrastructure, and global aggregated tenant totals. ### Method GET ### Endpoint /metrics/:region ### Parameters #### Path Parameters - **region** (string) - Required - The region to scope the metrics to. #### Query Parameters None #### Request Body None ### Request Example None ### Response #### Success Response (200) Prometheus-formatted metrics for the specified region. #### Response Example None ## GET /tenant-metrics/:region ### Description Retrieves low-priority, per-tenant labeled metrics scoped to a specific region. This includes connection counts, channel events, replication, and authorization. ### Method GET ### Endpoint /tenant-metrics/:region ### Parameters #### Path Parameters - **region** (string) - Required - The region to scope the metrics to. #### Query Parameters None #### Request Body None ### Request Example None ### Response #### Success Response (200) Prometheus-formatted per-tenant metrics for the specified region. #### Response Example None ### Authentication All endpoints require a `Bearer` JWT token in the `Authorization` header signed with `METRICS_JWT_SECRET`. ```