> ## Documentation Index
> Fetch the complete documentation index at: https://docs.useshipd.com/llms.txt
> Use this file to discover all available pages before exploring further.

# SDK benchmarks

> Measured flag evaluation latency, throughput, and configuration freshness in the TypeScript and Go SDKs.

## Overview

These benchmarks show how quickly the TypeScript and Go SDKs evaluate flags locally, and how quickly configuration changes reach the TypeScript SDK. Measurements were recorded on **October 15, 2026 (UTC)** using a small production snapshot and synthetic evaluation contexts. They describe the tested workload and hardware, not a performance guarantee or latency SLO.

## Evaluation latency and throughput

Flag checks read an in-memory snapshot without a network request. The table measures public SDK calls with **evaluation events disabled**. Startup, snapshot download, parsing, and refresh are excluded.

| Boolean flag workload | SDK | p50 (µs) | p95 (µs) | p99 (µs) | Evaluations/sec |
| - | - | - | - | - | - |
| No targeting rules | TypeScript | 0.042 | 0.084 | 0.084 | 19.46M |
| No targeting rules | Go | 0.166 | 0.209 | 0.333 | 4.98M |
| Disabled flag | TypeScript | 0.042 | 0.084 | 0.084 | 20.56M |
| Disabled flag | Go | 0.166 | 0.209 | 0.333 | 5.55M |
| Attribute targeting: one rule | TypeScript | 0.083 | 0.125 | 0.125 | 12.33M |
| Attribute targeting: one rule | Go | 0.375 | 0.500 | 0.875 | 2.96M |
| Audience targeting: one rule | TypeScript | 0.083 | 0.125 | 0.125 | 12.49M |
| Audience targeting: one rule | Go | 0.167 | 0.250 | 0.375 | 4.45M |
| Audience and percentage targeting: two rules | TypeScript | 0.125 | 0.125 | 0.167 | 10.10M |
| Audience and percentage targeting: two rules | Go | 0.208 | 0.250 | 0.375 | 4.03M |

Workload labels describe the configured rules. Which rules execute depends on the evaluation context and the first matching rule; these results do not cover every targeting path or rule count.

Latency percentiles come from individually timed calls and include timer overhead. TypeScript reports the median of five trial percentiles; Go latency comes from one pass. Throughput is measured separately and reports the median of five trials. It is not calculated from p99 latency.

## Evaluation while configuration updates

A separate stress test repeatedly replaced snapshots while evaluations continued. It used the same six boolean flags as the evaluation run, including a second flag without targeting rules. Refreshes used an in-process transport to isolate replacement behavior from network latency.

| SDK | Evaluation p99 across tested flags | First call after application p99 |
| - | - | - |
| TypeScript | 0.208–0.917 µs | 2.292–7.375 µs |
| Go | 0.375–0.583 µs | Not measured separately |

Each range contains the per-flag p99 values; it is not a percentile pooled across flags. The first TypeScript call after applying a snapshot was slower than steady-state calls in this run.

JavaScript evaluation and snapshot application share one thread, so the test yielded between batches to allow updates. Go refreshed in a background goroutine. Both tests used one evaluation caller; they do not establish scaling across many concurrent callers.

## Configuration freshness

The production test changed an isolated boolean flag ten times and measured when the SDK applied the new snapshot and returned the new value.

| Synchronization path | p50 change request to application | Observed maximum | Samples |
| - | - | - | - |
| WebSocket notification followed by snapshot fetch | 906 ms | 1,722 ms | 10 |
| Polling with a configured 1-second interval | 1,429 ms | 2,014 ms | 10 |

**The default polling interval is 30 seconds.** The polling result above uses an explicitly configured **1-second interval**; it does not describe default polling freshness. The default interval was not measured in this run.

Timing includes the configuration API request, publication, notification or polling, snapshot fetch, and application. The WebSocket test disabled polling fallback. Both paths were measured through the TypeScript SDK; Go currently refreshes through polling or manual refresh.

Ten samples give an initial observation, not reliable p95 or p99 propagation estimates. See [Snapshots](/concepts/snapshots) for how updates reach your application.

## Measurement conditions and limits

* **Hardware:** Apple M5 Pro with 18 logical CPUs; Node.js 26.11.1 and Go 1.26.2.
* **Workload:** Six boolean flags with up to two rules, five compiled audiences, and 64 rotating, preallocated synthetic contexts with two attributes each. The tables show five representative flag workloads. Variant, number, and JSON flags were not measured.
* **Sampling:** TypeScript latency used 50,000 calls per flag in each of five trials. Go latency used one 50,000-call pass per flag. Throughput used five trials per SDK, with warmup before measurement. Go throughput used `GOMAXPROCS=1`; the separate latency and replacement pass used the runtime default. Neither SDK was pinned to a physical CPU.
* **Replacement test:** TypeScript measured 102,400 calls and 100 replacements per flag, with about 100 first-call-after-application samples. Go measured 50,000 calls and observed 8–16 background replacements per flag.
* **Environment:** Measurements ran on a developer machine, and propagation testing overlapped part of the evaluation run. Submicrosecond timings are sensitive to timer resolution, runtime optimization, garbage collection, and scheduling.

Use these results as a starting point when assessing shipd for your application. Larger rule sets, different evaluation contexts, event delivery, browser runtimes, and concurrent callers can change performance. Measure your own workload before setting latency budgets or capacity targets.

Related: [Local evaluation](/concepts/local-evaluation) · [Snapshots](/concepts/snapshots) · [SDK reference](/reference/sdk) · [Go SDK reference](/reference/go-sdk).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.