Advanced use cases
Five cross-cutting patterns that combine flags, configs, killswitches, experiments, metrics, alerts and feedback into one workflow — the things you can only do when it's all one platform.
Every primitive on its own is documented in its own section. This page is about the seams — the workflows that only exist because flags, configs, killswitches, experiments, metrics, alerts and feedback share one SDK, one API and one project. Each pattern below states the problem, the approach, and which primitives it wires together. Follow the links for the step-by-step version.
One killswitch, a switch inserted per tenant by your provisioning code.
Read →Config + attributesPlan entitlements, no redeployA dynamic config as the live entitlements map, targeted by plan.
Read →Gate + metric + alertA rollout that halts itselfRamp behind a guardrail that pages — and break-glass with a killswitch.
Read →Universe + holdoutA quarter's compounding impactOne holdout measures everything you shipped, not one experiment.
Read →see() → alert → agentException to opened PRA spiking error files its own ticket and an AI trigger fixes it.
Read →Roll a feature out to new tenants automatically
Problem. You're rolling a feature out tenant by tenant, but your tenant list is never static — new accounts sign up every day, and you don't want to redeploy or hand-edit a targeting rule each time one does.
Approach. Create one killswitch for the feature. A killswitch carries a map
of named switches — per-key boolean overrides
layered on top of the global state. Have your provisioning code call the Admin API to
insert a tenant:<id> switch the moment a tenant is created, then flip that one
switch to grant or revoke access — no code change, no deploy, one lever per tenant.
import { configure, Client } from "@shipeasy/sdk/server";
configure({ apiKey: process.env.SHIPEASY_SERVER_KEY! });
export async function handler(tenantId: string) {
const flags = new Client({ user_id: tenantId });
// resolves the tenant's named switch, falling back to the global state
if (flags.getKillswitch("new-checkout", `tenant:${tenantId}`)) {
return newCheckout(tenantId);
}
return legacyCheckout(tenantId);
}# your onboarding job runs this as each tenant is provisioned
shipeasy killswitch toggle new-checkout --switch tenant:acme --on --env prodCombines: killswitch switches + the Admin API driven from your own provisioning code.
Change plan entitlements without a redeploy
Problem. A customer upgrades, downgrades, or negotiates a custom limit, and you want the new entitlements — seat count, API quota, which features are unlocked — to take effect immediately, without shipping code or running a migration.
Approach. Model entitlements as a typed dynamic config
rather than a flag. Store the limits and feature set as the config's value, and
target it by a plan (or tenant) attribute. Your code reads one getConfig(); a
plan change is a config edit — or just a change to the customer's attribute — applied
through the dashboard, CLI or Admin API and live on the next poll.
const flags = new Client({ user_id, attributes: { plan: "business" } });
const limits = flags.getConfig("entitlements"); // { seats: 25, apiRpm: 600, export: true }Combines: dynamic configs (typed values + targeting) + attributes + the Admin API for programmatic upgrades.
Ramp a feature that halts itself when a guardrail regresses
Problem. You want to ramp a risky change from 1% to 100%, but not babysit a dashboard the whole time. If it drives error rate or latency the wrong way, it should stop — or at least page someone — before it reaches everyone.
Approach. Put the feature behind a gate and ramp its rollout percentage. Define the thing you're afraid of breaking as a guardrail metric, and attach a threshold alert to it — "checkout errors > 50 in the last hour". The alert is evaluated server-side by cron and files a ticket into your feedback queue the instant the guardrail breaches, while you keep the same feature's killswitch armed as the break-glass to cut it to zero without redeploying.
Combines: gate rollout + a metric + a threshold alert (auto-files a ticket) + a killswitch for break-glass.
Alert rules are evaluated by a cron on the edge — you only define the rule and the metric. Nothing to poll, nothing to wire into the hot path.
Measure what a whole quarter of shipping actually added
Problem. Every experiment you ran this quarter showed a small lift in isolation. But did they compound, or did later wins quietly cannibalise earlier ones? A stack of individual p-values can't answer that.
Approach. Run the quarter's experiments inside a single universe with a holdout. Because holdouts live on the universe — not the individual experiment — the held-out slice never sees any of the changes. Comparing the holdout against everyone else measures the cumulative impact of everything you shipped, end to end. Run the experiments as mutually-exclusive within that universe so a single user never lands in two at once and the attribution stays clean.
Combines: a universe + a universe-level holdout + mutually-exclusive experiments + your success metrics.
Turn a spiking exception into an opened PR
Problem. A handled error that used to fire twice a day starts firing twice a minute after a deploy. You want it noticed, triaged and — where possible — fixed, without a human watching log volume.
Approach. Report the error through see() instead of
a bare console.error, so it becomes a tracked error with a frequency the backend
counts. Point a threshold alert at that error's rate; when it
crosses the line the alert files a bug into the same ops queue as everything else.
From there an AI trigger — Claude, Copilot, Cursor or
Jules — picks the ticket up and opens a pull request against it. The loop from caught
exception to proposed fix runs without anyone paging themselves.
Combines: see() error reporting → tracked-error frequency → a threshold alert (files the ticket) → the ops queue → an AI trigger that opens the PR.
Where to go next
These patterns are deliberately composed from primitives you can read about individually. If one is close to what you need, start from its section links above; if you want the smaller, single-primitive recipes, the Flags & Experiments case studies are the next level down.