The Big Picture — From Zero to Production
Running Roomzin as a complete global platform requires five steps.
Each step is independent,
and you can start small—a single shard—then scale out as your inventory grows.
A small HTTP service you provide. Resolves logical service IDs (e.g. node1)
to hostnames. Works with any infrastructure.
Export properties.csv
and packages.csv.
Run build-snapshot
to create the initial snapshot.
Launch RzID (registry). Start Roomzin shard nodes. Nodes auto-discover, elect a leader, and load the snapshot.
Run a bridge for each shard. The bridge is shard-aware — it knows the leader and followers. It routes writes to the leader and reads to followers. Routers cannot connect to shards without a bridge.
Deploy RzRouter (Edge + Zone modes) for global routing. Your platform is now ready.
RzPoint → CSVs → Snapshot → RzID + Shards → RzBridge → RzRouter
The platform is ready — you can connect to it using native SDKs or run RzProxy as an HTTP proxy alternative.
Data Model
Two tables. Only the fields used in searches.
Properties
Hotels and accommodation units
Daily Packages
Room type + date + availability + price
Roomzin stores only the hot window — the days to months that users actually search. Everything else stays in your database.
Properties
A hotel or accommodation unit. Roomzin uses Segment and Area instead of country, city, or neighborhood. Segment is required in every search query.
Daily Packages
Each property has a list of daily packages. A package represents one room type (Standard Double, Deluxe Suite, etc.) for one specific date — with availability, price, and policy tags.
Rate features — up to 24 policy tags per package: breakfast, cancellation policy, room amenities, and more.
Codecs — a YAML file that defines the list of rate features. Stored in RzID, fetched by all shards as an immutable copy. ⚠️ Changing codecs invalidates all existing snapshots — plan ahead.
Roomzin clusters are deployed per shard — isolated, independent, and unaware of each other.
Each shard is partitioned into segments,
the unit of geographic isolation for searches.
Example: One Medium Shard
Your numbers will vary
Segments
Properties
Room Types
Days
Records in-memory
Memory footprint: <4.2GB for 60M records. Even smaller than normalized data size.
Segment can be a city, a region with multiple smaller cities, or even part of a busy city like New York.
Constraints by Design
Deliberate performance trade-offs for optimal speed and reliability
Critical Considerations
-
Any change to
codecs.ymlwill invalidate existing queries - Requires a full restart of the cluster or standalone instance
- All existing snapshots will be dropped as they become invalid
- Modifications should be treated as an admin-level operation
Codecs Configuration
Rate features must be defined in codecs.yml
file. This file follows a specific schema, with up to
24 rate features.
Performance Trade-off: The limits of 24 rate features may seem restrictive, but they are a deliberate trade-off for optimal performance.
Schema Definition
The schema for codecs.yml:
rate_features:
- free_featurelation
- non_refundable
# ... up to 24 entries
Order Sensitivity: The order of entries is critical, as Roomzin uses this file for internal mapping.
Rate / Cancellation
Max: 24 entriesExample values (comma-separated):
Deployment
⚠️ Critical: Roomzin detects CPU core changes at runtime. If the hardware (number of cores) is modified while running, the application will automatically shut down for safety. Vertical scaling requires a restart — do not hot-add/remove CPUs without restarting the process.
Stand-alone
Dev / Single-Node
Drop the binary next to its config and codecs.yml, then run:
codecs.yml
is only used in standalone mode.
Clustered (Production)
Production ReadyNodes auto-discover each other. Only one seed is needed to pull the full peer list, provided the cluster graph stays connected.
Starting a Three-Node Cluster
Replace <node-id>
with node1,
node2, or
node3 on each
machine.
Learner Nodes
New nodes not in --initial-voters
join as learners. They catch up from the leader and can be promoted later.
Snapshot Restore
A strict majority of --initial-voters
must have the exact same snapshot. Empty nodes download from the leader.
Bulk Import
Build snapshots offline from CSVs. See Bulk Import for details.
Full Platform
All ComponentsRoomzin is the inventory engine. A complete production deployment requires these additional components:
RzID
GitHub →Control-plane registry. Topology + service identities. Not on the hot path.
RzPoint
You implementResolves logical service IDs to hostnames. Works with VMs, Kubernetes, or cloud. Docs →
RzBridge
GitHub →Shard-aware connector. Writes → leader, reads → followers.
RzRouter
GitHub →Single binary, two modes: Edge (entry point) and Zone (intra-zone routing).
💡 Deployment order: RzID → Roomzin nodes → RzBridge → RzRouter (Zone then Edge). RzPoint must be available before any component that resolves service identities.
RzPoint — Customer-Implemented Resolver
⚠️ Not provided by Roomzin. RzPoint is a small HTTP service that you implement based on your infrastructure.
Roomzin components work with logical service identities rather than IP addresses. RzPoint translates these identities into hostnames where services can be reached.
Roomzin Nodes & RzBridge
Resolve node identities within a shard:
GET /shards/{shard_id}/nodes/{node_id}
Returns: hostname
RzRouter
Resolve next-hop routers or bridges:
GET /routers/{router_id}
GET /bridges/{bridge_id}
Returns: hostname
Implementation Example
A minimal implementation might use a static mapping or query a service registry:
# Static mapping example (YAML)
shards:
shard1:
nodes:
node1: "node1.internal.company"
node2: "node2.internal.company"
node3: "node3.internal.company"
routers:
router-edge-1: "router-edge-1.internal.company"
bridges:
bridge-1: "bridge-1.internal.company"
Note: RzPoint returns hostnames, not IP addresses. Resolution to IPs is handled by the OS DNS layer. In production, you would query Kubernetes API, Consul, etcd, or your internal service registry to return the appropriate hostname.
💡 Why this matters: RzPoint separates service identity from network location. Roomzin components stay infrastructure-agnostic — you decide how hostnames are resolved.
Bulk Import
Initialize a shard by building a snapshot from CSV files.
Roomzin builds snapshots directly from CSV files — much faster than insert queries. Over 2.5 million records per second.
This is a one-time initialization for new shards.
What You Need
Two CSV files per shard, placed in the same directory:
Hotels and their attributes
Room types + dates + availability + prices
Command
shard1
data_dir)
codecs.yml in input
directory
File Formats
properties.csv
prop_1,segment_1,New York,hotel,test,4,40.713800,-74.005000,wifi|pool|gym|parking
packages.csv
prop_1,room_1,2025-10-03,7,120,free_cancellation|non_refundable|pay_at_property|includes_breakfast
⚠️ RateFeature must match codecs.
The pipe-separated values in RateFeature must exactly match
the rate features defined in your codecs (from RzID or codecs.yml).
Mismatches will cause import failures.
🔒 Codecs are immutable. If you change the codec list after building a snapshot, all snapshots become invalid. Plan your rate features carefully before importing.
💡 Room type limit. Up to 256 room types per property. For best performance, keep it under 10.
Next Step
Place the generated snapshot files in the data_dir
configured in roomzin.yml.
The snapshot loads at startup.
See Deployment for cluster setup.
Configuration
Complete example with all available options:
# ========== Core Settings ==========
# Number of cores reserved for system tasks.
# 0 = auto-detect (recommended, ~50% of available cores). Tune only after benchmarking.
# (optional, default: 0)
sys_cores_count: 0
# Average number of room types per property.
# Used for internal resource allocation.
# (optional, default: 6)
avg_room_types_per_property: 6
# ========== TCP Settings ==========
# TCP port for client connections
# (optional, default: 7777)
tcp_port: 7777
# Maximum concurrent TCP connections
# (optional, default: 10000)
tcp_max_connections: 10000
# TCP user timeout in milliseconds
# (optional, default: 200)
tcp_user_timeout_ms: 200
# TCP keepalive interval in seconds
# (optional, default: 30)
tcp_keepalive_seconds: 30
# TCP receive buffer size in bytes
# (optional, default: 262144)
tcp_recv_buffer_size: 262144
# TCP send buffer size in bytes
# (optional, default: 131072)
tcp_send_buffer_size: 131072
# ========== Cluster Settings ==========
# Port for cluster communication (Raft/RPC)
# (optional, default: 17777)
quic_port: 17777
# Raft tick interval in milliseconds
# (optional, default: 30)
raft_tick_ms: 30
# Raft election timeout in ticks
# (optional, default: 60)
raft_election_tick: 60
# Raft heartbeat interval in ticks
# (optional, default: 15)
raft_heartbeat_tick: 15
# RzID heartbeat interval in seconds
rzid_heartbeat_secs: 5
# ========== Server Settings ==========
# API port for HTTP endpoints
# (optional, default: 8080)
api_port: 8080
# Hour of day for maintenance tasks (0-23)
# (optional, default: 0)
maintenance_hour: 3
# Maximum number of dates allowed in a single query
# (optional, default: 14)
max_dates_in_query: 14
# Maximum number of results per query
# (optional, default: 200)
query_limit: 200
# Snapshot creation interval in seconds
# (optional, default: 60)
snapshot_interval_sec: 60
# Number of WAL entries before triggering snapshot
# (optional, default: 10000)
snapshot_trigger_count: 10000
# WAL flush threshold (number of entries)
# (optional, default: 2000)
wal_flush_threshold: 2000
Ready to run? Head to Quick Cluster
API
Standalone Mode
Available when running in standalone mode:
| Endpoint | Method | Description | Response |
|---|---|---|---|
| /healthz | GET | Node health status | "active" or "unavailable" |
| /metrics | GET | System metrics in Prometheus format | Prometheus Text |
Clustered Mode
Available when running in clustered mode:
| Endpoint | Method | Description | Response |
|---|---|---|---|
| /healthz | GET | Node health status | "active_leader" or "active_follower" or "unavailable" |
| /metrics | GET | System metrics in Prometheus format | Prometheus Text |
| /codecs | GET | Retrieve configured rate features | JSON |
| /node-info | GET |
Get detailed node information Returns: leader_id, shard_id, zone_id, node_id |
JSON Object |
| /leader | GET | Get current cluster leader ID | JSON (string) |
| /peers | GET | Get cluster peer list | JSON Array |
| /admin/add-member/{node_id} | POST | Promote learner to voting member | "add in progress" |
| /admin/remove-member/{node_id} | POST | Demote voting member to learner | "remove in progress" |
| /admin/transfer-leader/{node_id} | POST | Initiate leadership transfer | "transfer in progress" |
Core Commands
Primary Operations
Search & Query
Availability Management
Utility Queries
Delete Operations
For detailed rules and payload structures of all commands refer to the specifications of SDKs/RzProxy on their repository.
Connect to Roomzin
Native SDKs
HTTP/JSON Access via RzProxy
Lightweight HTTP/JSON proxy for legacy systems, third-party integrations, or languages without a native SDK. ~10–15% overhead.
Benchmarking Roomzin & RzProxy
Measure Roomzin's performance with precision.
Comprehensive benchmarking suite for both Roomzin (TCP/binary protocol) and RzProxy (HTTP/JSON
proxy).
Supports regular and spike load patterns with customizable queries.
Quick Setup
One command downloads everything you need: binaries, config files, certificates, and data generation scripts. Just run and start benchmarking in minutes.
Note
The downloaded zip includes a benchmark_guide.txt file with complete
instructions.
Complete documentation, examples, and source code available on GitHub
Quick Cluster — Run Roomzin in Minutes
A complete Roomzin cluster with one command.
Pre-configured distributed inventory system with 2 shards, full routing stack, and matching sample
queries.
Perfect for local development, testing, and evaluation.
Quick Setup
One command downloads everything: binaries, certificates, configurations, and test data.
Note
The downloaded files include a quick-start.txt file with complete
instructions.
Complete documentation and source code available on GitHub