We run a real crypto exchange for $148/month. Here is what it handles, and how.
Open Exchange is an open-source, low-latency exchange stack: a Raft-replicated matching engine, a separate Raft-replicated money ledger (the Assets Engine), an order-management service with auth, balance and risk, a market-data gateway, and a control plane that supervises all of it. Most people assume "matching engine" means a rack of servers. It does not.
Our public demo runs order intake, balance holds, risk checks, matching, and market data, the whole pipeline, on one m7g.xlarge: 4 vCPU, 16 GB, about $148/month in AWS Frankfurt. Here is exactly what that box does, and how you can stand up your own.
What $148 handles
Two numbers, because they measure two different things.
End-to-end, through the full production path (REST API, token auth, balance check, price-collar risk, matching, response):
- About 7,500 order submissions per second, sustained, on the $148 box. That is roughly 650 million orders a day, with every order authenticated, balance-checked, and risk-checked.
- p50 around 2.2 ms, p99 around 5.7 ms, end-to-end over HTTP.
- Measured from a co-located client (a separate small instance in the same availability zone) so the exchange keeps all four of its cores. The box was the bottleneck at this rate.
The matching engine core, in isolation (what the engine does once an order is inside):
- 150,000 orders per second at 100% acceptance, ingress p99 around 0.64 microseconds (sub-microsecond), benchmarked on comparable AWS hardware.
The bottleneck at $148 is not the engine. It is the per-order HTTP, auth, balance and risk work. The engine has roughly 50x headroom. That is the point: correctness and durability first, every order authenticated, balance-checked, risk-checked, and replicated, and it still clears thousands of orders a second on a box that costs less than a phone plan.
What is actually running on that box
Not a toy. The full stack, replicated:
| Component | What it is | Instances |
|---|---|---|
| Matching engine | Aeron Cluster (Raft), the order book | 3-node cluster |
| Assets Engine | Aeron Cluster (Raft), the money ledger (balances, holds, settlement) | 3-node cluster |
| OMS | Order management: REST and gRPC API, auth, balance, risk | 1 |
| Market gateway | Order-book and trade fan-out to clients | 1 |
| Postgres | Durable order and execution records | 1 |
| Admin gateway | Process supervisor and control plane | 1 |
That is six Raft consensus nodes plus services, co-resident on 4 vCPU, sitting at an idle load of about 3.4, with headroom to spare.
The trick: do not burn cores you are not using
A low-latency engine's instinct is to busy-spin, to poll a core flat-out so it never misses a nanosecond. Perfect on a dedicated 64-core box with pinned cores. Ruinous on a shared 4-vCPU cloud box, where it burns most of the machine doing nothing.
Getting to $148 meant finding and taming the busy-spins:
- The embedded media driver ran
DEDICATEDthreading with aBusySpinWaitStrategyon every agent, about 3 cores per node, at idle. We made it configurable:SHAREDthreading with a sleeping idle strategy on constrained hosts. - The per-market publishers each ran an LMAX Disruptor with a hard-wired
BusySpinWaitStrategy, a whole core per market, spinning for events that were not coming. We wired the wait strategy to the same knob: busy-spin in prod, block or sleep on a demo box.
Both are gated behind one setting (TRANSPORT_IDLE_MODE). Prod defaults are byte-identical to before, so you opt into "lean" only on the small box. The result: idle CPU dropped from about 7 cores to about 3, and the whole stack fit on half the instance. The same $148 box was a $296 box a week ago, so the credit runway doubled.
The server is the cheap part. So is the team.
$148/month is the hosting bill. The bigger cost it kills is the one nobody puts on a slide: owning a matching engine.
Because it is this light, it runs wherever you develop: a laptop, a CI runner, a $5 dev box. Run start-all and you have a full, replicated exchange to build against. No dedicated cluster to book, no "can I get time on the perf rig". Every engineer gets the real core on their own machine, and every pull request can spin one up and tear it down.
And because the control plane runs itself, it supervises the nodes, restores your last desired state on reboot, and recovers from crashes, you do not staff a team to babysit consensus and order books. The hard, expensive, easy-to-get-wrong part becomes a one-click dependency that sits underneath you and manages itself.
That flips the build economics. Instead of spending your first year, and your best engineers, rebuilding a matching engine and a money ledger (the table stakes every exchange needs and no customer ever thanks you for), you drop in a core that runs itself and spend that year on the part that is actually yours: your markets, your products, your users. The core is infrastructure. Your business is the business. Put a self-managing engine at the heart of the thing, and both your ops bill and your R&D bill come down.
How to run your own
Target: m7g.xlarge (4 vCPU, 16 GB, about $148/month on-demand, less on Graviton savings plans), Amazon Linux or Ubuntu, in a region near your users.
- Provision and network. One EC2 instance with an Elastic IP (it survives stop and start). No load balancer, no tunnel. The origin serves directly behind a reverse proxy (we use Caddy) with a TLS cert, and the security group is locked to your CDN's IP ranges.
- OS tuning. Raise the socket buffers the Aeron nodes need and make it persistent:
net.core.rmem_maxandnet.core.wmem_maxset to 16 MB in/etc/sysctl.d/. - Build the stack (v0.4.0-beta):
match,assets,order-management, and theadmin-gatewaycontrol plane. All open source at github.com/openexch. - Pick the lean profile. The admin gateway ships runtime profiles. The
cloudprofile setsdriverMode=embedded,threading=shared,idleMode=sleep, and lean heaps, the settings above, packaged. - Let the control plane run it.
systemdsupervises the admin gateway. The admin gateway supervises the six cluster nodes and services and restores your last desired state on reboot. CallPOST /api/admin/processes/start-alland it comes up. - DNS and TLS. Point a proxied A record at the Elastic IP. The origin cert terminates TLS.
A one-command bootstrap script and a Packer AMI are next. The goal is "Launch on AWS" in one click.
Why this matters
Running an exchange has always looked like a capital-intensive, ops-heavy undertaking. It is not anymore. The engine is fast enough that a $148 box is limited by how carefully it checks each order, not by matching speed, and that is the right thing to be limited by. It is cheap to run, cheap to build on, and it manages itself. Open the repos, run the benchmark yourself, and tell us what your box does.