Skip to content
Backend Performance DevOps

Shipping Elysia.js + Bun to Production: What the Docs Skip

Practical notes on running Elysia.js on Bun for production services: PM2, observability, and the error patterns you should watch out for.

Wafik Ulinnuha

Backend Developer

1 min read

Bun delivers fast startup and impressive throughput. Elysia.js adds type ergonomics on par with Hono or Fastify. The combination is tempting. But like any new runtime, plenty of production details are left for you to figure out.

Process supervisor

Bun does not yet have a mature equivalent of Node's cluster module. I use two approaches depending on load:

  • PM2 in fork mode with multiple instances. Great for stateless services.
  • systemd unit with Restart=always for critical services. Simpler, one bun binary, and logs go straight to journald.
[Service]
Type=simple
User=app
ExecStart=/usr/local/bin/bun run /var/www/app/src/index.ts
Restart=always
RestartSec=2
LimitNOFILE=65536
Environment=NODE_ENV=production

The right reverse proxy

Always put Nginx in front. Not because Bun struggles with TLS, but so rate-limits, security headers, and keep-alive tuning live in one place.

location /api/ {
  proxy_pass http://127.0.0.1:3000;
  proxy_http_version 1.1;
  proxy_set_header Upgrade $http_upgrade;
  proxy_set_header Connection "upgrade";
  proxy_set_header X-Real-IP $remote_addr;
  proxy_read_timeout 60s;
}

Minimal observability

Without instrumentation, Bun's performance is hard to debug. I always wire up:

  • Simple /healthz and /readyz endpoints.
  • A pino-based JSON logger, piped to Loki via Vector.
  • Handler duration histograms via prom-client; Elysia's onAfterHandle hook is perfect for this.

Error patterns to watch

A few things that bit me early:

  1. Top-level await stalls at boot — the service hangs until the orchestrator's timeout fires.
  2. Multipart body parsing on Bun was once incompatible with some clients; always test against a real Android client.
  3. Date timezones on Alpine Linux builds: install tzdata if you rely on local timezones.

Do I regret moving to Bun?

No. p95 latency on Gatsu dropped ~32% versus the Node version, and container startup became sub-second. But I stay careful: for mission-critical services that do not need a new innovation cycle, Node.js LTS is still a defensible choice.

Topics

#Backend #Performance #DevOps

Share

Back to all posts

Further reading

Further reading