I rebuilt the same short-video API in Java, Go, Kotlin, and Rust — here are the numbers

171 points netfishx 53 comments

I'm a backend engineer with 21 years of Java experience, recently migrated our production backend from Java to Go, and then rewrote it again in Rust. Along the way I also built a Kotlin (Ktor) version for completeness. All four implement the same short-video platform API: auth, video feed, follow system, S3 uploads, Redis caching.

Here are the results.

Throughput (wrk, 200 concurrent, 10s)

Java Go Rust Kotlin
QPS (health) 88K 100K 210K 99K
vs Java 1x 1.14x 2.39x 1.13x

Latency distribution (200 concurrent)

Go Rust Kotlin
p50 1.79 ms 0.70 ms 1.60 ms
p99 6.13 ms 1.48 ms 15.36 ms

Rust p99 is 4x better than Go and 10x better than Kotlin. Zero GC means zero surprises.

Memory (RSS)

Java Go Rust Kotlin
Idle 354 MB 25 MB 19 MB 254 MB
Under 500c load 372 MB 60 MB 33 MB 650 MB

Rust at 33 MB under 500 concurrent connections. Kotlin at 650 MB. That's a 20x difference.

Cold start

Java Go Rust Kotlin
Time 2,714 ms 69 ms 153 ms 914 ms

Go wins cold start. Rust's 153ms includes sqlx migration checks at startup — could be optimized.

Build time (clean, deps cached)

Java Go Rust Kotlin
Time 5.6s 9.4s 98.3s 14.1s

Yes, Rust compile times are painful. 98 seconds for a clean build. This is the real cost. In CI I'm mitigating this with BuildKit cache mounts on a self-hosted GitLab runner.

Code size (tokei, excluding blanks/comments)

Java Go Rust Kotlin
Lines 7,001 4,929* 4,179 8,607**
Files 156 86 37 52

* Go excluding sqlc generated code
** Kotlin includes ~2,000 lines of tests

Rust: fewest lines, fewest files, best runtime performance. The type system pulls a lot of weight.

Stack

  • Rust: Axum 0.8 + SQLx + deadpool-redis + Tokio
  • Go: Echo v4 + Huma v2 + pgx/v5 + sqlc + go-redis
  • Kotlin: Ktor 3.4 + Exposed + Lettuce + JVM 21 (Virtual Threads + ZGC)
  • Java: Spring Boot 3.2 + MyBatis-Plus + Jedis (JDK 17)

My take

I'm running Rust in production now. The compile time tax is real, but the runtime payoff is massive — we're looking at roughly halving our EC2 bill compared to Go, and the p99 stability gives me confidence I never had with JVM.

The biggest surprise was Kotlin/Ktor: it nearly matches Go in throughput, and p50 latency is actually better than Go. But p99 (15ms) and memory (650 MB under load) remind you it's still JVM under the hood.

Test environment: macOS Apple Silicon, Docker (OrbStack), PostgreSQL 18, Redis 8. All sharing the same DB/Redis instances (except Java which used MySQL). Health endpoint only — no DB queries in the benchmark. Full methodology in the report.

Happy to share the full report or answer questions about the migration experience.