>
Open Source

Hyperswitch is the open-source payment router that runs on your box

If you have two payment processors and a wish list, the easy part is wiring them up. The hard part is the second processor, the third currency, the retry rules, the dashboard for finance, and the migration story when one of those processors raises its rate. Hyperswitch is an Apache 2.0 project from the Indian payments company Juspay that puts a single API in front of a long list of processors, and it can run entirely on a Linux server you control.

The setup is not a single binary. There is no apt install hyperswitch. What you actually deploy is a small fleet of Docker containers: an app server (a payment routing layer written in Rust), a Postgres database, a Redis cache, and a web-based Control Center that you use to manage routing rules and view transactions. Your application sends a payment request to Hyperswitch over HTTP, and Hyperswitch handles the per-processor specifics.

This guide treats it as a Linux self-hosting project rather than a fintech tutorial. We will look at what the stack actually needs, where the gotchas live, and what dropping in your own payment switch is likely to cost you in operations time.

What Hyperswitch is, and what it is not

The official framing is “payments switch”, a piece of infrastructure that sits between your application and the long tail of payment processors (Stripe, Adyen, PayPal, and many regional alternatives). Most payment integrations start with one processor and one SDK. The moment you add a second processor, you start writing routing logic, retry logic, and reconciliation glue. Hyperswitch centralises that.

It is also a different kind of thing than a hosted gateway. The pieces you install are:

  • An app server (Rust) that exposes a payments API at port 8080.
  • A web-based dashboard called the Control Center at port 9000, used for configuration and reporting.
  • A web checkout SDK at port 9050, which includes HyperLoader.js for client-side integration.
  • Postgres at 5432 (the transactions database).
  • Redis at 6379 (used for caching, queueing, and a few coordination tasks).

The whole stack is meant to be reachable from a single Linux server. The source guidance lists Ubuntu 26.04 and Rocky Linux 10 as the tested targets, but Debian, Fedora, and other distros with a current Docker Engine should work the same way.

What you need on the host before you start

The minimum bar for the standard profile is 4 GB of free RAM and 2 CPU cores. The full profile (which also pulls in Grafana, Prometheus, and the scheduler) wants more. If you plan to run this on a home server alongside other things, 4 GB is the floor, not the comfortable recommendation.

Docker Engine and the Docker Compose plugin are required. The setup script also supports Podman for anyone who avoids the Docker daemon. You need these ports free on the host before the first run:

  • 8080 (Hyperswitch API)
  • 9000 (Control Center)
  • 9050 (Web SDK)
  • 5432 (Postgres)
  • 6379 (Redis)

If you already have a Postgres or Redis on the same host from another project, something will collide immediately. Pick a different host or change the published ports in the Compose file before you start.

Hostname and TLS are out of scope for the bare-metal setup. Until you put a reverse proxy in front, the Control Center is a plain HTTP dashboard bound to localhost. Treat it as an admin tool, not a public-facing surface.

Running the setup

The upstream ships a scripts/setup.sh that handles the Compose profile selection, so the first-run path is short:

git clone --depth 1 --branch latest https://github.com/juspay/hyperswitch
cd hyperswitch
scripts/setup.sh

The --depth 1 --branch latest combo clones only the current tagged release, which keeps the first download small. The setup script detects Docker or Podman, prepares the Postgres and Redis config, and asks you to pick a profile:

  • Standard, the app server, Control Center, and web SDK. The right choice for most first-time setups.
  • Full, Standard plus monitoring (Grafana and Prometheus) and the scheduler service.
  • Standalone App Server, only the core services, no dashboard. Useful for headless deployments.

The first run pulls several container images, so a slow internet connection will make this longer than it looks. Once the images are cached, subsequent starts take a few seconds.

After the script finishes, the source recommends sanity-checking the container state yourself rather than trusting the script’s summary:

docker compose ps

Look for the hyperswitch-server line. If it shows (healthy), the Rust application has started, connected to Postgres, and run its migrations. A Restarting status is the usual signal that something went wrong; docker compose logs hyperswitch-server will show the actual error, almost always a database connection issue or a port collision.

Confirming the API is actually live

The health endpoint at /health requires no authentication and is the cheapest way to confirm the deployment is working:

curl --head --request GET 'http://localhost:8080/health'

The source says a healthy response carries a via: HyperSwitch header, which is the right way to confirm the response came from the Hyperswitch app server and not another service that happens to own port 8080. If you see a 200 but no HyperSwitch header, you are probably hitting the wrong service.

First payment in the Control Center

After the health check passes, open http://your-server:9000 in a browser and create an account. The account is stored in your local Postgres, so it is local-only by default. Inside the dashboard, the first thing to configure is the Dummy Processor, which simulates approved and declined transactions without contacting any real gateway. That keeps the rest of the setup off the public payment rails.

Then generate an API key under Developers. The key is shown only once at creation time, so copy it to your password manager immediately. If you lose it, you generate a new one and re-deploy the application with the new value.

A test payment via the dummy processor is the cleanest end-to-end check. The source ships a curl example that posts a 499 cent USD charge to a test card (4242 4242 4242 4242, expiration 12/30, CVC 123). A successful response carries status: succeeded and a connector: dummy_processor field telling you which processor handled the request. The whole round trip should take a few hundred milliseconds.

Routing logic and when it matters

The single-processor setup is a bit of a toy. Routing is where the switch earns its name. The Control Center lets you write rules that pick a connector based on the transaction: card type, currency, country, business versus consumer card, transaction amount. A common pattern is a primary-default rule with a fallback for issuer declines.

You can do this in your application code, and that is how most small projects do it. The argument for moving it into Hyperswitch is that the rules live next to the metrics, the audit log, and the connector health, which means a payment engineer can change routing without redeploying your application. That is a real improvement, but it only matters once you have more than one processor and a reason to switch between them.

Trade-offs

There are real reasons to consider Hyperswitch, and a smaller number of real reasons to skip it.

  • You give up hosted simplicity. Hyperswitch is not a SaaS. You run the database, the cache, the dashboard, and the upgrade cycle. The Linux Foundation’s hosted offerings exist, but the self-hosted version is the one most open-source-curious teams take.
  • Postgres and Redis are exposed by default. The standard Compose configuration publishes ports 5432 and 6379 to the host. On a public VPS that means a Postgres and Redis that anyone on the internet can try to reach. The source recommends a firewall, but the default does not enforce one.
  • The dependency surface is wide. The app server depends on Rust crates, the SDK depends on JavaScript, the Control Center depends on a Node stack, and the database depends on a Postgres version that the Compose image pins. Upgrading is not always a one-step affair.
  • The dummy processor is the only default. Until you wire up real Stripe, Adyen, or regional credentials, payments do not flow. The setup script does not onboard you to any actual processor.
  • The single-server design has limits. Postgres, Redis, and the queueing inside the cache are all running on one host. The moment you need higher availability, you are doing real infrastructure work, and the project’s documentation is honest about that scope.

The honest reason to bring Hyperswitch in is that you have a second processor or a third currency and you are tired of writing the same routing code in three places. The honest reason to skip it is that one processor and one SDK cover everything you do, and a payment switch is just another piece of infrastructure to keep running.

What to do next

If you want to take this for a real spin, the cheapest path is a $4-a-month VPS with 4 GB of RAM, the script setup outlined above, and the dummy processor before you touch anything in production. Once the test payment returns succeeded, you have a working payment switch on your own box. Everything after that is a configuration problem.

Leave a comment