The idle timeout (default: 10 seconds) applies to streaming responses. If your stream goes quiet for longer than idleTimeout, the connection closes mid-stream. Disable it per-request with server.timeout(req, 0).
Return a BunFile as the response body to serve files from disk. Bun uses the sendfile(2) syscall for zero-copy transfers when possible.
Bun.serve({ routes: { // Served from filesystem on every request; supports range requests and 304s "/download/:file": req => { return new Response(Bun.file(`./public/${req.params.file}`)); }, // Buffered in memory at startup; zero allocation per request "/logo.png": new Response(await Bun.file("./public/logo.png").bytes()), }, fetch(req) { return new Response("Not Found", { status: 404 }); },});
Override the idle timeout for a single request. Pass 0 to disable it entirely — useful for Server-Sent Events and long-running streams.
Bun.serve({ async fetch(req, server) { server.timeout(req, 60); // allow 60 s of inactivity for this request const body = await req.text(); return new Response(`Got: ${body}`); },});
Instead of calling Bun.serve() explicitly, you can export default a server config object. Bun detects the fetch property and starts the server automatically:
import type { Serve } from "bun";export default { port: 3000, fetch(req) { return new Response("Bun!"); },} satisfies Serve.Options<undefined>;
import { Database } from "bun:sqlite";const db = new Database("posts.db");db.exec(` CREATE TABLE IF NOT EXISTS posts ( id TEXT PRIMARY KEY, title TEXT NOT NULL, content TEXT NOT NULL, created_at TEXT NOT NULL )`);Bun.serve({ routes: { "/api/posts": { GET: () => { const posts = db.query("SELECT * FROM posts").all(); return Response.json(posts); }, POST: async req => { const body = await req.json(); const id = crypto.randomUUID(); db.query( "INSERT INTO posts (id, title, content, created_at) VALUES (?, ?, ?, ?)", ).run(id, body.title, body.content, new Date().toISOString()); return Response.json({ id, ...body }, { status: 201 }); }, }, "/api/posts/:id": req => { const post = db .query("SELECT * FROM posts WHERE id = ?") .get(req.params.id); if (!post) return new Response("Not Found", { status: 404 }); return Response.json(post); }, }, error(error) { console.error(error); return new Response("Internal Server Error", { status: 500 }); },});