Skip to content

blog: the missing structured concurrency guarantees in k6's JavaScript runtime#1114

Open
taras wants to merge 27 commits intov4from
blog/k6-structured-concurrency
Open

blog: the missing structured concurrency guarantees in k6's JavaScript runtime#1114
taras wants to merge 27 commits intov4from
blog/k6-structured-concurrency

Conversation

@taras
Copy link
Member

@taras taras commented Feb 15, 2026

Summary

Add a new blog post documenting how @effectionx/k6 solves structured concurrency problems in k6.

Motivation

k6 has 20+ open issues that trace back to missing structured concurrency guarantees:

  • Context loss: group() doesn't work with async calls (#2728, #2848)
  • Resource leaks: Goroutine leaks, no per-VU lifecycle (#4241, Give docusaurus what it wants #785, #5382)
  • Silent failures: Unhandled promise rejections don't fail tests (#5249, #5524)
  • Unpredictable shutdown: 8 different stop mechanisms, none consistent (#2804, #3718)
  • Race conditions: Data races during shutdown (#4203, #5534, #3747)

This post:

  1. Documents the problem categories with real issue receipts
  2. Shows before/after code comparisons
  3. Validates the Sobek runtime fix (PR Update README and package.json with new repo name #115)
  4. Points readers to the conformance suite as evidence

Related PRs

Checklist

  • Post follows www/AGENTS.md conventions
  • Frontmatter complete (title, description, author, tags, image)
  • SVG thumbnail created with light/dark mode support
  • Code examples are technically accurate
  • Links to external issues included
  • deno fmt applied

Document how @effectionx/k6 solves 20+ open k6 issues related to
structured concurrency gaps: context loss, resource leaks, silent
failures, unpredictable shutdown, and race conditions.

References:
- Sobek PR #115: grafana/sobek#115
- Effectionx PR #156: thefrontside/effectionx#156

Session-ID: ses_39d99b9c2ffeSKxHPZAk9P7E1O
@pkg-pr-new
Copy link

pkg-pr-new bot commented Feb 15, 2026

Open in StackBlitz

npm i https://pkg.pr.new/thefrontside/effection@1114

commit: 72b1e6a

Replace generic JS hook with k6-specific group/tag drift framing and
align examples with k6 maintainer analysis in grafana/k6#2728.

Session-ID: ses_39d99b9c2ffeSKxHPZAk9P7E1O
@taras taras changed the title blog: Structured Concurrency for k6, With Receipts blog: the missing structured concurrency guarantees in k6's JavaScript runtime Feb 15, 2026
Remove absolution/blame-shift phrasing, make the two guarantees explicit,
and keep maintainer discussion to paraphrase plus a single anchored quote.

Session-ID: ses_39d99b9c2ffeSKxHPZAk9P7E1O
Restructure the post around:
1. The familiar k6 symptom (group/tag drift)
2. Why group() can't fix it (try/finally model + stack unwinding)
3. The two structured concurrency guarantees
4. Five categories of missing guarantees with issue links
5. Before/after example showing scope ownership
6. ECMAScript spec conformance and Sobek PR #115
7. What the conformance suite tests (what Sobek already has vs the one gap)
8. CTA for users and maintainers

Voice: paraphrase + one anchored quote per section, neutral attribution,
no absolution/blame-shift, explicit two guarantees.

Session-ID: ses_39d99b9c2ffeSKxHPZAk9P7E1O
Reframe opening and key transitions around 'your expectations':
- sync group() works the way you expect; async breaks that
- structured concurrency aligns async with those expectations
- scope owns async the same way it owns sync

Session-ID: ses_39d99b9c2ffeSKxHPZAk9P7E1O
Update featured image to show async deforming the call stack: a then() callback runs on the next tick with restored tags, so group attribution changes. Add a short bridge paragraph tying the diagram to k6 tag behavior.

Session-ID: ses_39d99b9c2ffeSKxHPZAk9P7E1O
Use "future tick" language consistently in the diagram and bridge paragraph.

Session-ID: ses_39d99b9c2ffeSKxHPZAk9P7E1O
Session-ID: ses_39d99b9c2ffeSKxHPZAk9P7E1O
Explain that k6 reads current tags from the sync stack, but async callbacks run
on a future tick after group() has unwound and restored tags.

Session-ID: ses_39d99bc2ffeSKxHPZAk9P7E1O
Session-ID: w0t1p0:529AE7AB-BFCA-4B51-9880-FDF1D759DFBE
Session-ID: w0t1p0:529AE7AB-BFCA-4B51-9880-FDF1D759DFBE
- Cut 45-line GitHub issue list
- Add bridge paragraph (universal async problem)
- Combine technical sections
- Tighten to ~650 words
- Replace fake delay() with http.asyncRequest()
- Use until() instead of call() for promises
- Rename section to 'Universal solution'
- Clarify guarantees match sync expectations
taras added 11 commits February 15, 2026 15:51
- Add transition paragraph before code examples
- Add 'Why Effection for k6?' section explaining polyfill design
- Include Rosetta Stone link
- Frame as easy/safe choice until JS runtime adds guarantees
- Note additive adoption without Sobek changes beyond ECMAScript
- Replace abstract 'Lifetime is structural' with concrete code comparison
- Rename Sobek section to 'Missing ECMAScript compliance'
- Add link to conformance suite gist showing 80% compatibility
- Link to ECMAScript spec for Generator.prototype.return
- Show that only async cleanup was missing
- Replace incorrect npm install instructions with Docker-based setup
- Redesign SVG to show vertical execution sequence with animated tag state
- Left side shows async/await losing tags before .then() runs
- Right side shows structured concurrency preserving tags through async
- Animation highlights when tag state changes (the key insight)
- Left-align all headings
- Update title: 'Missing Structured Concurrency Guarantees in Sobek'
- Left-align step text (remove awkward centered comments)
- Widen tag pills to fit 'group: coolgroup' text
- Add result summary labels at bottom of each card
- Fix card containers and spacing
- Remove CSS animations that caused content to be invisible on load
- Make all content static and visible by default
- Fix shadow filter bounds (use objectBoundingBox)
- Adjust card heights to prevent overlap with result labels
- Remove 'When the invariant holds, async stops lying' closing line
  (needs more thought, will revisit later)
- Fix animation by using proper keyframe timing
- Steps appear sequentially over 8-second cycle
- Left tag changes from green 'coolgroup' to red '(lost)' at step 4
- Right tag stays green 'coolgroup' through async, then '(done)'
- Result summaries appear after all steps
- Smooth loop with reset phase
- Add explicit audience callout for k6 users debugging flaky tests
- Reference k6 issues #2848, #5435, #5249, #5524 as evidence of the pattern
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant