Zum Hauptinhalt springen
Echtzeit-Radar & Feeds
Alle RSS Feeds ➔
👥 Community & Social
Windows Tipps & SecurityGrafikkarte vor Überhitzung schützen: So geht’s(25.09.2026 um 08:00 Uhr)
••••••••••
Windows Tipps & SecurityGrafikkarte vor Überhitzung schützen: So geht’s(25.09.2026 um 08:00 Uhr)
••••••••••
Intelligence View
⚡ tsecurity.de Intelligence

Your AI Is Still Billing After the User Closed the Tab

That’s not a bug. It’s a missing owner. The user closed the browser 30 seconds ago. Your logs show the response was never delivered. But the LLM stream is still running. The vector search is still scanning. The rerankers are still sco…

0
↗ Quelle (dev.to)
Reagiere als Erste:r — dein Feedback zählt!

That’s not a bug. It’s a missing owner.



The user closed the browser 30 seconds ago.



Your logs show the response was never delivered. But the LLM stream is still running. The vector search is still scanning. The rerankers are still scoring. The tool calls are still executing.



The invoice will arrive tomorrow.



This is not hypothetical. It is the default behavior of many AI backends today.




app.post("/chat", async (req, res) => {
const stream = await openai.chat.completions.create({
model: "gpt-4.1",
stream: true,
messages: req.body.messages,
});

for await (const chunk of stream) {
res.write(chunk.choices[0]?.delta?.content ?? "");
}

res.end();
});






This code looks completely reasonable.



It even works — until the user refreshes the page, closes the tab, loses signal, or navigates away.



At that moment:




  • the HTTP response is dead

  • the client no longer exists

  • the user no longer cares



But the async work often continues anyway.



The LLM may keep generating tokens. The vector search may keep scanning. Background tasks may continue running with no remaining consumer.



The work outlived the reason it existed.



That sentence is the real problem.









The real root cause: ownership is missing



Most async systems treat cancellation as an optional convention rather than a runtime guarantee.



You can pass an AbortController if you remember.



You can manually wire cleanup if every developer remembers.



You can hope every dependency correctly propagates cancellation.



But structurally, there is usually no single owner for the tree of async work created by a request.



A single AI request may spawn:




  • LLM streaming

  • vector search

  • rerankers

  • tool execution

  • background audit writes

  • metrics

  • cleanup handlers

  • retries

  • observability traces



Every one of these should stop when the user disconnects.



But native Promises do not provide ownership semantics.



So the work survives.









The hidden cost of abandoned AI work



At small scale this is invisible.



At production scale this becomes expensive.



Imagine:




100,000 abandoned requests/day
× 3–5 seconds of unnecessary downstream execution
= millions of wasted tokens
= unnecessary GPU time
= avoidable API spend
= infrastructure pressure






This is not just a code-quality issue.



This is infrastructure waste.









The fix: one scope owns the work



Instead of manually wiring cancellation across unrelated async operations, WorkIt introduces one ownership boundary: the scope.




import { WorkIt } from "@workit/core";

await WorkIt.run(async (scope) => {
// User disconnects → cancel everything
req.on("close", () => {
scope.cancel("client_disconnected");
});

// Each operation belongs to the scope
const llm = scope.spawn("llm-stream", async (signal) =>
streamLLM({
messages,
signal,
})
);

const tools = scope.spawn("tools", async (signal) =>
runTools({
input,
signal,
})
);

const vector = scope.spawn("vector-search", async (signal) =>
searchVectorDB({
query,
signal,
})
);

// Wait for all child work
return await scope.all([llm, tools, vector]);
});






Now the request owns the work.



When the client disconnects:





  1. scope.cancel("client_disconnected") fires

  2. every child operation receives cancellation

  3. streaming stops

  4. tool execution stops

  5. vector search stops

  6. cleanup handlers run

  7. the scope settles deterministically



No orphaned work.



No zombie tasks.



No invisible token burn.









This is not theory



We validated this behavior in the WorkIt test suite.



Scenario:




{
"case": "AI streaming disconnect",
"result": "LLM/tool/vector work stopped after cancellation",
"post_cancel_work_ms": 0,
"late_events": 0
}






The important part:




"late_events": 0






After cancellation, no additional downstream work completed.



The evidence is what did not continue running.









Why this matters



The AI ecosystem is rapidly moving toward:




  • streaming

  • agents

  • tool execution

  • multi-provider inference

  • background workflows

  • long-lived realtime sessions



All of these create trees of async work.



And most of them still lack clear ownership semantics.



The result is:




  • abandoned compute

  • leaking streams

  • runaway retries

  • zombie tool execution

  • incomplete shutdowns

  • hidden infrastructure cost



WorkIt treats async work as something that must have an owner.



When the owner disappears, the work disappears with it.









The deeper idea



This is not really about cancellation.



It is about lifecycle ownership.



The request should own the work it creates.



The WebSocket should own its subscriptions.



The agent should own its tools.



The stream should own its producers.



Without ownership, async systems slowly leak compute and complexity.









Try it






npm install @workit/core









import { WorkIt } from "@workit/core";

await WorkIt.run(async (scope) => {
req.on("close", () => {
scope.cancel("user_gone");
});

const result = await scope.spawn(
"my-ai-call",
async (signal) => {
return openai.chat.completions.create({
model: "gpt-4.1",
stream: true,
messages,
signal,
});
}
);
});












The larger problem



Every senior engineer has seen some version of this question in production:




“Why is this still running?”




That question appears in:




  • AI streaming

  • WebSockets

  • Kafka consumers

  • background workers

  • multiplayer game loops

  • Discord bots

  • server-side rendering

  • agent runtimes



The problem is the same every time:



The work outlived the reason it existed.



WorkIt is an attempt to fix that at the runtime level.






GitHub:

https://github.com/WorkRuntime/workit



Article series:

https://dev.to/admilsoncossa/owned-async-work-in-typescript-ogp

1. Sofort-Triage & Abwehrmaßnahmen

SOC Incident Playbook: Vulnerability Remediation & Verification
Syntax validiert (0 Fehler)
title: Detect Exploitation - Your AI Is Still Billing After the User Closed the Tab
id: 5c24f3a6-c652-474a-ab28-9d369b458cde
status: experimental
description: Automatisch generierte SIEM-Erkennungsregel basierend auf CTI Intelligence
references:
  - https://tsecurity.de/
author: iShareStuff CTI Automated Detection Engine
date: 2026-09-27
logsource:
  category: network_connection
  product: any
detection:
  selection:
      DestinationHostname:
        - 'dev.to'
  condition: selection
falsepositives:
  - Legitime administrative Zugriffe oder Penetrationstests
level: high
tags:
  - attack.initial_access
Syntax validiert (0 Fehler)
rule CTI_Threat_Indicator {
    meta:
        author = "iShareStuff CTI Automated Detection Engine"
        date = "2026-09-27"
        description = "YARA Signature for "
    strings:
        $str = "Your AI Is Still Billing After" ascii wide
    condition:
        any of them
}
Syntax validiert (0 Fehler)
index=security sourcetype IN ("cisco:asa", "pan:traffic", "zeek_conn", "suricata", "WinEventLog:Security")
(dest_host="dev.to")
| stats count earliest(_time) as first_seen latest(_time) as last_seen by src_ip, dest_ip, dest_host, signature
| eval first_seen=strftime(first_seen, "%Y-%m-%d %H:%M:%S"), last_seen=strftime(last_seen, "%Y-%m-%d %H:%M:%S")
| sort - count
Syntax validiert (0 Fehler)
destination.domain: ("dev.to") and event.category: "network"
Syntax validiert (0 Fehler)
CommonSecurityLog
| where DestinationHostName in ("dev.to")
| summarize EventCount = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by SourceIP, DestinationIP, DestinationPort, Activity
| extend DetectionRule = "iShareStuff-CTI-Compiled"
| sort by EventCount desc

2. Cyber Threat Intelligence & Forensik

IoC Intelligence (1 Indikatoren)
dev[.]to
CTI Threat Relationship Graph4 Knoten / 3 Relationen
CVE / Incident Software MITRE ATT&CK CWE Weakness IoC
🎯
MITRE ATT&CK Matrix Navigator 14 Taktiken
Reconnaissance
-
Resource Development
-
Initial Access
Execution
Persistence
-
Privilege Escalation
Defense Evasion
Credential Access
-
Discovery
-
Lateral Movement
-
Collection
-
Command and Control
Exfiltration
-
Impact
tsecurity.de Cognitive Threat RAG
Fokus-Vektor:

Analyse für identifizierte Bedrohung auf Basis von Live-CTI (ENISA EUVD): CVSS 0.0 · EPSS 0.0% · CISA KEV: nein. Handlungsableitung aus den verlinkten Hersteller-Quellen.

🛡️ Angriffsfläche & Exposure

Netzwerk/Remote-Zugriff ohne Vorauthentifizierung möglich.

⚡ Empfohlene Sofortmaßnahmen
  • 1. Perimeter-Inspektion: Relevante Portfreigaben und exponierte Endpunkte unverzüglich scannen.
  • 2. Patch-Applikation: Hersteller-Hotfix einspielen oder betroffene Daemons in isolierte DMZ-Segmente überführen.
  • 3. Telemetrie & EDR-Alerts: Prozessaufrufe und Child-Processes auf anomale Shell-Spawns überwachen.
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Your AI Is Still Billing After the User Closed the Tab

Thematisch verwandte Begriffe: Your, Still, Billing, After · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

💬 Kommentare werden geladen…
Zum Aktualisieren ziehen
ZERO-DAY CVE-2026-100739 | A vulnerability was detected in mathurvishal CloudClassroom-PHP-Project…
Advisory →
tsecurity.de Icon
Offline-Lesen, Eilmeldungen & 0ms Ladezeit

Installiere tsecurity.de direkt auf deinen Home-Bildschirm für das ultimative Vollbild-Magazinerlebnis ohne Browser-Leisten.

Nächster Beitrag