Current limitations
Prototype limitations
The relay is a prototype. The following limitations are known and must be understood before any deployment.
The relay's intended operating model is a public reusable relay: general-purpose infrastructure open to any Nostr client or user, not limited to Nostrfi's own products or team. The limitations below are what currently stand between the prototype and that goal; several earlier limitations have since been resolved and are noted as such rather than removed, so links to this page stay valid.
Unenforced limits
Resolved. Advertised NIP-11 limits (max message length, subscription and
filter counts, content length, tag count, timestamp bounds, proof-of-work,
and auth requirements) are now enforced on the request path, not just
advertised. See the source repository's README.md for the exact behavior
and defaults for each limit.
Tag fidelity
Stored tags retain only their first two fields, so events read from storage do not preserve full multi-field tags. Markers, relay hints, and other trailing values are not reconstructed. This remains open.
No TLS
The relay application itself still provides no native TLS — that boundary is
deliberate, not a gap: TLS termination is treated as a deployment-layer
responsibility. A documented, exercised TLS-terminating reverse-proxy overlay
now exists (Caddy, via docker-compose.tls.yml in the source repository) for
operators who need it.
WebSocket origins
Resolved. The WebSocket origin policy is now configurable, with a fail-closed production mode: an internet-facing deployment must set an explicit allow-list or the relay refuses to start. A permissive development mode remains available and is the default.
Single-instance
The design is single-instance. Connected clients, subscriptions, authentication, live broadcasts, and Negentropy sessions are local to one process. No inter-instance event bus or shared connection state exists. Horizontal scaling requires architectural work. This remains open.
No backup or retention policy
Resolved. A versioned schema-migration runner, a background worker that
purges expired events (and their tags) on a configurable interval, and
-backup/-restore flags using DuckDB's native export/import (with an
integrity-verified manifest) all now exist. Deletion and replacement on the
existing delete/replace code paths still do not remove associated tag
rows, which can create orphaned index data over time — that specific gap
remains open, tracked separately from the retention work above.
No health or metrics
Resolved. /healthz and /readyz endpoints exist, and /metrics exposes
Prometheus-format metrics (connections, messages by type, rejections by
reason, subscriptions, query latency, events stored, and save failures) with
cardinality-bounded labels. An initial, explicitly provisional dashboard and
alert set is documented, pending a formally approved service-level
objective. Distributed tracing remains open.
Authentication gaps
Resolved. The NIP-42 relay tag is now validated against the relay's
configured canonical URL (not just checked for presence), and authentication
events outside a configurable freshness window are rejected. Authentication
sessions are still not durable across connections.
No production-readiness claim
The relay has not been deployed as a public production service. Most of the production-readiness checklist in the development operation guide is now complete; load-testing and threat-modeling remain open.
Previous
Relay role and architecture