◇ Deep Dive · The Symmetra Engine

Your API, running on a
Turing machine, on a GPU

Symmetra takes ordinary TypeScript and runs it on your graphics card — not as a metaphor, but literally, by turning every request into a tiny computer on a tape. This is the story of how that works, explained from scratch, and what we measured when we pushed 7 publicly-known, published Turing machines to their limits.

17Turing-machine engines
199Bsteps / second (peak)
600Krequests / second
0errors, ever
Start here

What is this, and why should you care?

Every website you use runs on a server. That server is almost always a CPU — a general-purpose processor running Node.js, Python, or Go. It handles a few thousand things at once, and when you need more, you add more servers.

Symmetra asks a stranger question: what if the server were a GPU? A modern graphics card has thousands of tiny processors designed to do the same simple thing thousands of times in parallel. That's terrible for running a spreadsheet — but it might be extraordinary for running an API that's doing the same small computation for thousands of users at once.

The catch: a GPU can't run JavaScript. It doesn't understand functions, objects, or web requests. It understands one thing — massively parallel arithmetic. So Symmetra compiles your TypeScript down to the most fundamental model of computation that exists: the Turing machine. And then it runs thousands of them at once on the GPU.

Write a normal API handler in TypeScript. Symmetra turns it into a Turing machine and runs it on the GPU. This article explains every word of that sentence — then shows you the numbers.
First principles

What is a Turing machine?

In 1936, before computers existed, a mathematician named Alan Turing imagined the simplest possible machine that could compute anything computable. It has just three parts:

That's it. A tape, a head, and a rulebook that says "if you're in state X reading symbol Y, then write Z, move this way, and switch to state W." Astonishingly, this is enough to compute anything a modern computer can. Every program you've ever run is, at its core, a Turing machine.

A Turing machine in motionThe actual Wolfram (2,3) machine Symmetra ships — watch the head read, write, and move across the tape
State: A  ·  head at cell 0  ·  step 0

This is Alex Smith's 2007 Wolfram Prize-winning (2,3) UTM — 2 states, 3 symbols, proven Turing-complete. It's the exact transition table running in tc-wolfram23-nano's /run handler on the live GPU engine, not a simplification.

The surprising part

The smallest possible universal computer

Here's where it gets beautiful. A Turing machine can be Turing-complete — able to simulate any computer — with almost nothing in its rulebook. In 2007, Alex Smith proved that Stephen Wolfram's (2,3) machine — just 2 states and 3 symbols, 6 transition rules total — is universal. It won the $25,000 Wolfram 2,3 Turing Machine Research Prize, and it's the smallest known universal Turing machine by states × symbols.

The entire rulebook fits in six lines. Run it long enough on the right input and it can compute anything a modern computer can — including the API handler that just answered your request.

Wolfram (2,3), computing liveThe same 6-rule machine from the demo above, run continuously and fast — this is the actual GPU workload.
Each row is one full pass of the machine's tape after another step → 2 states × 3 symbols → 6 rules, no more.

Those diagonal bands aren't decoration — they're the head sweeping back and forth, writing and rewriting the tape as it works through its 6-rule program. It is, provably, a computer. And the whole rulebook fits in a lookup table you could write on a napkin.

This is the key idea behind Symmetra: if something as small as a 2-state, 3-symbol machine is a universal computer, then a GPU — which can run millions of copies of it in parallel — is a universal computer you can point a web request at.
The engine

How Symmetra runs your API

You write a normal handler. It looks exactly like Express or Node:

import { Router, serve } from '@symmetra/http'

const app = new Router()

app.get('/api/cart-total', ctx => {
  // ordinary business logic — runs on the GPU
  let total = 0
  for (let i = 0; i < items; i++) total = total + price[i]
  ctx.json({ total })
})

serve(app, { port: 8080 })

When you run sym server.ts, Symmetra does something no other runtime does. It reads your handler, and instead of executing it on a CPU, it compiles it into CUDA — the GPU's native language — as a Turing-machine program. That compiled program becomes a persistent kernel: a piece of code that lives on the GPU forever, waking up to run your handler every time a request arrives.

The pipeline

TypeScriptyour handler esbuildstrip types CodegenAST → CUDA C++ NVRTCcompile to GPU Persistent GPU kernelruns every request as a Turing machine
Your TypeScript becomes real GPU machine code. The last box is the Turing machine — it stays resident on the GPU and executes your handler thousands of times in parallel.

So when a thousand users hit /api/cart-total at once, the GPU runs a thousand copies of your handler simultaneously — each as its own little Turing machine on its own strip of tape. That's the whole idea.

The real code

The actual handler code behind these numbers

Every benchmark on this page came from a real Symmetra server file — not a simulation. Below is the unedited /health and /run handler pair from tc-wolfram23-nano, the flagship engine implementing Alex Smith's 2007 Wolfram (2,3) Universal Turing Machine (the simplest known universal Turing machine, by states × symbols). This exact code compiles to CUDA and runs on the GPU — nothing here is Node.js.

The transition table (the actual algorithm)

// State A: sym=0 → write 1, move R, go B
//          sym=1 → write 2, move L, go A
//          sym=2 → write 1, move L, go A
// State B: sym=0 → write 2, move R, go A
//          sym=1 → write 2, move R, go B
//          sym=2 → write 0, move L, go A

/health — trivial route, still a GPU Turing machine

app.get('/health', ctx => {
  ctx.json({ status: 'ok', engine: 'tc-wolfram23-nano', tc: 'WolframSmith2007', states: 2, symbols: 3, runtime: 'symmetra-gpu' })
})

/run — 512 machines, 16-cell tape, up to 32 steps each

app.get('/run', ctx => {
  let totalSteps = 0
  for (let id = 0; id < 512; id++) {
    const tape: number[] = []
    for (let j = 0; j < 16; j++) tape.push(0)
    tape[8] = 1
    let state = 0
    let pos = 8
    let steps = 0
    while (steps < 32 && state !== -1) {
      if (pos < 0 || pos >= 16) { state = -1; break }
      const s = tape[pos]
      if (state === 0) {
        if (s === 0) { tape[pos] = 1; pos = pos + 1; state = 1 }
        else if (s === 1) { tape[pos] = 2; pos = pos - 1; state = 0 }
        else { tape[pos] = 1; pos = pos - 1; state = 0 }
      } else if (state === 1) {
        if (s === 0) { tape[pos] = 2; pos = pos + 1; state = 0 }
        else if (s === 1) { tape[pos] = 2; pos = pos + 1; state = 1 }
        else { tape[pos] = 0; pos = pos - 1; state = 0 }
      }
      steps = steps + 1
    }
    totalSteps = totalSteps + steps
  }
  ctx.json({ engine: 'tc-wolfram23-nano', tc: 'WolframSmith2007', machines: 512, tape: 16, maxSteps: 32, totalSteps })
})

serve(app, { port: 8282 })

The other 6 engines on this page (Rule 110, the 3-state universal machine, the 2-tag system, the cyclotron tag system, Rule 60, and the 1-state halting machine) follow the identical shape: a /health route and a /run route, differing only in the transition rule and tape size — that uniform shape is what makes engines interchangeable. See the @symmetra/http reference for the full Router/serve API these handlers use.

The substrate

7 flavors of Turing machine — all public knowledge

Here's a subtle point: there isn't just one kind of Turing machine. There are infinitely many, and different ones have different characters — some are provably universal computers, some are famous cellular automata, some are landmark results in computability theory. Symmetra ships a whole family of them as interchangeable engines. Your same API can run on any of them.

The 7 below are every one a genuinely published, citable result — not a Symmetra-original construction. We benchmarked all of them on identical endpoints. Here's what each one actually is:

Want the full write-up for each one — its correctness proof, endpoint-by-endpoint RPS and steps/sec, and how it compares to the others? Read the full benchmark report for every engine →

Under the hood

The benchmark architecture

To measure these engines honestly, we separated the thing under test from the thing generating load. Three machines, one request path.

CLIENT · LOAD GEN 16-core VM runs wrk fires requests (never the bottleneck) 10 GbE ~0.2 ms SERVER UNDER TEST GPU server · 32 vCPU CPU sym runtime 1. CPU: recv + parse HTTP 2. CPU: copy to pinned memory 3. GPU: run as Turing machine PCIe THE GPU NVIDIA L4 58 SMs · 24 GB · 72 W executes every handler as a Turing machine
The request always flows CPU-first: the server's CPU receives the network bytes, parses the HTTP, and copies the request into GPU-readable memory before the GPU ever touches it. Remember this — it's the crux of what we found.

How much of the GPU did we actually use?

We deployed a grid of 4,096 GPU threads — but the L4 can run 89,088 at once. That's just 4.6% of the chip. And a light request only wakes about 4 of those 4,096 threads.

Each square = one of the L4's 58 SMs · green = the 32 we used
4,096 of 89,088 threads deployed = 4.6% of the GPU. We never came close to filling it. The GPU had enormous room to spare.
The numbers

Two metrics, one honest picture

Every benchmark answered two different questions:

The relationship between them is the single most important thing to understand:

A lighter handler serves more requests but each does little work. A heavier handler serves fewer requests but each does far more. So a lower RPS often means a higher steps/sec — the GPU working harder, not slower.

Here are the top engines by raw GPU throughput on the heavy endpoint:

EngineWhat it isSteps / secHeavy RPS

On the trivial /health endpoint every engine served ~600,000 requests/second — identical, because the Turing machine does nothing and the CPU is the only thing working. They only diverge when there's real computation to do.

What we learned

The conclusion — and an honest limitation

Symmetra works. You can write a normal TypeScript API, and it will run — really run — as thousands of Turing machines on a GPU, serving hundreds of thousands of requests per second with zero errors. The GPU can sustain up to 199 billion Turing-machine steps every second. That is a genuinely new kind of web server.

But our research surfaced one honest, important limitation, and we want to be straight about it.

Right now, the CPU is still doing essential work on every single request. We audited the code to be certain, and here is exactly what happens: when a request arrives, the server's CPU must first receive the raw network bytes, parse the HTTP, and copy the request into a special pinned-memory slot that the GPU can read over the PCIe bus. Only then does the GPU wake up and run your handler as a Turing machine. The CPU is the courier that carries every request from the network to the GPU's door.

This is why, in our tests, we had to add more CPU cores to the GPU server to get more requests per second — and yes, that is a little disappointing. It means that for lightweight endpoints, the GPU is not the bottleneck at all. It sits mostly idle, drawing near-idle power, while the CPU works flat-out shuttling network data to it. On an 8-core server we hit 207,000 requests/second; doubling to 32 cores pushed it to 483,000 — the GPU never changed, only the CPU's ability to feed it.

In plain terms: today, the CPU is a toll booth between the network and the GPU. Light requests spend all their time in the toll booth; the GPU's real power only shows when each request carries heavy computation.

The good news is twofold. First, where it matters, it already wins: when each request does real work — analytics, scoring, simulation, anything compute-heavy — the GPU takes over and delivers throughput a CPU runtime simply cannot match. Second, this limitation has a known fix. Technologies like GPUDirect and kernel-bypass networking can let the network card write directly into GPU memory, removing the CPU from the hot path entirely. That is the road ahead for Symmetra.

So: a GPU that runs your API as a Turing machine is real, it's fast, and it's honest about where it stands today. For heavy compute, it's already a breakthrough. For everything else, the CPU-to-GPU handoff is the next wall to break — and we know how.