Improving Performance
SpiceDB’s server-side configuration defaults favor correctness over raw speed. API requests,
however, default to minimize_latency consistency for read operations, favoring cache utilization
over strict freshness. The flags documented on this page allow you to further tune SpiceDB for
your specific workload.
By enabling cross-node communication
SpiceDB can be deployed in a clustered configuration where multiple nodes work together to serve API requests. In such a configuration, and for the CheckPermissions API, enabling a feature called dispatch allows nodes to break down one API request into smaller “questions” and forward those to other nodes within the cluster. This helps reduce latency and improve overall performance.
How it works
Each SpiceDB node maintains an in-memory cache of permissions queries it has resolved in the past. When a new permissions query is encountered by one node, its answer may be present on another node, so SpiceDB will forward the request onward to the other node to check the shared cache.
For more details on how dispatching works, see the Consistent Hash Load Balancing for gRPC article.
Configuration in Kubernetes environments
If using the SpiceDB Operator, dispatching is enabled by default and no additional configuration is necessary.
If not using it, you need to set the following flag:
--dispatch-upstream-addr=kubernetes:///spicedb.default:50053where spicedb.default is the Kubernetes Service in which SpiceDB is accessible.
If you are deploying SpiceDB under Kubernetes, it is recommended to use the SpiceDB Operator, which configures dispatching automatically.
Configuration in non-Kubernetes environments
Non-Kubernetes based dispatching relies upon DNS updates, which means it can become stale if DNS is changing. This is not recommended unless DNS updates are rare.
To enable dispatch, the following flags must be specified:
spicedb serve \
--dispatch-cluster-enabled=true \
--dispatch-upstream-addr=upstream-addr \
...or via environment variables with the SPICEDB_ prefix:
SPICEDB_DISPATCH_CLUSTER_ENABLED=true \
SPICEDB_DISPATCH_UPSTREAM_ADDR=upstream-addr \
spicedb serve ...The upstream-addr should be the DNS address of the load balancer at which all SpiceDB nodes are accessible at the default dispatch port of :50053.
Dispatch Chunk Size
The --dispatch-chunk-size flag controls the maximum number of object IDs included in a single dispatched request.
This is particularly impactful for lookup operations (such as LookupResources and LookupSubjects) that need to process many objects,
or checks that need to consider a “wide arrow,” where SpiceDB needs to walk a relation that has many entries in
order to resolve a check.
spicedb serve \
--dispatch-chunk-size=100Larger chunk sizes reduce dispatch overhead but increase memory usage per request. Start with the default (100) and increase if you observe high dispatch latency with large lookup or check operations.
By enabling Materialize
Materialize is a separate service that allows for the precomputation of permission query results.
If Materialize is running, SpiceDB can dispatch sub-queries to Materialize, which can significantly speed up permission checks.
By enabling the schema cache
The schema cache stores type definitions and caveat definitions to avoid repeatedly fetching schema information from the datastore.
SpiceDB offers two caching modes:
- Just-In-Time (JIT) Caching: The default mode that loads definitions on-demand. Uses less memory, but it incurs a cold start penalty on first access to each definition.
- Watching Cache: An experimental mode that proactively maintains an always-up-to-date cache. This mode uses more memory but avoids cold start penalties. It is recommended when there are frequent schema changes.
To configure the schema cache, use the following flags:
# Enable namespace cache (default: true)
--ns-cache-enabled=true
# Maximum memory (default: 32 MiB)
--ns-cache-max-cost=32MiB
# Enable experimental watchable schema cache (default: false)
# When true: uses watching cache if datastore supports it
# When false: always uses JIT caching
--enable-experimental-watchable-schema-cache=falseBy tuning revision quantization
The --datastore-revision-quantization-interval and --datastore-revision-quantization-max-staleness-percent flags control how SpiceDB groups revisions for caching.
Increasing these values improves cache hit rates at the cost of data freshness.
See the load testing guide for details on how quantization affects performance, and the hotspot caching blog post for a deeper explanation.
By tuning connection pools
For PostgreSQL, CockroachDB, and MySQL datastores, connection pool sizing significantly impacts performance under load.
Key flags include --datastore-conn-pool-read-max-open, --datastore-conn-pool-write-max-open, and the corresponding min and jitter settings.
See the datastores reference for the full list of connection pool flags and defaults, and the best practices guide for sizing recommendations.
By tuning the transaction overlap strategy (CockroachDB only)
The --datastore-tx-overlap-strategy flag controls how SpiceDB handles concurrent write transactions.
CockroachDB users can trade consistency guarantees for write throughput by selecting from strategies: static (default), prefix, request, or insecure.
See the CockroachDB datastore documentation for detailed strategy descriptions and trade-offs.