1. shorter lifetimes with no other revocation system. This works well if you go back to a central party which has the actual business logic/state to decide whether to issue a new token
2. token introspection API, possibly with caching to reduce network calls/user latency
3. API-based blacklist with invalidated token identifiers (either JTI or SID)
In the first two approaches you are trying to prevent state from being pushed out to the apps at the edges.
The third approach is what I took with Distributed Token Validity API, which was basically a distributed system (via state replication or fetch + cache) to move the minimal state needed as close to the app as feasible.