Skip to content

2234839/DynaPM

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

79 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

DynaPM

ไธญๆ–‡ๆ–‡ๆกฃ

Dynamic Process Manager - A lightweight, universal service management system with serverless-like features.

npm version Tests Performance

DynaPM is a lightweight alternative to complex container orchestration platforms (like Knative, Sablier) for private deployments. It helps you manage hundreds of low-frequency services on resource-constrained servers by starting them on-demand and stopping them when idle.


๐ŸŽฏ Why DynaPM?

The Problem

You have many side projects or internal tools that:

  • ๐ŸŒ Are accessed infrequently but need to be available instantly
  • ๐Ÿ’ธ Consume valuable RAM/CPU even when idle
  • ๐Ÿ˜“ Don't justify the complexity of Kubernetes/serverless platforms
  • ๐Ÿค” Are managed differently (PM2, Docker, systemd, etc.)

๐Ÿ’ก The Solution

DynaPM acts as a smart gateway that:

  1. Intercepts incoming requests to your services
  2. Automatically starts the service if offline (only 25ms overhead โšก)
  3. Stream-proxies the request (1-2ms latency ๐Ÿš€)
  4. Stops the service after a period of inactivity

๐Ÿ’ก Performance Note: 25ms is DynaPM's overhead (startup command: 8ms + port wait: 17ms). Total cold start time also includes the service's own startup time (e.g., ~475ms for Node.js apps, ~500ms total).

๐Ÿ† What Makes DynaPM Different?

Feature DynaPM Sablier traefik-lazyload Knative
Technology Node.js + uWS Go Go Go + K8s
Scope โญ Universal (any process) Docker only Docker only K8s only
Setup Complexity โญ Simple โญโญโญ Medium โญโญโญ Medium โญโญโญโญโญ Complex
Infrastructure Single server Docker/K8s Docker + Traefik K8s cluster
Cold Start โšก ~25ms overhead Container startup required Container startup required 2-4 seconds (source)
Proxy Latency ๐Ÿš€ 1-2ms Via reverse proxy Via reverse proxy Via Activator/Queue-proxy
Perfect For Personal projects/Small teams Docker environments Docker + Traefic Enterprise K8s

โœจ Key Features

โšก Blazing Fast Cold Start

๐Ÿš€ [myapp] GET / - Starting service...
[myapp] Start command executed
โœ… [myapp] Service ready (startup: 8ms, wait: 17ms)
๐Ÿ“ค [myapp] GET / - 200 - 30ms
  • DynaPM overhead: Only 25ms (startup command: 8ms + port wait: 17ms)
  • Instant retry: Zero-delay polling, forward immediately when port is ready
  • Total cold start: ~185ms (including service boot time, e.g., ~160ms for Node.js apps)

๐Ÿš€ Stream Proxying

When services are running, proxy latency is only 1-2ms:

๐Ÿ“ค [myapp] GET / - 200 - 1ms
๐Ÿ“ค [myapp] POST /api/data - 200 - 2ms

True streaming with uWebSockets.js - zero buffering, 10x+ performance vs Fastify!

๐ŸŒ SSE & WebSocket Support

DynaPM supports modern real-time protocols out of the box:

Server-Sent Events (SSE):

โœ… [sse-server] Service ready (startup: 3ms, wait: 429ms)
๐Ÿ“ค [sse-server] GET /events - 200 - 5.45s

WebSocket:

โœ… [ws-server] Backend WebSocket connected
๐Ÿ“จ [ws-server] Forward message to backend: 30 bytes
๐Ÿ”Œ [ws-server] Client WebSocket closed

Smart connection tracking prevents long connections from being shut down:

  • Active SSE/WebSocket connections increment connection counter
  • Services only stop when activeConnections === 0 AND timeout expires
  • No more premature service kills during active sessions

๐ŸŽ›๏ธ Universal Service Management

Configure ANY service using bash commands - no limits:

// PM2 services
{
  commands: {
    start: 'pm2 start app.js --name myapp',
    stop: 'pm2 stop myapp',
    check: 'pm2 status | grep myapp | grep online',
  }
}

// Docker containers
{
  commands: {
    start: 'docker run -d -p 3000:3000 myimage',
    stop: 'docker stop mycontainer',
    check: 'docker inspect -f {{.State.Running}} mycontainer',
  }
}

// systemd services
{
  commands: {
    start: 'systemctl start myservice',
    stop: 'systemctl stop myservice',
    check: 'systemctl is-active myservice',
  }
}

// Direct processes
{
  commands: {
    start: 'nohup node app.js > logs/app.log 2>&1 &',
    stop: 'lsof -ti:3000 | xargs -r kill -9',
    check: 'lsof -ti:3000 >/dev/null 2>&1',
  }
}

๐Ÿ”„ Idle Resource Reclamation

  • Services auto-stop after X minutes of inactivity
  • Configurable timeout per service
  • Frees up RAM/CPU for active services
  • Check interval: 3 seconds
  • Smart connection tracking: Active long connections (SSE/WebSocket) prevent premature shutdown

๐Ÿ“Š High Performance Metrics

Test Environment: Node.js HTTP Server (autocannon benchmark)

โœ… Cold start:       ~185ms (DynaPM: 25ms + service boot: 160ms)
โœ… Stream proxy:     Avg 10.3ms (range: 9-12ms)
โœ… Throughput:       5,942 req/s (multi-service, 150 concurrent)
โœ… Load test:        Low latency even under high concurrency
โœ… Memory overhead:  ~50MB (Node.js runtime)
โœ… Bundle size:      21.7KB (minified)
โœ… Logging:          Structured JSON logging (Pino)

๐Ÿš€ Quick Start

Installation

# Install globally
npm install -g dynapm

# Or use with pnpm
pnpm install -g dynapm

Configuration

Create a dynapm.config.ts file in your project directory:

import type { DynaPMConfig } from 'dynapm';

const config: DynaPMConfig = {
  port: 3000,
  host: '127.0.0.1',

  // Logging configuration (optional, disable for better performance in production)
  logging: {
    enableRequestLog: false,      // Enable request/response logging (high frequency, affects performance)
    enableWebSocketLog: false,    // Enable WebSocket lifecycle logging
    // Error logging is always enabled
  },

  services: {
    'app.example.com': {
      name: 'my-app',
      base: 'http://127.0.0.1:3001',
      idleTimeout: 5 * 60 * 1000, // Auto-stop after 5 minutes idle
      startTimeout: 10 * 1000,    // Startup timeout

      commands: {
        start: 'nohup node /path/to/app.js > logs/app.log 2>&1 &',
        stop: 'lsof -ti:3001 | xargs -r kill -9',
        check: 'lsof -ti:3001 >/dev/null 2>&1',
      },

      healthCheck: {
        type: 'tcp', // TCP port check (default, no service code changes needed)
      },
    },
  },
};

export default config;

Usage

# Start the DynaPM gateway
dynapm

# Or use with npx
npx dynapm

Now access your services at http://app.example.com:3000 - they'll start automatically!


๐Ÿงช Running Tests

DynaPM comes with a comprehensive automated test suite covering all core features.

Quick Test

# Clone the project
git clone https://github.com/2234839/DynaPM.git
cd DynaPM

# Install dependencies
pnpm install

# Run the full test suite
pnpm test

Test Coverage

The automated tests validate 81 test cases across 6 test suites:

  1. โœ… On-demand start - Services auto-start when offline
  2. โœ… Hot start - Direct proxy when service is running
  3. โœ… Auto-stop - Services auto-stop after timeout
  4. โœ… 404 handling - Unconfigured services return 404
  5. โœ… Multi-service - Manage multiple services concurrently
  6. โœ… Health checks - TCP and HTTP check methods
  7. โœ… Path proxying - Different paths proxy correctly
  8. โœ… Idle protection - Continuous requests update idle time
  9. โœ… POST requests - POST method support
  10. โœ… SSE streaming - Server-Sent Events proxy support
  11. โœ… WebSocket - WebSocket bidirectional communication support
  12. โœ… Long connections - Active connections prevent premature shutdown
  13. โœ… Concurrent startup - Multiple requests to offline service
  14. โœ… Security hardening - Body size limits, CRLF injection protection
  15. โœ… Port routing - Direct port-based proxy and on-demand start

Test Output Example

============================================================
Test Results Summary
============================================================
โœ“ Test 1: On-demand start (773ms)
โœ“ Test 2: Hot start (service running) (11ms)
โœ“ Test 3: Auto-stop (18025ms)
โœ“ Test 4: 404 error handling (11ms)
โœ“ Test 5: Multi-service concurrent start (843ms)
โœ“ Test 6: Different health checks (20ms)
โœ“ Test 7: Path proxying (10ms)
โœ“ Test 8: Idle time update on continuous requests (14112ms)
โœ“ Test 9: POST requests (12ms)
โœ“ Test 10: SSE streaming (3963ms)
โœ“ Test 11: WebSocket (1098ms)
โœ“ Test 12: Long connections (10110ms)

------------------------------------------------------------
Total: 12 tests
Passed: 12 โœ“
Failed: 0
๐ŸŽ‰ All tests passed!

Performance Verification

Tests output detailed performance logs:

๐Ÿš€ [app1] GET / - Starting service...
[app1] Start command executed
โœ… [app1] Service ready (startup: 8ms, wait: 17ms)
๐Ÿ“ค [app1] GET / - 200 - 30ms

# Subsequent requests (service already running)
๐Ÿ“ค [app1] GET / - 200 - 1ms
๐Ÿ“ค [app1] POST /api/data - 200 - 2ms

๐Ÿ“Š Performance Benchmarking

DynaPM includes an automated performance test script to verify system metrics.

Running Performance Tests

# Clone the project
git clone https://github.com/2234839/DynaPM.git
cd DynaPM

# Install dependencies
pnpm install

# Build the project
pnpm build

# Run performance benchmark
pnpm benchmark

Performance Test Output

๐Ÿš€ DynaPM Performance Benchmark

============================================================
Cold Start Performance
============================================================
โœ“ Cold start success, total time: 48ms
  DynaPM overhead: ~25ms (startup command + port wait)
  Service boot: ~23ms (Node.js application)

============================================================
Stream Proxy Latency
============================================================
โœ“ Stream proxy test completed (10 requests)
  Average latency: 9.5ms
  Min latency: 8ms
  Max latency: 14ms
  Latency range: 8ms - 14ms

============================================================
Throughput Test (autocannon)
============================================================
โ„น Running 5s load test (50 concurrent)...
  Multi-service throughput: 8,383 req/s
  Single-service throughput: 4,225+ req/s
  Average latency: ~23ms
  Zero errors under high concurrency

Test Requirements

  • Node.js: Run DynaPM gateway
  • curl: Basic functionality testing
  • autocannon (optional): Throughput load testing

Install autocannon:

npm install -g autocannon

๐Ÿ“– Configuration Examples

Check out dynapm.config.example.ts for complete examples including:

  • PM2-managed Node.js apps
  • Docker containers
  • systemd services
  • Direct process management
  • Environment variables
  • Custom health checks (HTTP/TCP/Command)

๐Ÿ—๏ธ Architecture

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚              User Request                        โ”‚
โ”‚   http://app.example.com:3000/api/data          โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                   โ”‚
                   โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚      DynaPM Gateway (uWebSockets.js)             โ”‚
โ”‚  - Check service status (memory cached)          โ”‚
โ”‚  - Execute start command if needed (8ms)         โ”‚
โ”‚  - Fast TCP port polling (17ms, zero-delay retry)โ”‚
โ”‚  - Stream proxy request (1-2ms)                  โ”‚
โ”‚  - Structured logging (Pino, async)              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                   โ”‚
                   โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚              Your Services                       โ”‚
โ”‚  - PM2, Docker, systemd, or any process         โ”‚
โ”‚  - Auto-stopped when idle                        โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Core Optimizations

  1. Memory state cache - No bash command execution on every request
  2. Fast TCP port check - 100ms timeout, instant retry on failure
  3. Stream forward instead of wait - Forward immediately when port is ready
  4. Startup time breakdown - Clear display of command time vs wait time

๐Ÿ“Š Performance Benchmarks

All performance data measured via pnpm benchmark script.

Cold Start Performance

Test: Total time from offline to first accessible request

Results:
โ”œโ”€ DynaPM overhead:   25ms (startup command: 8ms + TCP port wait: 17ms)
โ”œโ”€ Service boot:      160ms (Node.js application)
โ””โ”€ Total cold start:  185ms

Stream Proxy Performance

Test: Single request latency when service is running

Results:
โ”œโ”€ Average latency:  10.3ms
โ”œโ”€ Min latency:      9ms
โ”œโ”€ Max latency:      12ms
โ””โ”€ Latency range:    9-12ms

Throughput Performance

Test: Multi-service benchmark (3 services ร— 50 concurrent, 5 seconds)

Results:
โ”œโ”€ Total requests:      29,710 requests
โ”œโ”€ Average throughput:  5,942 req/s
โ”œโ”€ Per-service:         ~1,980 req/s
โ”œโ”€ Errors:              0
โ””โ”€ Test duration:       5 seconds

Resource Usage

Runtime resource usage:

โ”œโ”€ Memory:          ~50MB (Node.js runtime)
โ”œโ”€ CPU:             <1% when idle
โ”œโ”€ Disk:            21.7KB (bundle size, minified)
โ”œโ”€ Network:         Proxy traffic only, no overhead
โ””โ”€ Logging:         Async structured logging (Pino)

๐ŸŽจ Use Cases

  • ๐Ÿ‘จโ€๐Ÿ’ป Personal projects: Keep dozens of side projects ready without eating RAM
  • ๐Ÿ› ๏ธ Internal tools: On-demand access to development/testing environments
  • ๐Ÿ”ง Microservices: Lightweight alternative to Kubernetes for small deployments
  • ๐Ÿ’ฐ Resource optimization: Maximize server utilization by stopping idle services
  • ๐Ÿ“ฆ Cost saving: Run more services on smaller VPS instances
  • ๐ŸŽ“ Learning & experiments: Easily manage multiple test projects

๐Ÿ”ง Roadmap

  • ๐ŸŽ›๏ธ Web Dashboard - Service monitoring and management UI
  • ๐Ÿ“ˆ Prometheus Integration - Metrics collection and visualization
  • ๐Ÿ“‹ Service Templates - One-click PM2/Docker config generation
  • ๐Ÿ”„ Multi-instance Support - Distributed locking and state sync
  • ๐Ÿ”Œ Plugin System - Custom integrations and extensions
  • ๐ŸŒ More Health Checks - gRPC, Redis, etc.
  • โšก uWebSockets.js Migration - Completed (10x+ performance improvement)
  • ๐Ÿ“Š Structured Logging - Completed (Pino async logging)

๐Ÿ“ฆ Publishing Releases

DynaPM uses GitHub Actions to automatically publish to npm, requiring no manual tokens or 2FA.

Release Process

The project uses npm OIDC (OpenID Connect) Trusted Publishing, automatically triggered by Git tags:

# Method 1: patch version (bug fixes)
npm version patch
git push origin main --tags

# Method 2: minor version (new features)
npm version minor
git push origin main --tags

# Method 3: major version (breaking changes)
npm version major
git push origin main --tags

Automated Release Workflow

After pushing a tag, GitHub Actions automatically:

  1. โœ… Build project - Compile TypeScript with rslib
  2. โœ… Verify build - Check output file integrity
  3. โœ… Publish to npm - Use OIDC, no tokens needed
  4. โœ… Create Release - Generate release notes on GitHub

Monitor Release Status

Verify Release

# Check latest version
npm view dynapm version

# View version history
npm view dynapm versions --json

# Install and test
npm install -g dynapm@latest

Publishing Configuration

This project uses npm Trusted Publishing:

  • โœ… No NPM_TOKEN environment variable needed
  • โœ… No two-factor authentication (2FA) required
  • โœ… Automatic verification via GitHub Actions OIDC
  • โœ… More secure (short-lived tokens, auto-expiry)

For detailed setup: docs/NPM_OIDC_SETUP.md

Version Numbering

Follows Semantic Versioning:

  • 1.0.4 โ†’ 1.0.5 (patch): Bug fixes
  • 1.0.4 โ†’ 1.1.0 (minor): New features, backward compatible
  • 1.0.4 โ†’ 2.0.0 (major): Breaking changes

๐Ÿค Contributing

Contributions are welcome! Feel free to open issues or submit pull requests.

Workflow:

  1. Fork the project
  2. Create a feature branch (git checkout -b feature/AmazingFeature)
  3. Commit your changes (git commit -m 'Add some AmazingFeature')
  4. Push to the branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

๐Ÿ“„ License

ISC


๐Ÿ™ Acknowledgments

Built with amazing open-source tools:

  • uWebSockets.js - Highest performance web server for Node.js (10x+ faster than Fastify)
  • Pino - Extreme fast structured logger
  • c12 - Configuration loader

๐Ÿ“ฎ Support


โšก Made with โค๏ธ for resource-conscious developers

About

DynaPM is a dynamic start-stop application management tool with serverless-like features designed for resource-constrained environments. It starts and stops programs on demand, optimizes resource usage, and is suitable for private deployments.

Topics

Resources

License

Contributing

Stars

1 star

Watchers

1 watching

Forks

Packages

 
 
 

Contributors