{"id":44053675,"url":"https://github.com/mateothegreat/go-jwt-paseto","last_synced_at":"2026-02-07T23:39:58.036Z","repository":{"id":310116601,"uuid":"1035748140","full_name":"mateothegreat/go-jwt-paseto","owner":"mateothegreat","description":"JWT vs PASETO Performance \u0026 Security Comparison","archived":false,"fork":false,"pushed_at":"2025-08-11T06:13:41.000Z","size":20,"stargazers_count":1,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-12-22T20:52:03.443Z","etag":null,"topics":["go","golang","jwt","paseto"],"latest_commit_sha":null,"homepage":"https://www.notion.so/Can-we-do-better-than-JWT-Implementation-Performance-Security-Driven-Comparison-24cd7342e5718006a7d5d9a0e0ba39eb","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mateothegreat.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-08-11T03:14:03.000Z","updated_at":"2025-09-01T07:41:36.000Z","dependencies_parsed_at":"2025-08-15T22:00:31.759Z","dependency_job_id":"b5310ed2-3600-4f11-bdd9-0b8cd6a6fbc3","html_url":"https://github.com/mateothegreat/go-jwt-paseto","commit_stats":null,"previous_names":["mateothegreat/go-jwt-paseto"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/mateothegreat/go-jwt-paseto","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mateothegreat%2Fgo-jwt-paseto","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mateothegreat%2Fgo-jwt-paseto/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mateothegreat%2Fgo-jwt-paseto/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mateothegreat%2Fgo-jwt-paseto/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mateothegreat","download_url":"https://codeload.github.com/mateothegreat/go-jwt-paseto/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mateothegreat%2Fgo-jwt-paseto/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29212761,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-07T23:36:15.537Z","status":"ssl_error","status_checked_at":"2026-02-07T23:36:12.879Z","response_time":63,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["go","golang","jwt","paseto"],"created_at":"2026-02-07T23:39:57.448Z","updated_at":"2026-02-07T23:39:58.031Z","avatar_url":"https://github.com/mateothegreat.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# JWT vs PASETO Performance \u0026 Security Comparison\n\nThis repository provides a comprehensive comparison between JWT and PASETO implementations with Go, covering both performance benchmarks and security properties.\n\n\u003e [!NOTE]\n\u003e Feeeling froggy?\n\u003e `/ship-it` with a `go install github.com/mateothegreat/go-jwt-paseto@latest` and you'll be able to use the `jwt` and `paseto` packages in your own project for POC'ing and then you can decide which one is right for _you_.\n\n### What's wrong with JWT?\n\nNothing. It has a place in the ecosystem and is a great tool for many use cases.\n\nJWT's popularity stems from its ubiquity and tooling, but that ease can mask complexity—especially around algorithm selection, claim validation, and expiration enforcement.\n\n### What's wrong with PASETO?\n\nNothing. It has a place in the ecosystem and is a great tool for many use cases.\n\nPASETO's popularity stems from its security properties, performance, and clarity of design. It enforces safer defaults and avoids common pitfalls like algorithm confusion.\n\n## Overview\n\nWhat this demonstration provides:\n\n- 🤩 Comprehensive test coverage with handcrafted edge-case scenarios.\n- 📈 Extensive benchmark coverage—because performance matters.\n- 🔄 Consistent implementations.\n- 📚 Healthy documentation to help you reason about what the code is _doing_.\n- 🔒 Security-oriented development™ practice to ensure robustness.\n\n## Performance Comparison\n\n### Key Generation \u0026 Initialization\n\n| Operation          | JWT           | PASETO        | Winner |\n| ------------------ | ------------- | ------------- | ------ |\n| Key Generation     | ~13,324 ns/op | N/A*          | JWT    |\n| Key Initialization | ~14,339 ns/op | ~27,460 ns/op | JWT    |\n\n\u003e **Note**: PASETO uses generated keys directly for symmetric encryption; asymmetric key generation (Ed25519) is measurable but not benchmarked here.\n\n### Token Signing Performance\n\n| Data Type       | JWT (ns/op) | JWT (B/op) | JWT (allocs/op) | PASETO (ns/op) | PASETO (B/op) | PASETO (allocs/op) | Winner          |\n| --------------- | ----------- | ---------- | --------------- | -------------- | ------------- | ------------------ | --------------- |\n| String          | ~28,528     | 8,824      | 106             | ~28,108        | 3,205         | 44                 | PASETO (memory) |\n| Simple Struct   | ~28,561     | 8,904      | 106             | ~28,475        | 3,357         | 44                 | PASETO (memory) |\n| Complex Struct  | ~36,454     | 10,685     | 114             | ~30,875        | 5,025         | 51                 | PASETO          |\n| Large Data      | ~64,841     | 69,399     | 307             | ~96,630        | 56,859        | 242                | JWT (speed)     |\n| Very Large Data | ~517,259    | 763,500    | 2,110           | ~1,089,027     | 712,679       | 2,047              | JWT (speed)     |\n\n### Token Parsing Performance\n\n| Data Type       | JWT (ns/op) | JWT (B/op) | JWT (allocs/op) | PASETO (ns/op) | PASETO (B/op) | PASETO (allocs/op) | Winner      |\n| --------------- | ----------- | ---------- | --------------- | -------------- | ------------- | ------------------ | ----------- |\n| String          | ~65,315     | 4,552      | 76              | ~59,347        | 3,713         | 72                 | PASETO      |\n| Simple Struct   | ~67,460     | 4,616      | 78              | ~59,419        | 3,905         | 76                 | PASETO      |\n| Complex Struct  | ~68,542     | 5,952      | 94              | ~63,793        | 4,890         | 91                 | PASETO      |\n| Large Data      | ~144,105    | 61,617     | 392             | ~150,619       | 47,110        | 384                | JWT (speed) |\n| Very Large Data | ~858,143    | 847,571    | 3,107           | ~1,287,302     | 627,891       | 3,096              | JWT (speed) |\n\n### Round-Trip Performance (Sign + Parse)\n\n| Data Type      | JWT (ns/op) | JWT (B/op) | JWT (allocs/op) | PASETO (ns/op) | PASETO (B/op) | PASETO (allocs/op) | Winner |\n| -------------- | ----------- | ---------- | --------------- | -------------- | ------------- | ------------------ | ------ |\n| String         | ~104,558    | 13,372     | 182             | ~89,117        | 6,914         | 116                | PASETO |\n| Simple Struct  | ~107,710    | 13,517     | 184             | ~100,560       | 7,266         | 120                | PASETO |\n| Complex Struct | ~101,715    | 16,241     | 203             | ~97,172        | 10,826        | 139                | PASETO |\n\n### Memory Allocation Comparison\n\n- **PASETO uses ~40–60% fewer allocations** across all payload sizes.\n- **For small/medium payloads**, PASETO is significantly more memory-efficient.\n- **For very large payloads**, JWT is slightly more efficient due to its simpler structure.\n\n## Security Properties\n\n### ✅ Security Features Validated\n\n1. **Key Isolation**: Tokens signed with different keys are not interchangeable.\n2. **Tamper Detection**: Modified tokens are properly rejected.\n3. **Truncation Protection**: Truncated tokens are properly rejected.\n4. **Expiration Validation**: Expired tokens are rejected (JWT via config; PASETO requires explicit validation).\n5. **Type Safety**: Generic type system prevents type confusion attacks.\n\n### Key Differences\n\n| Security Aspect          | JWT                        | PASETO                        | Verdict                                |\n| ------------------------ | -------------------------- | ----------------------------- | -------------------------------------- |\n| Algorithm Agility        | ✅ Multiple algorithms      | ✅ Fixed per version           | PASETO (safer)                         |\n| Expiration Enforcement   | ⚠️ Optional via config      | ⚠️ Manual validation required  | Tie (both require developer diligence) |\n| Token Structure          | ✅ Header.Payload.Signature | ✅ Version.Purpose.Payload     | PASETO (clearer)                       |\n| Cryptographic Primitives | ✅ HMAC, RSA, ECDSA         | ✅ Ed25519, XChaCha20-Poly1305 | PASETO (modern)                        |\n\n\u003e PASETO’s design forces developers to be explicit, which can be safer in high-assurance systems. JWT libraries often auto-check expiration, but only if configured correctly.\n\n## Concurrency Performance\n\n| Operation        | JWT (ns/op) | PASETO (ns/op) | Winner            |\n| ---------------- | ----------- | -------------- | ----------------- |\n| Concurrent Sign  | ~7,723      | ~5,501         | PASETO            |\n| Concurrent Parse | ~11,478     | ~11,143        | PASETO (marginal) |\n| Round-Trip       | ~19,852     | ~16,094        | PASETO            |\n\n✅ PASETO handles concurrent operations more efficiently, making it ideal for high-throughput systems.\n\n## Recommendations\n\n### Choose JWT When:\n- You need automatic expiration validation\n- Working with very large payloads (\u003e100KB)\n- Integration with existing JWT-based systems is required\n- Algorithm flexibility is needed\n\n### Choose PASETO When:\n- Memory efficiency is critical\n- High concurrency is expected\n- Security is the top priority\n- Working with small to medium payloads (\u003c100KB)\n- You want modern cryptographic primitives\n\n## Payload Size Recommendations\n\n| Payload Size | Recommended | Reason                                |\n| ------------ | ----------- | ------------------------------------- |\n| \u003c 1KB        | PASETO      | Better memory efficiency and speed    |\n| 1KB – 10KB   | PASETO      | Balanced performance and security     |\n| 10KB – 100KB | JWT         | Better performance for large payloads |\n| \u003e 100KB      | JWT         | Significantly better performance      |\n\n## Conclusion\n\n**Winner by Category:**\n\n- **Overall Performance**: Tie (depends on use case)\n- **Memory Efficiency**: PASETO\n- **Security**: PASETO\n- **Large Payload Performance**: JWT\n- **Concurrency**: PASETO\n- **Ease of Use**: JWT\n\n**Recommendation**: Use **PASETO** for new projects requiring high security and memory efficiency with small to medium payloads. Use **JWT** for large payloads or when integrating with existing JWT infrastructure.\n\n## Benchmark Results\n\n```sh\n../go-jwt-paseto 🌱 main [?] ✗ make bench                      \ngo test -bench=. -benchmem . ./jwt\ngoos: darwin\ngoarch: arm64\npkg: github.com/mateothegreat/go-jwt-paseto\ncpu: Apple M1 Max\nBenchmarkPasetoParse/String-10                     19654             61264 ns/op            3921 B/op         76 allocs/op\nBenchmarkPasetoParse/SimpleStruct-10               19526             59469 ns/op            4113 B/op         80 allocs/op\nBenchmarkPasetoParse/ComplexStruct-10              19048             62453 ns/op            5098 B/op         95 allocs/op\nBenchmarkPasetoParse/LargeData-10                   8241            147518 ns/op           47317 B/op        388 allocs/op\nBenchmarkPasetoParse/VeryLargeData-10               1008           1190245 ns/op          628119 B/op       3100 allocs/op\nBenchmarkPasetoSignParseRoundTrip/String-10                13854             86489 ns/op            7122 B/op        120 allocs/op\nBenchmarkPasetoSignParseRoundTrip/SimpleStruct-10          13023            101668 ns/op            7475 B/op        124 allocs/op\nBenchmarkPasetoSignParseRoundTrip/ComplexStruct-10         12721            103823 ns/op           11034 B/op        143 allocs/op\nBenchmarkPasetoMemoryAllocation/SignMemoryAllocation-10                    43807             28540 ns/op            3357 B/op         44 allocs/op\nBenchmarkPasetoMemoryAllocation/ParseMemoryAllocation-10                   20155             62646 ns/op            4114 B/op         80 allocs/op\nBenchmarkPasetoMemoryAllocation/RoundTripMemoryAllocation-10               12944             87192 ns/op            7475 B/op        124 allocs/op\nBenchmarkPasetoTokenSizes/Sign_Tiny-10                                     41811             29864 ns/op            2948 B/op         43 allocs/op\nBenchmarkPasetoTokenSizes/Parse_Tiny-10                                    20356             65514 ns/op            3793 B/op         75 allocs/op\nBenchmarkPasetoTokenSizes/Sign_Small-10                                    42700             28938 ns/op            4046 B/op         43 allocs/op\nBenchmarkPasetoTokenSizes/Parse_Small-10                                   18825             60344 ns/op            4498 B/op         76 allocs/op\nBenchmarkPasetoTokenSizes/Sign_Medium-10                                   32300             35504 ns/op           14173 B/op         43 allocs/op\nBenchmarkPasetoTokenSizes/Parse_Medium-10                                  17362             72123 ns/op           10933 B/op         76 allocs/op\nBenchmarkPasetoTokenSizes/Sign_Large-10                                    10000            110636 ns/op           75420 B/op         41 allocs/op\nBenchmarkPasetoTokenSizes/Parse_Large-10                                    7866            155395 ns/op           54217 B/op         75 allocs/op\nBenchmarkPasetoTokenSizes/Sign_VeryLarge-10                                 1557            756676 ns/op          758392 B/op         43 allocs/op\nBenchmarkPasetoTokenSizes/Parse_VeryLarge-10                                1210            986434 ns/op          535735 B/op         75 allocs/op\nBenchmarkPasetoConcurrency/ConcurrentSign-10                              216289              5078 ns/op            3217 B/op         44 allocs/op\nBenchmarkPasetoConcurrency/ConcurrentParse-10                             116119              9950 ns/op            4011 B/op         80 allocs/op\nBenchmarkPasetoConcurrency/ConcurrentRoundTrip-10                          77720             15559 ns/op            7236 B/op        124 allocs/op\nBenchmarkInitializeKeys-10                                                 64270             18695 ns/op             192 B/op          5 allocs/op\nBenchmarkPasetoSign/String-10                                              43429             28336 ns/op            3205 B/op         44 allocs/op\nBenchmarkPasetoSign/SimpleStruct-10                                        37423             27538 ns/op            3357 B/op         44 allocs/op\nBenchmarkPasetoSign/ComplexStruct-10                                       40060             29699 ns/op            5025 B/op         51 allocs/op\nBenchmarkPasetoSign/LargeData-10                                           13218             91074 ns/op           56860 B/op        242 allocs/op\nBenchmarkPasetoSign/VeryLargeData-10                                        1370            889633 ns/op          709442 B/op       2046 allocs/op\nPASS\nok      github.com/mateothegreat/go-jwt-paseto  49.866s\ngoos: darwin\ngoarch: arm64\npkg: github.com/mateothegreat/go-jwt-paseto/jwt\ncpu: Apple M1 Max\nBenchmarkGenerateKeys-10                   94039             13247 ns/op            1000 B/op         17 allocs/op\nBenchmarkInitializeKeys-10                 84576             13979 ns/op            1696 B/op         31 allocs/op\nBenchmarkJWTSign/String-10                 36080             28008 ns/op            8824 B/op        106 allocs/op\nBenchmarkJWTSign/SimpleStruct-10           43452             28153 ns/op            8904 B/op        106 allocs/op\nBenchmarkJWTSign/ComplexStruct-10          39272             29119 ns/op           10684 B/op        114 allocs/op\nBenchmarkJWTSign/LargeData-10              18891             61890 ns/op           69429 B/op        307 allocs/op\nBenchmarkJWTSign/VeryLargeData-10           2523            479498 ns/op          762431 B/op       2110 allocs/op\nBenchmarkJWTParse/String-10                18606             63336 ns/op            4552 B/op         76 allocs/op\nBenchmarkJWTParse/SimpleStruct-10          18824             64622 ns/op            4616 B/op         78 allocs/op\nBenchmarkJWTParse/ComplexStruct-10         18139             66315 ns/op            5952 B/op         94 allocs/op\nBenchmarkJWTParse/LargeData-10              9765            128674 ns/op           61617 B/op        392 allocs/op\nBenchmarkJWTParse/VeryLargeData-10          1586            797797 ns/op          847571 B/op       3107 allocs/op\nBenchmarkJWTSignParseRoundTrip/String-10                   12958             92585 ns/op           13372 B/op        182 allocs/op\nBenchmarkJWTSignParseRoundTrip/SimpleStruct-10             12912             93132 ns/op           13516 B/op        184 allocs/op\nBenchmarkJWTSignParseRoundTrip/ComplexStruct-10            12196             95512 ns/op           16239 B/op        203 allocs/op\nBenchmarkJWTMemoryAllocation/SignMemoryAllocation-10               43232             27736 ns/op            8904 B/op        106 allocs/op\nBenchmarkJWTMemoryAllocation/ParseMemoryAllocation-10              18842             67113 ns/op            4616 B/op         78 allocs/op\nBenchmarkJWTMemoryAllocation/RoundTripMemoryAllocation-10          12638             94745 ns/op           13517 B/op        184 allocs/op\nBenchmarkJWTTokenSizes/Sign_Tiny-10                                42672             28185 ns/op            8664 B/op        106 allocs/op\nBenchmarkJWTTokenSizes/Parse_Tiny-10                               17263             64686 ns/op            4432 B/op         75 allocs/op\nBenchmarkJWTTokenSizes/Sign_Small-10                               41091             32895 ns/op            9434 B/op        106 allocs/op\nBenchmarkJWTTokenSizes/Parse_Small-10                              17872             65683 ns/op            4912 B/op         76 allocs/op\nBenchmarkJWTTokenSizes/Sign_Medium-10                              38210             31442 ns/op           17065 B/op        106 allocs/op\nBenchmarkJWTTokenSizes/Parse_Medium-10                             17226             70197 ns/op           10896 B/op         77 allocs/op\nBenchmarkJWTTokenSizes/Sign_Large-10                               19928             57905 ns/op           86643 B/op        106 allocs/op\nBenchmarkJWTTokenSizes/Parse_Large-10                               9555            134839 ns/op           81937 B/op         80 allocs/op\nBenchmarkJWTTokenSizes/Sign_VeryLarge-10                            3853            317032 ns/op          831852 B/op        108 allocs/op\nBenchmarkJWTTokenSizes/Parse_VeryLarge-10                           1800            659602 ns/op          755235 B/op         83 allocs/op\nBenchmarkJWTConcurrency/ConcurrentSign-10                         162852              7681 ns/op            8881 B/op        106 allocs/op\nBenchmarkJWTConcurrency/ConcurrentParse-10                        109900             11122 ns/op            4576 B/op         78 allocs/op\nBenchmarkJWTConcurrency/ConcurrentRoundTrip-10                     60620             21717 ns/op           13458 B/op        184 allocs/op\nPASS\nok      github.com/mateothegreat/go-jwt-paseto/jwt      51.534s\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmateothegreat%2Fgo-jwt-paseto","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmateothegreat%2Fgo-jwt-paseto","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmateothegreat%2Fgo-jwt-paseto/lists"}