Course contentsShow
← Node.js
Lesson 481 of 1,9805. Streams and BackpressureFree lesson

Custom Stream Scheduling

Implement a custom scheduler to prioritize certain stream pipelines over others based on business logic.

In this lesson, you will learn how to implement a custom scheduler to prioritize specific stream pipelines over others based on your business logic.

The Problem: Stream Contention

By default, Node.js streams process data as fast as the internal event loop and buffer limits allow. When multiple streams share the same system resources, a low-priority background task (like generating a report) might starve a high-priority task (like processing a real-time payment). To manage this, we can implement a custom scheduler that acts as a "traffic controller" for our streams.

Implementing a Priority Scheduler

Instead of piping streams directly, we pass them through a scheduler that monitors their state and uses pause() and resume() to enforce priority rules.

Think of this like a busy intersection: the scheduler checks the "importance" of each pipeline and only allows the most critical ones to flow.

class StreamScheduler {
  constructor() {
    this.pipelines = [];
  }

  register(stream, priority) {
    this.pipelines.push({ stream, priority });
    this.pipelines.sort((a, b) => b.priority - a.priority);
  }

  run() {
    // Logic: Only resume the highest priority stream
    // that is currently waiting for data.
    const topPriority = this.pipelines[0];
    topPriority.stream.resume();
    
    // Pause lower priority pipelines if resources are tight
    this.pipelines.slice(1).forEach(p => p.stream.pause());
  }
}

Why Use This?

This approach gives you granular control over resource allocation. For example, in an e-commerce backend, you might assign Priority 10 to user checkout streams and Priority 1 to analytics logging. When the CPU or memory hits a threshold, your scheduler can automatically freeze the analytics stream to ensure the checkout process receives 100% of the available I/O bandwidth.

By manually calling .pause() and .resume() inside your scheduler based on external variables (like queue length or request headers), you ensure that your business-critical pipelines always move first, regardless of the order in which they were initialized.

Key Takeaway: Use a central scheduler to govern your pipelines via pause() and resume() to ensure business-critical data flows before background tasks during periods of high resource contention.