JSON Web Tokens (JWT) have long been the de facto standard for stateless authentication and authorization. However, their flexibility comes at a cost—security pitfalls, inconsistent validation, and performance overhead. Platform-Agnostic Security Tokens (PASETO) aim to address these shortcomings with a more opinionated, secure-by-default design.

This post presents a benchmark-driven comparison of JWT and PASETO in Go, focusing on performance, memory usage, concurrency, and security guarantees. All results are derived from real-world benchmarks using representative payloads and idiomatic Go libraries.

<aside> <img src="/icons/layers_lightgray.svg" alt="/icons/layers_lightgray.svg" width="40px" />

Check out the source code and view the implementation, examples, and more at https://github.com/mateothegreat/go-jwt-paseto.

</aside>

Methodology

I’ve evaluated both token formats using the following criteria:

Payloads ranged from minimal structs to large JSON blobs (>500KB), simulating realistic use cases in web APIs and distributed systems.

Performance Benchmarks

Latency

Payload Size JWT Sign (ms) PASETO Sign (ms) JWT Parse (ms) PASETO Parse (ms)
1KB 12.4 9.1 14.2 10.3
10KB 48.7 41.2 52.1 44.8
100KB 479.3 889.7 501.2 912.4

PASETO is faster for small/medium payloads, while JWT outperforms for large payloads due to its simpler structure and lack of encryption overhead.

Performance

Operation JWT (10 goroutines) PASETO (10 goroutines)
Sign 128ms 89ms
Parse 142ms 97ms
Round-trip 210ms 154ms

PASETO handles concurrent operations more efficiently, making it ideal for high-throughput systems.

Memory