{"slug":"pingora-proxy-manager-tako-reverse-proxy-dashboard","url":"https://tako.sh/blog/pingora-proxy-manager-tako-reverse-proxy-dashboard/","canonical":"https://tako.sh/blog/pingora-proxy-manager-tako-reverse-proxy-dashboard/","title":"Pingora Proxy Manager: Why Tako Is More Than a Reverse Proxy Dashboard","date":"2026-05-21T14:02","description":"A Pingora proxy manager handles routes. Tako coordinates deploys, TLS, readiness, process state, and scale-to-zero in one app control plane.","author":null,"image":"9409ef186dd0","imageAlt":null,"headings":[{"depth":2,"slug":"a-proxy-manager-manages-traffic-config","text":"A proxy manager manages traffic config"},{"depth":2,"slug":"tako-treats-proxying-as-app-lifecycle","text":"Tako treats proxying as app lifecycle"},{"depth":2,"slug":"readiness-is-not-a-port-field","text":"Readiness is not a port field"},{"depth":2,"slug":"tls-belongs-to-the-app-route-too","text":"TLS belongs to the app route too"},{"depth":2,"slug":"scale-to-zero-makes-the-proxy-active","text":"Scale-to-zero makes the proxy active"},{"depth":2,"slug":"so-is-tako-a-pingora-proxy-manager","text":"So is Tako a Pingora proxy manager?"}],"markdown":"If you search for \"Pingora proxy manager\", you are probably looking for something reasonable: a way to run a Rust proxy, add hosts, point each host at an upstream, issue certificates, and reload config cleanly.\n\nThat category makes sense. [Pingora](https://github.com/cloudflare/pingora) is a framework, not a finished dashboard. Projects like [Pingora Proxy Manager](https://github.com/DDULDDUCK/pingora-proxy-manager) and [Pingap](https://github.com/vicanso/pingap) show the natural next layer: a Pingora-backed reverse proxy product with config, a web UI, SSL automation, upstreams, access control, and observability.\n\nTako is not trying to be that dashboard.\n\nTako uses Pingora, but the product boundary is different. We are not asking, \"How do we make proxy config nicer to edit?\" We are asking, \"What if the proxy, deploy system, TLS manager, process supervisor, readiness protocol, logs, and scale-to-zero all agreed on the same app state?\"\n\nThat is bigger than a reverse proxy dashboard, and it can feel unusual if you expected a screen full of upstream rows.\n\n## A proxy manager manages traffic config\n\nA reverse proxy manager is usually centered on resources like hosts, upstreams, certificates, middleware, and access rules. That is useful because raw proxy config can get tedious fast.\n\n| Job                 | What a proxy manager usually owns               |\n| ------------------- | ----------------------------------------------- |\n| Route a domain      | Host, path, and upstream mapping                |\n| Add HTTPS           | Certificate issuance, renewal, and storage      |\n| Change a backend    | Update upstream address, weight, or timeout     |\n| Protect an endpoint | IP allowlists, basic auth, rate limits, plugins |\n| Observe traffic     | Access logs, response codes, upstream timing    |\n| Apply changes       | Hot reload or graceful restart                  |\n\nThat is the right shape when your apps already exist somewhere else. Maybe Docker starts them, systemd starts them, or Kubernetes owns the service registry.\n\nIt usually does not know how that process was built, what version it is, whether it is the new release or old release, which secrets it received, or whether the next request should wake it from zero.\n\nTako chooses not to separate that lifecycle from the proxy.\n\n## Tako treats proxying as app lifecycle\n\nIn Tako, routes live with the app:\n\n```toml\nname = \"api\"\nruntime = \"bun\"\n\n[envs.production]\nroutes = [\"api.example.com\", \"example.com/api/*\"]\nservers = [\"prod\"]\n```\n\nThat little block is not just proxy config. It participates in [`tako deploy`](/docs/deployment/), certificate issuance, route conflict detection, runtime startup, static asset serving, load balancing, logs, and cold starts. The same app identity appears in [`tako.toml`](/docs/tako-toml/), server state, the Pingora route table, TLS, and instance management.\n\nHere is the shape:\n\n```d2\ndirection: right\n\ndashboard: \"Proxy manager\" {\n  direction: down\n  ui: \"dashboard\"\n  config: \"proxy config\"\n  proxy: \"Pingora proxy\"\n  certs: \"cert store\"\n  upstreams: \"existing upstreams\"\n\n  ui -> config: \"edit host\"\n  config -> proxy: \"reload\"\n  certs -> proxy: \"TLS\"\n  proxy -> upstreams: \"forward\"\n}\n\ntako: \"Tako control plane\" {\n  direction: down\n  cli: \"tako deploy\"\n  server: \"tako-server\"\n  state: \"app state\"\n  pingora: \"Pingora proxy\"\n  app: \"native app process\"\n\n  cli -> server: \"artifact + routes + env\"\n  server -> state: \"version, scale, health\"\n  state -> pingora: \"route + backend\"\n  server -> app: \"spawn + readiness\"\n  pingora -> app: \"loopback request\"\n}\n```\n\nThe proxy manager path starts with config and ends at traffic. Tako starts earlier. It builds and uploads the release, runs production install, starts the new instance, waits for readiness, probes health, adds the backend to the load balancer, drains old instances, and then keeps serving through the same Pingora proxy.\n\nThe proxy does not need a user-facing \"reload this host\" button. The route changed because the app changed.\n\n## Readiness is not a port field\n\nIn a dashboard-oriented proxy, an upstream is usually something you type or discover: `127.0.0.1:3000`, `api:8080`, a Docker service, a Kubernetes service, or a static list of servers.\n\nIn Tako, deployed app instances bind to `127.0.0.1` on an OS-assigned port. The app starts with `PORT=0`, then the SDK writes the actual bound port to file descriptor 4 once the server is listening. Only after that does `tako-server` route traffic to the loopback endpoint.\n\nThe source of truth is not \"the user entered port 3000.\" It is \"this exact process instance reported that it is listening, then passed health checks.\"\n\n| Question                           | Dashboard proxy answer                   | Tako answer                                           |\n| ---------------------------------- | ---------------------------------------- | ----------------------------------------------------- |\n| What port should receive traffic?  | The configured upstream port             | The port the instance reported on fd 4                |\n| Is the new release ready?          | Usually external health or manual timing | SDK readiness plus health probe                       |\n| Can the old process stop?          | Another tool decides                     | Rolling update drains it after the new one is healthy |\n| Where are startup errors recorded? | Process manager or app logs              | App-scoped logs in Tako                               |\n| Who updates the route?             | Human, API, file watcher, or provider    | The deploy flow updates app state                     |\n\nThis is where Pingora being a framework matters. The [`pingora-proxy`](https://docs.rs/pingora-proxy/latest/pingora_proxy/) crate exposes programmable request phases through `ProxyHttp`: inspect a request, answer early, select an upstream, adjust the upstream request, inspect the response, and log.\n\nFor a normal proxy, `upstream_peer` means \"pick one of the configured backends.\" For Tako, it means \"resolve the app route, maybe serve a Tako-owned endpoint, maybe serve a static file, maybe wake the app, then pick a healthy native process.\"\n\n## TLS belongs to the app route too\n\nTLS is another place where \"proxy config\" and \"app lifecycle\" overlap.\n\nWhen a route is deployed, Tako knows which hostnames belong to the app. That route set drives certificate management. Exact hostnames can use Let's Encrypt HTTP-01. Wildcard hostnames use Cloudflare DNS-01 credentials set up with `tako credentials set ssl.cloudflare --env <env>`. Private and local hostnames get self-signed certificates.\n\nAt request time, the TLS handshake happens before app routing. The browser sends SNI, and `tako-server` chooses the certificate by exact hostname first, wildcard fallback second, then a default self-signed certificate if no match exists yet.\n\nA reverse proxy dashboard can manage certs too. The difference is ownership. In Tako, certificates are not a separate panel that happens to mention the same host. They are an effect of app routes and deploy validation. If a wildcard route needs provider credentials, deploy can fail before shipping an unreachable app.\n\n## Scale-to-zero makes the proxy active\n\nThe biggest philosophical split is scale-to-zero.\n\nIf an always-on app has no healthy backend, the proxy should return `503`. Something is wrong. But if an app is intentionally scaled to zero with [`tako scale 0`](/docs/cli/), \"no backend\" is not the end of the request. It is the beginning of a cold start.\n\nTako's backend resolution handles that path:\n\n| State                             | What Tako does                   |\n| --------------------------------- | -------------------------------- |\n| Healthy instance exists           | Route through the load balancer  |\n| No backend, desired instances > 0 | Return `503 Service Unavailable` |\n| No backend, desired instances = 0 | Start one instance and wait      |\n| Startup passes readiness          | Continue the waiting request     |\n| Startup times out                 | Return `504 Gateway Timeout`     |\n| Startup fails                     | Return `502 Bad Gateway`         |\n| Too many waiters                  | Return `503 Service Unavailable` |\n\nThe first request becomes the leader that triggers the spawn. Later requests wait behind the same cold start, up to the configured queue limit. The app is still a normal native process; it just does not need to sit in memory all day.\n\nThis is not a feature a proxy dashboard can add by editing an upstream row. It requires the proxy to talk to the process supervisor, readiness protocol, app state store, load balancer, and logs. In Tako, those are already in the same `tako-server` process.\n\n## So is Tako a Pingora proxy manager?\n\nSort of, but only if you squint. The proxy matters. You would miss it immediately. But it is not the whole product.\n\nIf you want to manually manage reverse proxy hosts, upstreams, TLS, and access rules, a Pingora-powered proxy manager is a good category to explore.\n\nIf you want a VPS app platform, the proxy is not the product. The product is the agreement between [`tako.toml`](/docs/tako-toml/), [`tako deploy`](/docs/deployment/), TLS, secrets, readiness, native process supervision, scale-to-zero, static assets, app logs, and local HTTPS through [`tako dev`](/docs/development/).\n\nThat is why Tako does not expose Pingora as a dashboard full of knobs. Pingora is the request engine inside the platform. Tako is the control plane around it.\n\nThe distinction is small until something changes: a new route, a new release, a failed startup, a wildcard cert, or a scaled-to-zero admin app waking up after lunch. At that moment, the question is not \"did the proxy reload config?\" It is \"does the whole app lifecycle know what traffic should do next?\"\n\nThat is the layer Tako is building."}