Keep the useful bits, human.
Beginner field notes
- Back-pressure lets the receiver’s readiness influence how much more a producer sends. The producer has to honor that feedback for it to slow the flow.
- A buffer can hold a temporary burst. If arrivals keep exceeding processing capacity, a finite buffer eventually fills; making it larger does not make the worker faster.
- Pausing new work does not finish work already accepted. In this lesson, J1 can keep running while the producer holds J4 upstream.
See a worked example
Pause new admission without inventing completion or an infinite buffer
Sample only. Nothing here runs on your computer.
OFFLINE Lantern Archive protocol, not Node or Reactive Streams API calls.
Source initially retains distinct jobs [J1, J2, J3, J4]. Receiver starts waiting=[], in-service=none, completed=[].
Capacity: at most 2 waiting plus 1 in service. Three initial completion permits. Each receiver acceptance consumes 1; each stated completion returns 1. No permit is returned merely on a start.
The producer must have a permit before sending; the receiver independently enforces its local capacity. Each listed send and acceptance are one completed paper event; no concurrent or in-flight sends are modeled. With 0 permits it holds its next job without transmitting, dropping or retrying it.
Automatic dispatch in this version: an accepted job starts immediately if idle; a completion immediately starts the oldest waiting job, if any. No other events or hidden jobs occur.
1. Producer sends J1 using a permit; receiver accepts it.
2. Producer sends J2 using a permit; receiver accepts it.
3. Producer sends J3 using a permit; receiver accepts it.
4. Producer checks whether it may send J4.
5. Worker completes J1.
6. Producer sends J4 using the returned permit; receiver accepts it.
Track permits, transmissions, waiting, service, accepted history, completed and upstream-held jobs.1. J1 in service; waiting []; permits 2; source [J2, J3, J4]; completed [].
2. J1 in service; waiting [J2]; permits 1; source [J3, J4]; completed [].
3. J1 in service; waiting [J2, J3]; permits 0; source [J4]; completed [].
4. J4 is held upstream; no transmission. Receiver and permits stay unchanged.
5. J1 completes; J2 immediately starts; waiting [J3]; permits 1; source [J4]; completed [J1].
6. J4 accepted into waiting [J3, J4]; J2 in service; permits 0; source []; completed [J1].
Transmissions 4; accepted history [J1, J2, J3, J4]; completed only [J1]. Peak waiting 2; peak accepted unfinished 3. The trace does not establish later completion of J2, J3 or J4.The return of a completion permit permits another admission; it does not complete that newly accepted job. Accepted history is not another ownership bucket to add to waiting/service/completed. The source-retention rule is finite and explicit. A real API’s demand or false return must be interpreted under that API’s contract, not substituted for these toy permits.
Visual
The reviewed description and complete diagram source are available here.
More of this diagram is available inside its frame. Focus the frame and use the arrow keys to pan.
Read the complete diagram source
This is the source for the reviewed diagram, not a command to run.
flowchart TD
P["Producer retains unsent job"] --> G{"Permit and receiver space?"}
G -->|"No"| H["Hold upstream; no transmission"]
G -->|"Yes"| A["Accept once; consume one permit"]
A --> W["Start if idle, otherwise wait in FIFO"]
W --> C["Explicit completion returns one permit"]
C --> G Sources and full explanation
Notes sources · Beginner
AI source review · 2026-10-17
Reviewed explanation
Back-pressure is feedback from downstream that changes how quickly upstream supplies more work. A slow consumer can signal that it is not ready for another item, and a cooperating producer can pause or reduce sending. The control concerns further admission or delivery; it does not manufacture service capacity. A larger queue can absorb a burst, but a producer that remains faster than its consumer will eventually exhaust a finite buffer unless some other policy or rate changes.
Our Lantern Archive protocol makes the feedback concrete. It has two waiting slots, one in-service slot and three initial permits for accepted but unfinished jobs. Acceptance consumes a permit. Only a stated completion returns one. The producer sends only with a permit; the receiver separately admits work only within its local capacity. Each listed send and its acceptance form one completed paper event, with no concurrent or in-flight sends. This version immediately starts an accepted job if the worker is idle, and completion immediately dispatches the next FIFO waiting job. Those automatic-dispatch rules intentionally differ from the foundation’s manual-take trace.
When J1 is in service and J2,J3 fill the waiting slots, no permit remains. The producer keeps the finite J4 upstream and sends nothing in that step. That is neither a failed transmission nor an automatic retry. The worker can continue processing while the producer is paused. Completing J1 frees one permit and starts J2; the producer can then send J4 into the now-available waiting slot. Four jobs have been accepted by the end, but only J1 is stated complete.
Real mechanisms expose different signals. In the normal buffering path documented for Node Writable.write, the return value is computed after admitting the current chunk; false asks the writer to stop additional writes until drain. It is not a full-queue refusal of that chunk or proof of business completion. Reactive Streams Subscription.request signals demand for elements, not completion of business jobs, and a stream can end before supplying all requested elements. Our completion-returned permits are an explicit application policy, not either API’s literal rules.
Flow control has boundaries. A consumer-side queue limit does not automatically cap buffers in every upstream stage, a transport, or the original source. If that source cannot slow down, work may accumulate elsewhere unless the system has an explicit bounded storage, rejection, loss or other admission policy. Node’s highWaterMark is specifically a buffering threshold, not a strict general memory limit. The example’s source contains only four known jobs, not an unlimited live feed or a durable storage promise.
Back-pressure also does not make a failed operation succeed, deduplicate a message or define a delivery guarantee. Retries and other failure-handling protocols remain separate choices. Our finite trace supplies successful J1 completion and has no message loss, duplication, cancellation or additional arrivals. Real asynchronous feedback can take time to arrive, and protocols must define what their signals permit. Stop reasoning at the given final state rather than inventing later success or universal messaging quality-of-service.
- Reactive Streams: problem and scope
Explains asynchronous back pressure as regulating exchange so a fast source does not force arbitrary receiving-side buffering. It does not supply this example’s completion-based permits or a whole-pipeline memory guarantee.
- Reactive Streams 1.0.4 API: Subscription.request
Documents signaling demand for elements and that a publisher can send fewer if a stream ends. Data demand is not a business-task completion acknowledgement or a bound on every upstream buffer. The example’s completion permits are a different, expressly stated application rule.
- Node.js stream documentation: buffering and writable.write
In the documented normal buffering path, write return values are determined after admitting the chunk; false asks the writer to pause additional writes until drain. highWaterMark is a threshold, not a strict general memory limit. No default sizes or API operations are reproduced in the exercise.
AI source comparison recorded 2026-10-17. Human learner validation is pending.
Quick quiz · one question
Hold work until the receiver returns capacity
Sample scenario. Finite J1–J4 at source; waiting 2 plus one service slot; automatic FIFO dispatch; 3 initial permits for accepted-but-not-completed work. This explicit toy rule is not literal Reactive Streams request(n). Zero-permit consideration does not transmit/retry/drop the item. Permits are sender feedback, not a remote queue-inspection API. Every modeled send and receiver decision is one completed listed step; no concurrent or in-flight sends are hidden.
- Finite initial source
J1, J2, J3, J4 retained upstream; initially no receiver-owned or completed job. No duplicates, hidden arrivals, concurrent sends, background work or guaranteed later completion.- Receiver capacity and dispatch
2 waiting slots, separate from one in-service slot. FIFO. Start immediately if idle; a completion starts the next waiting job. A full receiver accepts nothing and the source retains the item.- Producer feedback
3 completion permits initially. Acceptance consumes one; only an explicit completion returns one. At zero, retain the next item without transmission, retry or drop. Sender credit is not a remote queue-inspection API. This is a fictional application rule, not literal Reactive Streams demand or Node write behavior, nor a whole-pipeline memory bound.- Step 1
Producer considers offering J1, subject to its stated permit rule and the receiver’s independent admission rule.- Step 2
Producer considers offering J2, subject to its stated permit rule and the receiver’s independent admission rule.- Step 3
Producer considers offering J3, subject to its stated permit rule and the receiver’s independent admission rule.- Step 4
Producer considers offering J4, subject to its stated permit rule and the receiver’s independent admission rule.- Step 5
Given completed work: J1. No other completion is inferred.- Step 6
Producer considers offering J4, subject to its stated permit rule and the receiver’s independent admission rule.
Follow completion-based permits. What happens when J4 is first considered at zero permits, and what changes after J1 explicitly completes?
Why this answer?
Answers stay on this device.
Sources and exercise scope
- Reactive Streams: problem and scope
Explains asynchronous back pressure as regulating exchange so a fast source does not force arbitrary receiving-side buffering. It does not supply this example’s completion-based permits or a whole-pipeline memory guarantee.
- Reactive Streams 1.0.4 API: Subscription.request
Documents signaling demand for elements and that a publisher can send fewer if a stream ends. Data demand is not a business-task completion acknowledgement or a bound on every upstream buffer. The example’s completion permits are a different, expressly stated application rule.
- Node.js stream documentation: buffering and writable.write
In the documented normal buffering path, write return values are determined after admitting the chunk; false asks the writer to pause additional writes until drain. highWaterMark is a threshold, not a strict general memory limit. No default sizes or API operations are reproduced in the exercise.
Original synthetic exercise. AI comparison against the reviewed lesson recorded on 2026-10-17; the references above state their scope. Human learner validation has not been run. A result here records this attempt; it does not establish mastery.
Save or adjust this lesson
Make this lesson yours
Save it for later, or tell your robot what would help.
This correction stays on this browser. Browse all concepts if the topic is missing.
Familiarity is your own assessment. To use it in your coding tool, download your updated learning profile.
Choices are saved on this browser. They do not sync to your account or coding tool.