The Pipe Platform Achieves Security and Compliance Milestone with SOC 2 Type I Attestation. Learn More

STRESS TEST // main thread

FPS --
Frame -- ms
Jank --
Frame Time (ms) — last 120 frames  |  <16ms   16–50ms   >50ms
⚡ MASTER INTENSITY
1.0× Multiplier applied to all active stressors
🔥 CPU Burn Loop
Runs a tight synchronous while loop doing heavy math (sin/cos/sqrt, string concatenation) for a set duration, then waits for an interval before firing again. Directly starves the event loop.
Burn: 50 ms/tick 1–500ms
Interval: 200 ms 10–2000ms
🌪 DOM Thrash
Each animation frame: creates N elements, reads their offsetHeight (forced reflow), mutates their styles, then removes them. The read-after-write pattern prevents the browser from batching layout work.
Elements: 100 / frame 1–5000
💾 Memory Pressure
Allocates large typed arrays on an interval. Toggle Hold refs to keep them in memory (heap growth) or release them (GC pressure). Both modes stress the runtime differently.
Alloc: 10 MB / tick 0.1–200 MB
Interval: 500 ms 50–5000ms
Hold references (heap growth instead of GC churn)
Timer Flood
Spawns N setTimeout callbacks simultaneously every tick, each doing light work (array sort, string ops). Stresses the timer queue and task scheduling overhead.
Timers: 500 / batch 1–10000
Spawn every: 500 ms 100–5000ms
Microtask Storm
Chains N resolved Promise callbacks back-to-back, flooding the microtask queue. Unlike timers, microtasks run synchronously between tasks and cannot be interrupted — a deep chain fully blocks rendering.
Chain depth: 5000 100–100000
Interval: 1000 ms 100–5000ms

How this page works & what everything does

Background Loop

A requestAnimationFrame loop runs continuously to measure frame timing. Each frame, the loop records the elapsed time since the last frame, appends it to a rolling 120-sample buffer, and redraws the frame-time graph on a <canvas> element. This loop itself is intentionally lightweight — all frame budget consumption comes from the stress modules below.

Stats Bar (top-right)

StatDescription
FPSFrames per second calculated from the last 30 frames. Drops below 60 indicate the main thread is busy. At 0 FPS the page is fully frozen.
FrameThe raw milliseconds elapsed since the previous frame. Smooth animation requires <16.67ms. Values above 50ms are red and represent severe jank.
JankThe number of frames in the last 120 that exceeded 50ms (a "long task"). Higher = worse user experience.

Frame Time Graph

The canvas graph plots the last 120 frame durations as a bar chart. Bars are color-coded: green = normal (<16ms), amber = degraded (16–50ms), red = severe jank (>50ms). A dashed line marks the 16.67ms target threshold.

Master Intensity (slider)

A global multiplier (1× – 20×) applied on top of each individual stressor's settings. At 20×, the burn duration, DOM element count, allocation size, timer count, and microtask depth are all scaled up by 20. Use this to quickly ramp all active stressors simultaneously without adjusting each card.

☢ NUKE Button

Temporarily overrides every stressor to its absolute maximum value and enables all of them for 5 seconds, then restores all previous states. Use this to instantly simulate a worst-case scenario and observe how the browser (and any monitoring tools you're testing) responds.

↺ RESET ALL Button

Disables every stressor, resets all sliders to their default values, clears the held memory buffer, and clears the frame-time graph. Returns the page to a clean baseline state.

Stress Modules

🔥 CPU Burn Loop

What it does in the background: a setInterval fires every Interval ms. When it fires, it runs a synchronous while loop for exactly Burn duration ms (measured via performance.now()), performing floating-point math (Math.sin, Math.cos, Math.sqrt) and string concatenation to prevent the JIT from optimizing it away. This is the most direct way to starve the event loop — nothing else can run during the burn.

ControlEffect
ToggleEnables / disables the burn interval.
Burn (ms/tick)How many milliseconds the synchronous burn runs per invocation. At 16ms+ you will start dropping frames. At 100ms+ the page becomes noticeably unresponsive.
Interval (ms)How often (in ms) a new burn tick fires. Lower = more frequent blocking. E.g. 50ms interval with 50ms burn = near 100% main thread saturation.

🌪 DOM Thrash

What it does in the background: inside every requestAnimationFrame callback, it creates N <div> elements in an off-screen container, then reads their offsetHeight (forcing a synchronous layout reflow), then mutates their style.width (invalidating layout again). This read-write-read pattern prevents the browser from batching style recalculations and layout. After processing all elements, they are removed. High element counts can spike frame time into the hundreds of milliseconds.

ControlEffect
ToggleEnables / disables per-frame DOM thrashing.
Elements / frameHow many DOM nodes are created, force-reflowed, mutated, and removed each animation frame. Linear relationship with frame cost — 5000 elements typically causes severe jank.

💾 Memory Pressure

What it does in the background: a setInterval allocates a Float64Array of the configured size. In hold mode the reference is pushed into a retained array, growing the JS heap until the tab is killed or the stressor is reset. In release mode the reference is immediately discarded, triggering frequent garbage collection cycles which pause JS execution (GC pauses can be 5–50ms depending on heap size).

ControlEffect
ToggleEnables / disables memory allocation.
Alloc (MB/tick)Size of the typed array allocated per tick in megabytes.
Interval (ms)How often a new allocation is made.
Hold referencesWhen ON, allocated arrays are kept alive (heap grows). When OFF, they are immediately discarded, stressing the GC instead of raw heap size.

⏱ Timer Flood

What it does in the background: every Interval ms, it schedules N setTimeout(fn, 0) calls simultaneously. Each callback sorts a small random array, does a string join, and runs a short math loop — lightweight per-task but collectively overwhelming. This exercises the browser's task scheduler and timer queue, which can cause starvation of other event listeners and I/O callbacks.

ControlEffect
ToggleEnables / disables timer spawning.
Timers / batchHow many setTimeout callbacks are scheduled per batch invocation.
Spawn every (ms)Interval between batches. Lower interval + higher count = deeper timer queue saturation.

⚡ Microtask Storm

What it does in the background: every Interval ms, it kicks off a chain of N resolved Promise.resolve().then() calls, each scheduling the next. Crucially, the microtask queue is drained completely before the browser returns to the task queue — so a chain of 100,000 microtasks blocks rendering for the entire duration of the drain, with no opportunity for the browser to paint frames or handle input. Unlike timers, you cannot "yield" out of a microtask chain once it starts.

ControlEffect
ToggleEnables / disables the microtask chain.
Chain depthNumber of chained .then() callbacks per storm. At 100,000 this will freeze rendering for multiple seconds.
Interval (ms)How often a new chain is initiated.