OTP ERLANG Wiregrid Plainwire · Manual 1.0

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_sessions10,000100,0001,000,000
max_sessions_per_owner321281,024
max_subscription_edges100,0002,000,00020,000,000
max_room_edges50,0001,000,00010,000,000
max_room_grace50,0001,000,00010,000,000
max_room_states50,0001,000,00010,000,000
max_presence_watch_edges50,0001,000,00010,000,000
max_activity_entries50,000500,0005,000,000
max_receipt_entries100,0001,000,00010,000,000
max_rate_limit_buckets100,0001,000,0005,000,000
max_cache_entries25,000250,0002,000,000
max_resume_snapshots10,000100,0001,000,000
max_delivery_reservations100,0002,000,00020,000,000
max_cluster_dedupe100,000500,0002,000,000
max_remote_presence100,000500,0002,000,000
max_remote_room_edges100,0002,000,00020,000,000
max_memory_events250,0001,000,0005,000,000
max_expiry_entries250,0002,000,00020,000,000
max_control_pending2,00020,000100,000
max_callback_pending2562,0488,192
max_adapter_pending1281,0244,096
fanout_buckets3264256

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.

KeyDefault
profile:balanced
security_mode:trusted (:strict refuses AllowAll)
telemetry_metric_eventsfalse
readiness_pressure_threshold1.0 (number in (0, 1])
control_call_timeout_ms15,000
authorizer_mode:inline or :isolated
callback_timeout_ms100
adapter_mode:inline or :isolated
adapter_timeout_ms5,000
max_sessions_per_user32
max_sessions_per_owner128, then replaced by the profile
max_subscriptions_per_session2,048
max_presence_watches_per_session1,024
max_watchers_per_user100,000
max_rooms_per_session256
max_room_members100,000
max_activities_per_session512
max_receipts_per_session2,048
max_topic_bytes512
max_topic_depth4
max_user_id_bytes512
max_session_id_bytes96
max_storage_id_bytes256
max_metadata_bytes16,384
max_event_bytes1,048,576
max_encoded_event_bytes1,572,864
max_cache_key_bytes1,024
max_cache_value_bytes1,048,576
max_rate_limit_key_bytes1,024
max_websocket_frame_bytes1,048,576
max_batch_items512
max_batch_targets4,096
max_query_results10,000
soft_queue500
hard_queue2,000
fanout_buckets64, then replaced by the profile
reconnect_grace_ms15,000
resume_ttl_ms120,000
activity_ttl_ms5,000
receipt_ttl_ms86,400,000
max_ttl_ms604,800,000
expiry_tick_ms100
expiry_batch_size2,048
slow_consumer_action:disconnect or :exit_owner
presence_aggregation:priority or :latest
presence_priority[:online, :dnd, :idle, :offline]
clusterfalse
cluster_shards16 (maximum 256)
cluster_namespace:instance
cluster_dedupe_ttl_ms60,000
cluster_pending_per_shard10,000
authorizerWiregrid.Authorizer.AllowAll
codecWiregrid.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.

KeyDefault
max_message_bytes65,536
max_attachment_count32
max_mention_count100
max_reaction_bytes64
max_client_nonce_bytes128
max_chat_event_bytes262,144
message_rate_limit{30, 10_000}
activity_rate_limit{60, 10_000}
allow_empty_messages_with_attachmentstrue

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.

KeyHard maximum
max_pending1,000,000
max_concurrency1,024
max_body_bytes16,777,216
max_response_bytes16,777,216
max_header_bytes131,072
max_retries0 to 20
base_backoff_ms86,400,000, and not above max_backoff_ms
max_backoff_ms86,400,000
connect_timeout_ms300,000
request_timeout_ms300,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.

Wiregrid 1.0 · Plainwire · github.com/Plainwire-development/Wiregrid