Backend Development 6 min read

Performance Comparison of Java FunTester, Go net/http, and fasthttp HTTP Servers

This article compares the performance of three HTTP server implementations—Java FunTester, Go's net/http, and the fasthttp library—by measuring QPS, CPU usage, and memory consumption across 1, 5, and 10 concurrent threads, and concludes that fasthttp consistently outperforms the others.

FunTester
FunTester
FunTester
Performance Comparison of Java FunTester, Go net/http, and fasthttp HTTP Servers

Test Cases

The previous post evaluated three HTTP client libraries (Java & Go) and concluded that fasthttp > FunTester > http in client performance. This article examines the server‑side performance of services built with those three frameworks.

The test plan measures QPS, CPU usage, and memory consumption of each server under different thread counts. Earlier Mac‑local HTTP service limits dropped after OS upgrades, so the focus is on comparative load testing rather than absolute limits.

Test Script

The test uses FunTester’s standard template com.funtester.frame.thread.RequestThreadTimes . The script (simplified) is shown below:

static String url = "http://localhost:8001/test";

public static void main(String[] args) {
    HttpGet httpGet = getHttpGet(url);
    RUNUP_TIME = 0;
    RequestThreadTimes requestThreadTimes = new RequestThreadTimes(httpGet, 20000);
    new Concurrent(requestThreadTimes, 20, "FunTester").start();
}

Thread count, warm‑up time, and request numbers are hard‑coded.

Server Implementations

All servers return the plain string "Have Fun ~ Tester !" as the response.

FunTester (Java)

Implemented with the moco_FunTester framework (a thin wrapper around mocoAPI). This framework previously achieved 120k QPS.

static void main(String[] args) {
    def server = getServerNoLog(8001)
    server.response("Have Fun ~ Tester !")
    def run = run(server)
    waitForKey("fan")
    run.stop()
}

Go net/http

A minimal Go HTTP server using the standard library:

func TestHttpSer2(t *testing.T) {
    http.Handle("/test", &indexHandler{content: "Have Fun ~ Tester !"})
    http.ListenAndServe(":8001", nil)
}

Go fasthttp

The same endpoint implemented with the fasthttp library and router:

func TestFastSer2(t *testing.T) {
    address := ":8001"

    router := fasthttprouter.New()
    router.GET("/test", func(ctx *fasthttp.RequestCtx) {
        ctx.Response.SetBody([]byte("Have Fun ~ Tester !"))
    })
    fasthttp.ListenAndServe(address, router.Handler)
}

Measured Results

1 Thread

Framework

CPU

Memory

QPS

FunTester

39.85

212.2 MB

17073

Go(net/http)

93.72

16.5 MB

14124

Go(/valyala/fasthttp)

61.53

12.8 MB

17502

5 Threads

Framework

CPU

Memory

QPS

FunTester

185.75

181.8 MB

64690

Go(net/http)

311.89

18.4 MB

48608

Go(/valyala/fasthttp)

186.85

15.1 MB

67001

10 Threads

Framework

CPU

Memory

QPS

FunTester

276.91

161.0 MB

75795

Go(net/http)

479.69

19.0 MB

62534

Go(/valyala/fasthttp)

269.33

16.6 MB

75723

Conclusion

Overall, the server‑side ranking matches the client‑side results: fasthttp > FunTester > net/http. Go’s net/http consumes more memory and CPU, resulting in slightly lower QPS. The superior performance of fasthttp stems from its object‑pool design, though developers should be aware of the associated pitfalls when using it in high‑throughput services.

backendJavaGoPerformance TestingHTTPfasthttp
FunTester
Written by

FunTester

10k followers, 1k articles | completely useless

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.