Performance

Fast Enough to Feel Instant: Search Algorithms Inside One Browser Tab

No backend, no worker thread — the whole adversarial search runs between two frames on the user's device. Here's what keeps it under the frame budget.

 ·  7 min read  ·  all numbers from re-runnable headless benchmarks

By the Numbers

~0.3
ms/move (tic-tac-toe)
93%
nodes cut by α-β
0.5
ms/move (2048)
0.006
ms per Lines query

The Frame Budget

There is no server in this picture. When the tic-tac-toe opponent picks a move, or the 2048 solver evaluates a tile placement, or Color Lines finds a path, the entire search runs on the main thread, in the same tab as the UI, between two paints. Miss that budget and the game stutters — there is no loading spinner to hide behind, because there was never a request to wait on.

That constraint is what makes the algorithm choice load-bearing. A search that is asymptotically correct but slow is not a shippable feature here — it is a dropped frame. So the interesting engineering question was never "does the AI play well," it was "does it still play well once it has to finish inside a fraction of a frame."

What Alpha-Beta Buys

Tic-tac-toe's search tree is small enough to brute-force, which makes it a clean place to measure what pruning actually does. Alpha-beta pruning skips branches that provably cannot change the outcome, without changing the result — same optimal move, far fewer positions visited. Full write-up of the algorithm is in how the minimax AI works; here's what it measures out to.

Nodes explored, plain minimax vs. alpha-beta (full depth 9)

549,945 plain 36,528 α-β Opening move 7,331 plain 1,682 α-β Mid-game position

Each pair is scaled to its own position so both bars stay readable — the opening move and the mid-game position have very different tree sizes. At the opening, alpha-beta cuts 549,945 nodes down to 36,528: a 93% reduction, for the identical optimal move.

Completed 3x3 tic-tac-toe board against the full-depth alpha-beta engine, every line blocked, ending in a draw
The engine behind those node counts, in a finished game — full-depth alpha-beta on 3×3, forced to a draw. The pruning charted above is what lets it search the whole tree this fast, one frame per move.

Adaptive Depth and Candidate Pruning

Alpha-beta pruning alone doesn't survive a bigger board. Tic-tac-toe's 3×3 grid keeps the full-depth tree small enough to search exhaustively every move; a larger board's branching factor grows fast enough that the same brute-force search would blow straight through the frame budget. The shipped code handles this two ways, both visible in the source rather than benchmarked here.

First, the search depth is capped and adapts to board size rather than staying fixed at "search everything." Second, instead of evaluating every empty cell as a candidate move, the search narrows to cells near existing pieces — the squares that can plausibly matter to the next few moves — rather than scoring the entire empty board on every ply. Neither trick is free: both trade a small amount of theoretical optimality for a bounded amount of work per move, which is the correct trade when the alternative is a dropped frame.

The result is qualitative, not a benchmark number: the tree stops exploding because the search stops trying to look at all of it. We don't have a re-runnable measurement for the larger boards to put a figure on, so none is printed here — the 3×3, full-depth numbers above are the ones we can actually stand behind.

Instant by Design

The same pattern holds across the other two search algorithms on the site. The 2048 solver's expectimax search averages 0.5 ms per move. Color Lines' BFS pathfinding answers a hint query in 0.006 ms. Both numbers come from the same class of headless self-play benchmark as the tic-tac-toe figures above — measured against the shipped code, not a lab version of it.

None of this runs on a server, because none of it is deployed as one — the site is static, vanilla JS with zero dependencies, served at Cloudflare's edge. There's no round trip to shave because there was never a round trip; the only latency budget that matters is the one inside a single browser tab. That's the same discipline behind the rest of this build — see 26 Repos in 29 Days for the wider retrospective on shipping it.

Feel the Frame Budget Yourself

Play a game against the search that's doing all this work in the background — no lag, no spinner, no server round trip.

Play Tic-Tac-Toe → Play Color Lines →