The problem snap tokens solve
Permify is built for distributed deployments where multiple replicas serve requests. Without a consistency mechanism, a check request might land on a replica that hasn’t yet received the latest write — returning a stale result even though the data already exists in the primary database. Snap tokens solve this with snapshot reads: every check is anchored to a specific point in time, preventing false positives and false negatives caused by replication lag.
How snap tokens work
1
Write data
Call the Write Data API to create or delete relationships and attributes. Every successful write returns a
snap_token in the response body.2
Store the snap token
Associate the snap token with the resource it describes. A common approach is adding a
snap_token column to the relevant table in your application database and updating it on every write.3
Pass the snap token on reads and checks
Include the stored snap token in the
snap_token field of subsequent Check, LookupEntity, LookupSubject, or Read requests. Permify ensures the result reflects a database state that is at least as fresh as that token.When snap token is not provided
If you omitsnap_token, Permify retrieves the ID of the latest transaction from the transactions table and uses it as the snapshot anchor. This ID represents the most current state of the database.
When two identical requests arrive without a snap token, both query for the latest transaction ID. The first request to complete writes its result to the cache under a key such as:
Snap tokens and the cache
The snap token is embedded directly in the permission cache key. There is no separate snap-token cache — the samepermission.cache configuration governs both:
Eviction is driven by memory pressure using Ristretto’s TinyLFU/SampledLFU policy — not by a fixed TTL. When a schema version changes, the
schema_version component of the key changes and all prior entries become stale naturally.
See Caching for a full description of Permify’s cache mechanisms.