menuTicketing

What Is Ticketing?


Why Distributed Locking

When multiple processes or multiple servers touch the same resource (an account, an order, inventory, a batch job, etc.) at the same time, contention arises. Language-built-in mutexes or semaphores are only valid within a single process — when there are multiple processes, or they're spread across multiple servers, you need a separate mutual-exclusion mechanism that crosses process boundaries.

Ticketing is a lock server and a family of clients built to solve exactly this problem: distributed mutual exclusion across process and server boundaries. A client connects to the lock server over TCP, acquires a named key, passes through the critical section, and releases it.

Core Philosophy

⚡ Lightweight and Fast

Ticketing uses a frame protocol made of fixed-width binary fields, not JSON. After a 1-byte op dispatch, it reads a fixed number of bytes per op as the length, and only the trailing key is read up to a newline (\n). Parsing is closer to plain offset reads than actual parsing, so the overhead is lower than parsing JSON on every request.

🔑 Safety via Fencing Tokens

Every time a lock is acquired, the server hands back a monotonically increasing u64 fencing token along with it. If the protected resource is made to verify the monotonicity of this token, it can refuse access from a client that wakes up late after its lease expired and tries to use a lower token. As a result, the lock server itself doesn't need to be perfectly consistent at every instant to keep things safe — this matters especially during failover.

🔄 Zero-Downtime Cluster

A single server works fine on its own (single mode), but if you need zero-downtime operation, form a cluster with at least 2 nodes. The cluster elects one active node based on priority, not consensus (quorum) — the rest become standbys receiving real-time replication. If the active dies (including restarts) or shuts down gracefully, a standby takes over. See the How It Works page for details.

🌐 Language-Agnostic

On top of the same binary protocol, official clients are provided for 8 languages: Rust, Java/Kotlin, JavaScript/TypeScript, Python, C#, Go, Ruby, and C/C++. Each language exposes the API in a way natural to its ecosystem — for example, async/await-style languages get async APIs, while Go/Ruby/C get blocking APIs backed by a background thread. The protocol is byte-identical across every language. See the Libraries page for language-specific installation instructions and examples.