Skip to content

Add Fiber: Express-inspired Go framework on fasthttp (~35k ⭐)#59

Open
BennyFranciscus wants to merge 5 commits intoMDA2AV:mainfrom
BennyFranciscus:add-fiber
Open

Add Fiber: Express-inspired Go framework on fasthttp (~35k ⭐)#59
BennyFranciscus wants to merge 5 commits intoMDA2AV:mainfrom
BennyFranciscus:add-fiber

Conversation

@BennyFranciscus
Copy link
Collaborator

Fiber — Go Web Framework

Fiber is an Express-inspired Go web framework built on fasthttp. With ~35k stars, it's one of the three most popular Go web frameworks alongside Gin and Echo.

Why Fiber?

HttpArena already has a great Go lineup:

  • go-fasthttp — raw fasthttp, no framework
  • gin — most popular Go framework (net/http based)
  • echo — the other top Go framework (net/http based)

Fiber fills the obvious gap: a framework built on top of fasthttp. This creates an awesome comparison:

  • Raw fasthttp vs Fiber → what's the framework overhead on fasthttp?
  • Fiber (fasthttp) vs Gin/Echo (net/http) → does the fasthttp foundation actually translate to faster framework performance?

These are questions Go devs always ask when picking a framework. Now we can answer them with data.

Implementation Details

  • Fiber v2 with prefork mode (one process per CPU core, matching fasthttp's reuseport approach)
  • Pure Go SQLite via modernc.org/sqlite (no CGO)
  • Manual compression (deflate/gzip) with BestSpeed
  • Static files pre-loaded into memory
  • All 8 HttpArena endpoints implemented

Endpoints

Endpoint Method Description
/pipeline GET Returns "ok"
/baseline11 GET/POST Query param + body sum
/baseline2 GET Query param sum
/json GET JSON processing
/compression GET Compressed large JSON
/upload POST Body size echo
/db GET SQLite query
/static/:filename GET Pre-loaded static files

Build

docker build -t fiber-bench frameworks/fiber/

cc @Fenny @efectn @ReneWerner87 — thought it'd be cool to see how Fiber stacks up against raw fasthttp and the net/http-based Go frameworks in HttpArena! 🚀

Fiber returns 200 by default for unmatched routes. Added a Use()
middleware at the end to return 404 for any request that doesn't
match a defined route, fixing the noisy resilience validation tests.
@BennyFranciscus BennyFranciscus requested a review from MDA2AV as a code owner March 16, 2026 20:11
@MDA2AV
Copy link
Owner

MDA2AV commented Mar 16, 2026

@BennyFranciscus revert last commit and disable noisy test.

Fiber (fasthttp) returns 200 for unmatched routes by design.
Disabling noisy test per MDA2AV's request.
@BennyFranciscus
Copy link
Collaborator Author

Done — reverted the catch-all handler and removed noisy from the test list. Fiber (fasthttp) returns 200 for unmatched routes by design, so easier to just skip that test than fight it. CI should pass now.

Prefork uses SO_REUSEPORT + process forking which fails in restricted
container environments. Fiber still performs well in single-process mode
since fasthttp already uses goroutines for concurrency.
@github-actions
Copy link

Benchmark Results

Framework: fiber | Profile: all profiles

fiber / baseline / 512c (p=1, r=0, cpu=unlimited)
  Best: 391309 req/s (CPU: 2879.7%, Mem: 87.8MiB) ===

fiber / baseline / 4096c (p=1, r=0, cpu=unlimited)
  Best: 395332 req/s (CPU: 2947.7%, Mem: 149.9MiB) ===

fiber / baseline / 16384c (p=1, r=0, cpu=unlimited)
  Best: 387918 req/s (CPU: 2866.4%, Mem: 229.0MiB) ===

fiber / pipelined / 512c (p=16, r=0, cpu=unlimited)
  Best: 629747 req/s (CPU: 683.9%, Mem: 50.3MiB) ===

fiber / pipelined / 4096c (p=16, r=0, cpu=unlimited)
  Best: 617395 req/s (CPU: 684.9%, Mem: 95.9MiB) ===

fiber / pipelined / 16384c (p=16, r=0, cpu=unlimited)
  Best: 659452 req/s (CPU: 658.2%, Mem: 108.9MiB) ===

fiber / limited-conn / 512c (p=1, r=10, cpu=unlimited)
  Best: 179008 req/s (CPU: 2838.4%, Mem: 71.9MiB) ===

fiber / limited-conn / 4096c (p=1, r=10, cpu=unlimited)
  Best: 214009 req/s (CPU: 3411.4%, Mem: 79.5MiB) ===

fiber / json / 4096c (p=1, r=0, cpu=unlimited)
  Best: 128904 req/s (CPU: 5299.0%, Mem: 163.2MiB) ===

fiber / json / 16384c (p=1, r=0, cpu=unlimited)
  Best: 158615 req/s (CPU: 6397.4%, Mem: 325.1MiB) ===

fiber / upload / 64c (p=1, r=0, cpu=unlimited)
  Best: 972 req/s (CPU: 5444.1%, Mem: 2.1GiB) ===

fiber / upload / 256c (p=1, r=0, cpu=unlimited)
  Best: 953 req/s (CPU: 5356.9%, Mem: 8.3GiB) ===

fiber / upload / 512c (p=1, r=0, cpu=unlimited)
  Best: 913 req/s (CPU: 5358.0%, Mem: 16.2GiB) ===

fiber / compression / 4096c (p=1, r=0, cpu=unlimited)
  Best: 9455 req/s (CPU: 10989.5%, Mem: 5.9GiB) ===

fiber / compression / 16384c (p=1, r=0, cpu=unlimited)
  Best: 8938 req/s (CPU: 9580.7%, Mem: 7.3GiB) ===

fiber / mixed / 4096c (p=1, r=5, cpu=unlimited)
  Best: 38287 req/s (CPU: 9071.1%, Mem: 3.9GiB) ===

fiber / mixed / 16384c (p=1, r=5, cpu=unlimited)
  Best: 31024 req/s (CPU: 7951.1%, Mem: 3.0GiB) ===
Full log

  57868 requests in 5.00s, 44693 responses
  Throughput: 8.93K req/s
  Bandwidth:  1.94GB/s
  Status codes: 2xx=44693, 3xx=0, 4xx=0, 5xx=0
  Latency samples: 44693 / 44693 responses (100.0%)
  CPU: 9580.7% | Mem: 7.3GiB

=== Best: 8938 req/s (CPU: 9580.7%, Mem: 7.3GiB) ===
  Input BW: 645.91KB/s (avg template: 74 bytes)
[dry-run] Results not saved (use --save to persist)
httparena-bench-fiber
httparena-bench-fiber
[skip] fiber does not subscribe to noisy

==============================================
=== fiber / mixed / 4096c (p=1, r=5, cpu=unlimited) ===
==============================================
54c50493819514f1918a539923095874d1a6284076d381a9906c7d7a81e116f5
[wait] Waiting for server...
[ready] Server is up

[run 1/3]
gcannon — io_uring HTTP load generator
  Target:    localhost:8080/
  Threads:   64
  Conns:     4096 (64/thread)
  Pipeline:  1
  Req/conn:  5
  Templates: 10
  Expected:  200
  Duration:  5s


  Thread Stats   Avg      p50      p90      p99    p99.9
    Latency   92.82ms   1.95ms   382.30ms    1.08s    1.98s

  206531 requests in 5.00s, 191435 responses
  Throughput: 38.26K req/s
  Bandwidth:  1.24GB/s
  Status codes: 2xx=191435, 3xx=0, 4xx=0, 5xx=0
  Latency samples: 191431 / 191435 responses (100.0%)
  Reconnects: 39818
  Per-template: 18537,19901,21355,23092,24925,21473,19523,15957,12860,13808
  Per-template-ok: 18537,19901,21355,23092,24925,21473,19523,15957,12860,13808
  CPU: 9071.1% | Mem: 3.9GiB

[run 2/3]
gcannon — io_uring HTTP load generator
  Target:    localhost:8080/
  Threads:   64
  Conns:     4096 (64/thread)
  Pipeline:  1
  Req/conn:  5
  Templates: 10
  Expected:  200
  Duration:  5s


  Thread Stats   Avg      p50      p90      p99    p99.9
    Latency   103.55ms   11.40ms   343.30ms   973.70ms    1.48s

  182066 requests in 5.00s, 168058 responses
  Throughput: 33.59K req/s
  Bandwidth:  1.23GB/s
  Status codes: 2xx=168058, 3xx=0, 4xx=0, 5xx=0
  Latency samples: 168058 / 168058 responses (100.0%)
  Reconnects: 35373
  Per-template: 15946,16965,18040,19168,20375,17483,16915,16410,14187,12569
  Per-template-ok: 15946,16965,18040,19168,20375,17483,16915,16410,14187,12569
  CPU: 9631.0% | Mem: 3.5GiB

[run 3/3]
gcannon — io_uring HTTP load generator
  Target:    localhost:8080/
  Threads:   64
  Conns:     4096 (64/thread)
  Pipeline:  1
  Req/conn:  5
  Templates: 10
  Expected:  200
  Duration:  5s


  Thread Stats   Avg      p50      p90      p99    p99.9
    Latency   90.04ms   8.60ms   328.00ms    1.06s    1.88s

  204725 requests in 5.00s, 189806 responses
  Throughput: 37.94K req/s
  Bandwidth:  1.27GB/s
  Status codes: 2xx=189806, 3xx=0, 4xx=0, 5xx=0
  Latency samples: 189802 / 189806 responses (100.0%)
  Reconnects: 39279
  Per-template: 18297,19865,21379,22967,24609,20907,18446,15889,13440,14003
  Per-template-ok: 18297,19865,21379,22967,24609,20907,18446,15889,13440,14003
  CPU: 9277.6% | Mem: 3.7GiB

=== Best: 38287 req/s (CPU: 9071.1%, Mem: 3.9GiB) ===
  Input BW: 3.74GB/s (avg template: 104924 bytes)
[dry-run] Results not saved (use --save to persist)
httparena-bench-fiber
httparena-bench-fiber

==============================================
=== fiber / mixed / 16384c (p=1, r=5, cpu=unlimited) ===
==============================================
154646f4759bb553a3d3b1f9ef8ba4d2c7abd4c3428a279b8ba9f7f2619449d5
[wait] Waiting for server...
[ready] Server is up

[run 1/3]
gcannon — io_uring HTTP load generator
  Target:    localhost:8080/
  Threads:   64
  Conns:     16384 (256/thread)
  Pipeline:  1
  Req/conn:  5
  Templates: 10
  Expected:  200
  Duration:  5s


  Thread Stats   Avg      p50      p90      p99    p99.9
    Latency   193.43ms   15.00ms   761.60ms    1.40s    3.87s

  162052 requests in 5.00s, 139166 responses
  Throughput: 27.82K req/s
  Bandwidth:  1.04GB/s
  Status codes: 2xx=139166, 3xx=0, 4xx=0, 5xx=0
  Latency samples: 139166 / 139166 responses (100.0%)
  Reconnects: 29986
  Errors: connect 0, read 314, timeout 0
  Per-template: 13314,13972,15347,16363,17103,14068,13430,12977,11522,11070
  Per-template-ok: 13314,13972,15347,16363,17103,14068,13430,12977,11522,11070
  CPU: 7151.9% | Mem: 2.1GiB

[run 2/3]
gcannon — io_uring HTTP load generator
  Target:    localhost:8080/
  Threads:   64
  Conns:     16384 (256/thread)
  Pipeline:  1
  Req/conn:  5
  Templates: 10
  Expected:  200
  Duration:  5s


  Thread Stats   Avg      p50      p90      p99    p99.9
    Latency   184.40ms   21.60ms   677.50ms    1.37s    2.14s

  177041 requests in 5.01s, 154421 responses
  Throughput: 30.83K req/s
  Bandwidth:  1.14GB/s
  Status codes: 2xx=154421, 3xx=0, 4xx=0, 5xx=0
  Latency samples: 154421 / 154421 responses (100.0%)
  Reconnects: 33166
  Errors: connect 0, read 204, timeout 0
  Per-template: 16300,16259,16892,17917,17964,14390,14229,15517,12153,12800
  Per-template-ok: 16300,16259,16892,17917,17964,14390,14229,15517,12153,12800
  CPU: 8763.4% | Mem: 3.9GiB

[run 3/3]
gcannon — io_uring HTTP load generator
  Target:    localhost:8080/
  Threads:   64
  Conns:     16384 (256/thread)
  Pipeline:  1
  Req/conn:  5
  Templates: 10
  Expected:  200
  Duration:  5s


  Thread Stats   Avg      p50      p90      p99    p99.9
    Latency   168.37ms   24.10ms   633.20ms    1.03s    1.64s

  176125 requests in 5.01s, 155435 responses
  Throughput: 31.05K req/s
  Bandwidth:  1.12GB/s
  Status codes: 2xx=155435, 3xx=0, 4xx=0, 5xx=0
  Latency samples: 155435 / 155435 responses (100.0%)
  Reconnects: 33126
  Per-template: 15706,16652,17553,18543,18953,15213,14008,14462,11919,12426
  Per-template-ok: 15706,16652,17553,18543,18953,15213,14008,14462,11919,12426
  CPU: 7951.1% | Mem: 3.0GiB

=== Best: 31024 req/s (CPU: 7951.1%, Mem: 3.0GiB) ===
  Input BW: 3.03GB/s (avg template: 104924 bytes)
[dry-run] Results not saved (use --save to persist)
httparena-bench-fiber
httparena-bench-fiber
[skip] fiber does not subscribe to baseline-h2
[skip] fiber does not subscribe to static-h2
[skip] fiber does not subscribe to baseline-h3
[skip] fiber does not subscribe to static-h3
[skip] fiber does not subscribe to unary-grpc
[skip] fiber does not subscribe to unary-grpc-tls
[skip] fiber does not subscribe to echo-ws
[restore] Restoring CPU governor to powersave...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants