How Much Traffic Can a $5 VPS Handle for Next.js, APIs, and Static Assets?

How Much Traffic Can a $5 VPS Handle for Next.js, APIs, and Static Assets?

Tako-kun ·

A $5-ish VPS is not a toy server. The useful question is not “can a cheap box run my app?” It almost certainly can. The useful question is: which part of the app consumes the box first? A static asset request, a cached image variant, an API route that hits Postgres, and a server-rendered Next.js page all look like “web traffic” on a bill. They do not look the same to the CPU.

We now have enough public Tako data to stop hand-waving. The small-VPS HTTPS proxy benchmark put Tako on one 2 vCPU VM, with load generator, proxy, and upstream app sharing the machine. Tako returned 12,504 clean HTTPS 200 RPS at c5000 and 7,266 clean HTTPS 200 RPS at c20000, with zero non-200 responses and zero client errors in every Tako HTTP row.

That is not “your Next.js app will do 12k RPS.” It is a ceiling for a very small upstream response on one saturated box. Real apps spend CPU on rendering, JSON, database calls, auth, image transforms, and cache misses. The benchmark is still useful because it gives the first budget line: on modest hardware, the platform path is unlikely to be the first limit for most small apps.

Start with the traffic mix

A Next.js app on a VPS usually has at least three traffic classes:

Traffic classWhat the server doesUsual bottleneckTako path
Static assetsServe files from public/ or framework build outputTLS, file I/O, connection count, browser cache policyDirect static response after route match
Optimized imagesValidate source, load original, resize/encode misses, serve cached variantsTransform misses first, cache hits later/_tako/image plus source and transform caches
API routes and SSR pagesRun your Node/Bun process, app code, data fetching, auth, serialization, and headersApp CPU, database, external APIs, memoryProxy to a healthy app instance selected by tako-server

That table matters more than one headline RPS number. If 80% of your traffic is static JS, CSS, fonts, and images that browsers cache aggressively, your server has a different life than an app where every request renders a dashboard and fans out to three APIs.

Next.js helps with this split. Its current deployment docs describe output: "standalone" as a way to produce a deployment-ready folder with the traced runtime files, and static export as a separate output: "export" mode for sites that do not need server features. With Tako, the normal server-rendered path is:

// next.config.ts
import { withTako } from "tako.sh/nextjs";

export default withTako({});

The nextjs preset and framework guide explain the rest: withTako() enables standalone output, installs the Tako adapter, configures local dev origins, and writes .next/tako-entry.mjs. If Next emits .next/standalone/server.js, Tako uses it; otherwise the wrapper falls back to next start. Your tako.toml stays boring:

runtime = "bun"
preset = "nextjs"

[envs.production]
routes = ["app.example.com"]
servers = ["vps-1"]

The important part is where requests land. Tako matches the app route, reserves /_tako/* for platform endpoints, serves matching static assets directly, and proxies the rest to the app process.

Diagram

Translate the benchmark into a budget

The public proxy run gives one conservative starting point: a single small VM can move thousands of clean HTTPS responses per second through Tako’s app-aware path when the upstream work is tiny. The run used a 2 vCPU, 7.8 GiB RAM VM, HTTP/1.1 over TLS, one certificate, one route, and a small Go plaintext app behind each proxy. Load generator, proxy, and app all ran on the same host.

Here is how to turn that into a practical Next.js budget without lying to yourself:

Workload shapeCapacity read from the benchmarkWhat to measure in your app
Cached static assets and tiny API responsesThe platform can plausibly handle many thousands of clean HTTPS RPS on 2 vCPUFile hit ratio, browser cache headers, compression, connection use
JSON APIs with normal database accessThe proxy is probably not the first limiterDB latency, pool size, p95 route time, serialization CPU
SSR pages with auth, data fetching, and renderingThe benchmark is only a transport ceiling, not a page-rendering promiseRender time, external calls, cache hit rate, memory per instance
First-hit image variantsDo not compare to tiny-response RPS; transforms are intentionally bounded workMiss rate, source size, output widths, transform queue pressure
Cached image variantsMuch closer to static traffic after the transform existsTransform cache hit rate, disk cache size, response format

That gives a better answer than “12k RPS.” For a marketing site with a few API calls, a cheap VPS may spend most of its time serving static files and cached image variants. For a SaaS dashboard, the app process and database will usually decide capacity first. For an image-heavy app, the first wave of uncached image sizes is the expensive part; after variants are cached, the same URLs become much cheaper.

Tako’s image behavior is designed around that distinction. Public optimized image responses use long-lived immutable cache headers. Source bytes are cached briefly in memory so one page asking for several widths can reuse the original, and transformed variants are cached on local disk under a bounded cache. Misses run through isolated libvips worker processes with a bounded queue, so image work does not silently eat the entire proxy and app budget.

This is also where deployment behavior matters. During a rolling deploy, Tako starts a fresh instance, waits for the health check, adds it to the load balancer, and drains the old one. That does not make a slow page fast, but it keeps deploy mechanics from becoming the bottleneck.

A concrete testing plan

If you want to know what your $5 VPS can handle, test traffic classes separately before you test the whole app. One combined “homepage” benchmark hides too much.

Test targetExample URLWhy it exists
Static asset/assets/app.css or /_next/static/...Measures direct file serving and TLS pressure
Cached image variant/_tako/image?src=%2Fhero.jpg&w=1200 twiceSeparates transform miss from steady-state hit
Cheap API route/api/health or /api/versionMeasures proxy-to-app overhead with tiny app work
Real API route/api/search?q=...Measures database, auth, and JSON work
SSR page/dashboard with representative cookies/headersMeasures the page your users actually wait on

Run each target with enough concurrency to find the bend in the curve, not just the biggest RPS number you can screenshot. Watch p95 and p99 latency, not only average latency. Watch tako logs for app-scoped proxy diagnostics: request IDs, selected instances, route matches, cold-start wait time, upstream latency, compression fields, and handler/cache results. The CLI reference covers the log surface, and How Tako Works explains the proxy, app lifecycle, static files, images, and reserved routes.

That is how a $5 VPS becomes capacity planning.

The honest answer

For tiny HTTPS responses through Tako’s app-aware proxy path, the published small-VM baseline is thousands of clean 200 responses per second: 12.5k at c5000 and 7.3k at c20000 on the tested 2 vCPU VM. For static assets and warmed image variants, that is the right neighborhood to start thinking in. For API routes and server-rendered pages, your app work decides the number.

That is good news. The cheap VPS argument is not only about price; it is about having enough headroom to run the app and platform layer together. Tako handles routing, TLS, static files, image optimization, health checks, secrets, logs, and rolling deploys on the same machine, so the traffic question becomes concrete: what is static, what is cached, and what actually needs your Next.js process?

Start with the Next.js framework guide, read the full performance report, and inspect the open-source repo if you want to see the moving parts. Your small server probably has more room than you think. The trick is measuring the right room.