Reference
Configuration
An instance is configured at start. There is no required application environment. Wiregrid.Config.build/1 rejects a non-keyword, a list longer than 128 entries, duplicate keys (:invalid_options), and unknown keys ({:unknown_options, keys}). The profile is applied first, then explicit options overwrite it.
Wiregrid.start_instance(:chat, profile: :balanced, max_sessions: 4_000)
Profiles
:small is the conservative set for development and modest services. :balanced is the default and the usual production start. :large raises ceilings. It does not preallocate the tables, and it is not a separate scheduler mode. Any other profile atom is {:invalid_profile, other}.
| Key | :small | :balanced | :large |
|---|---|---|---|
max_sessions | 10,000 | 100,000 | 1,000,000 |
max_sessions_per_owner | 32 | 128 | 1,024 |
max_subscription_edges | 100,000 | 2,000,000 | 20,000,000 |
max_room_edges | 50,000 | 1,000,000 | 10,000,000 |
max_room_grace | 50,000 | 1,000,000 | 10,000,000 |
max_room_states | 50,000 | 1,000,000 | 10,000,000 |
max_presence_watch_edges | 50,000 | 1,000,000 | 10,000,000 |
max_activity_entries | 50,000 | 500,000 | 5,000,000 |
max_receipt_entries | 100,000 | 1,000,000 | 10,000,000 |
max_rate_limit_buckets | 100,000 | 1,000,000 | 5,000,000 |
max_cache_entries | 25,000 | 250,000 | 2,000,000 |
max_resume_snapshots | 10,000 | 100,000 | 1,000,000 |
max_delivery_reservations | 100,000 | 2,000,000 | 20,000,000 |
max_cluster_dedupe | 100,000 | 500,000 | 2,000,000 |
max_remote_presence | 100,000 | 500,000 | 2,000,000 |
max_remote_room_edges | 100,000 | 2,000,000 | 20,000,000 |
max_memory_events | 250,000 | 1,000,000 | 5,000,000 |
max_expiry_entries | 250,000 | 2,000,000 | 20,000,000 |
max_control_pending | 2,000 | 20,000 | 100,000 |
max_callback_pending | 256 | 2,048 | 8,192 |
max_adapter_pending | 128 | 1,024 | 4,096 |
fanout_buckets | 32 | 64 | 256 |
fanout_buckets must be a positive integer no greater than 1,024. Above that, startup returns :fanout_buckets_too_large.
Base keys
These values apply on every profile unless an option overrides them. Positive-integer keys reject zero and negatives with :invalid_limits.
| Key | Default |
|---|---|
profile | :balanced |
security_mode | :trusted (:strict refuses AllowAll) |
telemetry_metric_events | false |
readiness_pressure_threshold | 1.0 (number in (0, 1]) |
control_call_timeout_ms | 15,000 |
authorizer_mode | :inline or :isolated |
callback_timeout_ms | 100 |
adapter_mode | :inline or :isolated |
adapter_timeout_ms | 5,000 |
max_sessions_per_user | 32 |
max_sessions_per_owner | 128, then replaced by the profile |
max_subscriptions_per_session | 2,048 |
max_presence_watches_per_session | 1,024 |
max_watchers_per_user | 100,000 |
max_rooms_per_session | 256 |
max_room_members | 100,000 |
max_activities_per_session | 512 |
max_receipts_per_session | 2,048 |
max_topic_bytes | 512 |
max_topic_depth | 4 |
max_user_id_bytes | 512 |
max_session_id_bytes | 96 |
max_storage_id_bytes | 256 |
max_metadata_bytes | 16,384 |
max_event_bytes | 1,048,576 |
max_encoded_event_bytes | 1,572,864 |
max_cache_key_bytes | 1,024 |
max_cache_value_bytes | 1,048,576 |
max_rate_limit_key_bytes | 1,024 |
max_websocket_frame_bytes | 1,048,576 |
max_batch_items | 512 |
max_batch_targets | 4,096 |
max_query_results | 10,000 |
soft_queue | 500 |
hard_queue | 2,000 |
fanout_buckets | 64, then replaced by the profile |
reconnect_grace_ms | 15,000 |
resume_ttl_ms | 120,000 |
activity_ttl_ms | 5,000 |
receipt_ttl_ms | 86,400,000 |
max_ttl_ms | 604,800,000 |
expiry_tick_ms | 100 |
expiry_batch_size | 2,048 |
slow_consumer_action | :disconnect or :exit_owner |
presence_aggregation | :priority or :latest |
presence_priority | [:online, :dnd, :idle, :offline] |
cluster | false |
cluster_shards | 16 (maximum 256) |
cluster_namespace | :instance |
cluster_dedupe_ttl_ms | 60,000 |
cluster_pending_per_shard | 10,000 |
authorizer | Wiregrid.Authorizer.AllowAll |
codec | Wiregrid.Codec.Term |
storage | {Wiregrid.Storage.Memory, []} |
cache | {Wiregrid.Cache.Memory, []} |
webhooks | [enabled: false] |
max_encoded_event_bytes must be at least max_event_bytes. activity_ttl_ms and receipt_ttl_ms must be at most max_ttl_ms. soft_queue must be below hard_queue. cluster_namespace may be an atom, a non-negative integer, a binary of 1 to 128 bytes, or a tuple of 1 to 4 such parts.
Chat façade defaults
Passed under chat: to use Wiregrid.Chat and checked by Wiregrid.Chat.Config. See the chat façade for the ceilings.
| Key | Default |
|---|---|
max_message_bytes | 65,536 |
max_attachment_count | 32 |
max_mention_count | 100 |
max_reaction_bytes | 64 |
max_client_nonce_bytes | 128 |
max_chat_event_bytes | 262,144 |
message_rate_limit | {30, 10_000} |
activity_rate_limit | {60, 10_000} |
allow_empty_messages_with_attachments | true |
Webhooks
Webhooks start disabled. enabled: true requires a non-empty allowlist of hostnames, each 1 to 253 bytes, at most 128 entries. Missing allowlist is :webhook_allowlist_required.
| Key | Hard maximum |
|---|---|
max_pending | 1,000,000 |
max_concurrency | 1,024 |
max_body_bytes | 16,777,216 |
max_response_bytes | 16,777,216 |
max_header_bytes | 131,072 |
max_retries | 0 to 20 |
base_backoff_ms | 86,400,000, and not above max_backoff_ms |
max_backoff_ms | 86,400,000 |
connect_timeout_ms | 300,000 |
request_timeout_ms | 300,000 |
Call Wiregrid.webhook(instance, url, body, opts). Destinations are resolved on every attempt. Private, link-local, loopback, and multicast targets are rejected. Redirects are not followed. Deliveries are signed.
Rate limits
{:ok, remaining} = Wiregrid.rate_limit(:chat, :login, ip, 30, 60_000)
{:ok, remaining} = Wiregrid.rate_limit(:chat, :send, user_id, 20, 10_000,
policy: :token_bucket, burst: 20)
Policies are :fixed_window and :token_bucket. Option keys are :policy, :burst, and :idle_ttl_ms. The window must be positive and at most max_ttl_ms. The key {bucket, key} must fit in max_rate_limit_key_bytes. Bucket rows are capped by max_rate_limit_buckets. A full table or a refused call increments :rate_limit_rejections. Token buckets update one ETS row with compare-and-swap and do not schedule a timer per hit.