Editions & Limits
patinaDB’s server (patinadb-raft) ships as one binary with three commercial
editions gated by a signed license token. This chapter is the
honest, public table of what each edition includes, what each limit
actually does when you hit it, and how to watch your own usage before you do.
The guiding principle: the wall is for the successful, never the evaluator. Community is deliberately generous — a real evening project, or even a medium-sized proof-of-concept, should never brush against a cap. The limits start to matter once a deployment is running real production traffic: needs failover, needs more than a couple of databases, or needs to keep the whole audit history forever.
The table
| Axis | Community | Pro | Enterprise | What it’s for |
|---|---|---|---|---|
| Cluster voters (HA) | 1 (no failover) | 5 | unlimited | A single voter has no automatic failover — production reliability needs more than one, which is the primary commercial wall. |
| Nodes + edges (combined) | 5,000,000 | 100,000,000 | unlimited | A backstop, not the main fence — generous enough that a real medium-graph evaluation never hits it. |
| Databases | 2 | 20 | unlimited | Multi-tenant / multi-workload isolation is a business feature. |
| History retention | 30 days rolling | unlimited | unlimited | Time-travel itself is free in every edition (see below) — keeping the entire timeline forever, for compliance/audit, is the Pro/Enterprise sell. |
| Fine-grained (per-label) security | off | on | on | GRANT/REVOKE READ|WRITE ON <db>:<Label> + the /mgmt/audit security log. |
| Point-in-time-recovery backup | off | on | on | GET /mgmt/snapshot?history=true — a portable backup that carries the whole engram timeline, not just HEAD state. |
| Telemetry | mandatory (degrades if unreachable) | best-effort, --disable-telemetry | best-effort, --disable-telemetry / fully air-gapped | See Licensing & Telemetry. |
Every other capability — full Cypher + Bolt, graph algorithms, full-text and vector search, spatial queries, time-travel itself, RBAC with blanket per-database roles, engrams/diffs, change streams, everything in this manual that isn’t in the table above — is identical across every edition. The limits above are the entire commercial fence; nothing else is gated.
What happens when you hit a limit
Two different things happen depending on which axis you hit, and neither one ever touches data that’s already there:
- The scale cap (nodes + edges) degrades to read-only. Once a database’s
combined node+edge count would cross the cap, further writes are
refused with a clear, actionable error (
503over REST, a Bolt failure) — your data stays exactly as it was, and every read keeps working normally. ADELETEthat shrinks the graph back under the cap is still allowed, so you can always recover headroom without needing to buy anything. This is the same mechanism the community telemetry gate uses (see Licensing & Telemetry) — a write choke-point that either lets a proposal through or refuses it with an upgrade message. - The cluster/database/feature caps refuse the specific operation. Trying
to promote a
(max_voters + 1)-th voter, create a(max_databases + 1)-th database, or run a feature-gated command (a per-labelGRANT,/mgmt/audit,?history=true) past Community’s ceiling fails loudly with an upgrade message — but the running system is completely untouched. Nothing you already have breaks; the specific action you tried just doesn’t happen.
History retention in practice
Community’s 30-day rolling retention window means: AS OF <engram> /
CALL patinadb.diff(<engram>) work for anything committed in roughly the last
30 days. Older history is periodically compacted (squashed into a single
snapshot at the retention boundary) rather than kept forever — this shrinks
the engram log, not the live graph, so HEAD data and every current query are
completely unaffected. A Pro or Enterprise license simply omits the retention
cap, so nothing is ever compacted and the full timeline (all the way back to
the very first commit) stays queryable.
Reading your own usage
GET /version (no authentication required, same as /health) reports the
resolved tier, every entitlement cap, and a live usage snapshot — so you can
see headroom before hitting a wall instead of finding out from a failed
write:
curl http://localhost:8080/version
{
"name": "patinadb-raft",
"version": "0.9.0",
"tier": "community",
"entitlements": {
"max_elements": 5000000,
"max_voters": 1,
"max_databases": 2,
"history_retention_days": 30,
"fine_grained_security": false,
"pitr_backup": false
},
"usage": {
"nodes": 812345,
"edges": 1204981,
"elements": 2017326,
"elements_usage_ratio": 0.403
}
}
elements_usage_ratio is null whenever the cap is unlimited (a licensed
Enterprise deployment, or any axis a license simply omits) — there is nothing
to divide against, so no ratio is ever emitted for an uncapped axis. Watch this
value (or scrape it — see below) and you’ll see the “you’re at 40% of the
community node limit” signal well before you ever hit the wall.
Prometheus
The same usage figures are exported as gauges on the existing /metrics
scrape endpoint:
patinadb_entitlement_usage_ratio{axis="elements"}— current / cap, current / cap, emitted only when theelementscap is finite.patinadb_entitlement_limit{axis="elements"|"voters"|"databases"}— the resolved numeric caps themselves, so a dashboard panel can render headroom without re-deriving it from the license.
Wire these into the same Grafana dashboard as the rest of the cluster metrics (see Configuration Reference and Cache Observability & Tuning for the sibling observability surfaces) to get an early warning before a busy database approaches its scale cap.
Getting a license
A license carries signed entitlement claims — the specific numeric caps and feature flags a tier unlocks (an Enterprise license simply omits every numeric cap, so every axis resolves to unlimited). Licenses are issued by patinaDB; contact your vendor or account representative to obtain one for your tier.
See Licensing & Telemetry for how licenses are verified and
installed once you have one. A node with no license (or an invalid/expired
one) always resolves to the hard-coded Community ceiling in the table above.
Check what a running node actually resolved to via GET /version (see
Reading your own usage).