Skip to main content

Performance

View as Markdown

This page gives measured numbers for one Dex Server node and what it costs to run.

How the benchmark ran

The numbers below were measured on 2026-11-09 in AWS us-west-2:

  • Server: one Dex Server node on a c7gd.large (2 vCPU) or a c7gd.4xlarge (16 vCPU). Its local store was on the instance's NVMe disk. Its log went to S3 Standard in the same Region.
  • Load: a separate c7g.8xlarge in the same Availability Zone ran the benchmark tool with a Go SDK Worker. Its CPU stayed below 38%.
  • Versions: Dex Server (server-zd) v0.1.23 for Steps, Flows, and Channel wakes; v0.1.25 for RPCs and reads.
  • Runs: each point had a 10-second warmup and a 45-second measurement on a new server. Most points ran three times, and the tables show the median. Flow starts ran once per point.
  • Load model: a fixed number of concurrent clients, each sending its next request when the last one returns. Latency grows with the client count once the server is busy.

Every run and its settings are in the benchmark results folder, and Reproduce a result shows how to repeat one.

Peak throughput

Operationc7gd.largec7gd.4xlarge
SYNC Steps1,772 per second8,403 per second
ASYNC Steps2,105 per second10.1k per second
Flows started and completed, one Step each1,111 per second5,626 per second
RPCs that read one Attribute15,392 per second67.3k per second
RPCs that lock and update one Attribute2,165 per second13.8k per second
Reads of ten 16 KiB Attributes, without a Worker5,941 per second11.3k per second
Channel messages that wake a waiting Step460 per second2,278 per second

Latency below the peak

These rows ran at about half of peak throughput. Latency is in milliseconds. The client count differs by row, and latency grows with it. The SYNC rows ran with 96 clients on c7gd.large and 1,024 on c7gd.4xlarge. So the larger node shows a higher SYNC latency because it carried more than ten times the load, not because it is slower.

OperationInstanceThroughputp50p99
SYNC Stepc7gd.large846 per second105285
SYNC Stepc7gd.4xlarge4,527 per second218382
ASYNC Stepc7gd.large1,224 per second1.34.9
ASYNC Stepc7gd.4xlarge4,766 per second1.63.3
RPC that reads one Attributec7gd.large7,501 per second0.50.9
RPC that reads one Attributec7gd.4xlarge35.0k per second0.62.1
Channel wakec7gd.4xlarge1,400 per second139308

The Channel wake throughput includes untimed setup before each publish. Only its latency, from the publish to the start of the woken Step, measures Dex.

What the numbers mean

  • A SYNC Step waits for S3. A SYNC Step waits for two log commits: its attempt start and its result. Each commit is one S3 PUT, and one commit can carry the commands of many Flows. At the SYNC peaks, a commit took 41 to 98 milliseconds on average. Under load, a SYNC Step also waits for its batch, so it needs many concurrent Flows to reach peak throughput.
  • What a Flow adds. At the half-peak load on c7gd.large (96 concurrent clients), a SYNC Step took 105 milliseconds at p50. A Flow with five SYNC Steps in a row therefore spends about half a second waiting on Dex commits, plus the time of your own code. Agent sessions use SYNC Steps for model calls and tool calls, so each one adds a commit to a turn.
  • At low load. The benchmark did not measure SYNC Steps at low load. A lightly loaded SYNC Step still waits for its two commits, the start and the result, so a handler that waits for Charge sees about two object-storage writes in a row, plus your own code. Those writes averaged 41 to 98 milliseconds at the peaks; at low load, expect your object store's single-write latency. This is an estimate, not a measurement.
  • An ASYNC Step moves on at once. The Flow moves on before the commit, so a Step takes 1 to 2 milliseconds at low load. SYNC and ASYNC Steps explains the trade-off.
  • S3 requests follow batches, not Steps. Dex Server groups writes into log batches. A busy node made 23 to 98 log PUTs per second, whatever its size. At USD 0.005 per 1,000 PUTs, that is at most about USD 1.8 per busy hour per node. An idle node renews its lease with about 0.3 PUTs per second.
  • CPU is the limit. The 2-vCPU node used 93 to 99% of its CPU at every peak. The 16-vCPU node used 68 to 87% at most peaks. Reads of large Attributes on the 16-vCPU node were limited by its 15 Gbps network instead.
  • Reads need no Worker. An RPC runs on a Worker. A direct Attribute read goes only to Dex Server.
  • These peaks are the ceiling of one cluster. One active node serves a cluster. Limits covers that ceiling, failover, and upgrades.

What it costs to run

Dex Server needs one instance, an optional standby instance, and object storage. Price the instances and the stored bytes at your provider's rates. The S3 requests follow from the numbers above, at USD 0.005 per 1,000 PUTs:

SetupPUTs per secondPUTs per 30-day monthPUT cost per month
Idle node, lease renewals onlyabout 0.3about 0.78 millionabout USD 4
Busy node, low end of the measured range23about 60 millionabout USD 300
Busy node at the highest measured rate, all month98about 254 millionabout USD 1,270

Most deployments sit between the first two rows, because a node is busy only part of the time.

A worked example for a light load: 1 million orders a month, each a Flow with five SYNC Steps, is 5 million Steps. A SYNC Step stores its start and its result, and each log commit is one PUT. At light load a batch rarely holds more than one commit, so the upper bound is about 2 PUTs per Step: 10 million PUTs, about USD 50 a month, plus about USD 4 for lease renewals. Under heavier load several commits share a batch, so the cost per Step falls. The monthly total is then:

  • instances: the active node, plus a standby if you run one, at your provider's hourly price;
  • PUTs: the estimate above, or the table's rows for a node that stays busy;
  • stored bytes: the runs kept in the retention window, at your provider's price. The benchmark did not measure stored bytes per Flow. Closed runs are deleted after retention, so storage follows the number of runs in that window.

Reproduce a result

The scripts in benchmark/aws rerun a recorded point on your own AWS account. You need:

  • the AWS CLI v2 and openssl, with a profile that can manage EC2, S3, and IAM;
  • an EC2 key pair in the Region;
  • Linux arm64 builds of dexbench and dex-server-zd, built on Ubuntu 24.04 arm64 to match the hosts.

Launch the shared resources, a server, and a load host in one Availability Zone:

export DEXBENCH_RUN_ID=<run id> DEXBENCH_AWS_PROFILE=<profile> DEXBENCH_AWS_REGION=us-west-2
export DEXBENCH_AZ=us-west-2b DEXBENCH_KEY_NAME=<key pair>
benchmark/aws/launch.sh infra
DEXBENCH_SERVER_INSTANCE_TYPE=c7gd.large benchmark/aws/launch.sh server
DEXBENCH_MARKET=on-demand DEXBENCH_LOAD_INSTANCE_TYPE=c7g.8xlarge benchmark/aws/launch.sh load

Then rerun a point from a recorded result set. The script reads that run's settings from its config.env and points.txt; leave out the scenario and the client count to rerun every point:

benchmark/aws/reproduce.sh benchmark/results/<run> sequential-steps 512

Delete everything when you are done. The instances also shut themselves down after two and a half hours.

benchmark/aws/teardown.sh

Release status and license

Limits gives the release status of Dex and its license.

Next

  • Limits: capacity, requests that can repeat, release status, and the license.