npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

async-guardian

v2.1.2

Published

Async deadlock, memory leak, and event loop monitoring for Node.js - with AI-powered suggestions

Readme

🛡️ Async Guardian

Catch memory leaks, deadlocks, blocking code and async bugs — instantly.

Like Chrome DevTools for your Node.js backend.

npm version License: MIT

🎯 What is Guardian?

Guardian is a runtime analysis engine that detects:

  • Event Loop Blocking - Find synchronous code that's killing performance
  • 🔄 Async Deadlocks - Detect circular waits and stuck promises
  • 💾 Memory Leaks - Catch growing heaps before they crash production
  • ⚠️ Unawaited Promises - Find missing await keywords
  • 🔥 CPU-Bound Code - Identify blocking functions

All with file + line number and real-time dashboard.

🚀 Quick Start

Installation

npm install async-guardian
# or
yarn add async-guardian

Basic Usage

CLI (Zero-Config)

# Start monitoring your app
npx guardian start -- node your-app.js

# Open real-time dashboard
npx guardian dashboard

# Check for deadlocks
npx guardian deadlocks

# Run health check
npx guardian doctor

Programmatic

import { Guardian } from 'async-guardian';

const guardian = Guardian.getInstance();
guardian.start();

// Your app code here

NestJS Integration (🎯 Recommended)

// app.module.ts
import { GuardianModule } from 'async-guardian/nestjs';

@Module({
  imports: [
    GuardianModule.forRoot({
      dashboard: {
        enabled: true,
        port: 4600,
      },
      monitoring: {
        eventLoop: true,
        promises: true,
        memory: true,
        unawaitedPromises: true,
      },
    }),
  ],
})
export class AppModule {}

Then visit: http://localhost:4600 for real-time monitoring.

💡 Key Features

1. Async Deadlock Detection

Automatically detects promises that are stuck waiting:

// ❌ This will be detected as a deadlock
async function orderService() {
  await paymentService(); // Waiting...
}

async function paymentService() {
  await orderService(); // Circular wait!
}

Guardian Output:

🔴 CIRCULAR DEADLOCK DETECTED

Promise pending for 32s at:
src/order.service.ts:34

This is a circular dependency in your async calls.

2. Unawaited Promise Detection

Finds promises that are created but never awaited:

// ❌ Missing await
async function badCode() {
  someAsyncFunction(); // No await!
  return 'done';
}

Guardian Output:

⚠️ UNAWAITED PROMISE

src/user.service.ts:45

Fix: Add 'await' keyword or .catch()

3. Memory Leak Detection

Monitors heap growth and identifies leaks:

🔴 MEMORY LEAK DETECTED

Heap growth: +127MB over 60s
Trend: growing

Common causes:
1. Event listeners not removed
2. Timers not cleared
3. Caches without size limits

4. Event Loop Monitoring

Detects blocking code:

⚠️ EVENT LOOP STALL

Duration: 523ms (Critical!)

Look for:
- Synchronous I/O (fs.readFileSync)
- Heavy CPU computations
- Blocking database queries

5. Real-Time Dashboard

Beautiful web UI with live metrics:

  • 📊 Event loop lag graph
  • 💾 Memory usage chart
  • 🔄 Pending promises list
  • ⚡ Live event stream
  • 🎯 Issue suggestions

📖 CLI Commands

# Start monitoring
guardian start

# Open dashboard
guardian dashboard

# Show current status
guardian status

# Show recent events
guardian events

# Check for deadlocks (runs for 5s)
guardian deadlocks

# Run full health check (runs for 10s)
guardian doctor

🎯 NestJS Integration

Guardian has first-class support for NestJS:

Method Monitoring

import { MonitorAsync } from 'async-guardian/nestjs';

@Injectable()
export class UserService {
  
  @MonitorAsync({ timeout: 5000 })
  async findUser(id: string) {
    // Will alert if this takes > 5 seconds
    return await this.db.user.findOne({ id });
  }
}

Class Monitoring

import { GuardianMonitored } from 'async-guardian/nestjs';

@GuardianMonitored()
@Injectable()
export class PaymentService {
  // All async methods in this class are monitored
}

🔧 Configuration

Advanced Config

import { Guardian } from 'async-guardian';

const guardian = Guardian.create({
  eventLoop: {
    enabled: true,
    stallThreshold: 100, // ms
    sampleInterval: 1000,
  },
  promises: {
    enabled: true,
    deadlockThreshold: 30000, // 30s
    checkInterval: 5000,
  },
  memory: {
    enabled: true,
    checkInterval: 5000,
    leakThreshold: 10, // MB
    consecutiveGrowth: 3,
  },
  unawaitedPromises: {
    enabled: true,
    checkInterval: 3000,
    warningThreshold: 5000,
  },
});

guardian.start();

🎨 Dashboard

Access the dashboard:

guardian dashboard --port 4600 --host localhost

Then open: http://localhost:4600

Features:

  • Real-time metrics
  • Event stream
  • Prometheus-style graphs
  • Issue details with suggestions
  • Export capabilities

📊 API Usage

import { Guardian, EventType } from 'async-guardian';

const guardian = Guardian.getInstance();

// Listen to specific events
guardian.getEventStore().on(EventType.MEMORY_LEAK, (event) => {
  console.log('Memory leak detected!', event);
  // Send to Slack, PagerDuty, etc.
});

// Get current status
const status = guardian.getStatus();
console.log(status);

// Get pending promises
const promises = guardian.getPendingPromises();

// Force garbage collection (if --expose-gc enabled)
guardian.forceGC();

🚀 Production Usage

Recommended Setup

// main.ts
import { Guardian } from 'async-guardian';
import { DashboardServer } from 'async-guardian/dashboard';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  
  if (process.env.NODE_ENV === 'production') {
    const guardian = Guardian.getInstance();
    guardian.start();
    
    // Only start dashboard on internal port
    const dashboard = new DashboardServer(guardian, {
      port: 4600,
      host: '127.0.0.1', // Only localhost
    });
    await dashboard.start();
  }
  
  await app.listen(3000);
}

Performance Impact

Guardian has minimal overhead:

  • Dev Mode: ~5-10% CPU overhead
  • Production Mode: ~2-3% CPU overhead (recommended config)
  • Memory: ~50MB base + ~5MB per 10k tracked promises

🤝 Enterprise Features

Need more? We offer:

  • 📊 Team Dashboard - Centralized monitoring for all services
  • 📈 Historical Analysis - 90 days retention
  • 🔔 Advanced Alerting - Slack, PagerDuty, Email
  • 🎯 Custom Rules - Define your own detection logic
  • 🏢 On-Premise - Deploy in your infrastructure
  • 🎓 Training - Node.js performance workshops
  • 🛠️ Consulting - Performance audits & optimization

Contact: [[email protected]]

📚 Examples

Check out the /examples folder for:

  • Express integration
  • NestJS full example
  • Microservices setup
  • Custom monitoring rules

🐛 Troubleshooting

"Can't call forceGC()"

Run with: node --expose-gc your-app.js

"Too many warnings about unawaited promises"

Adjust threshold in config or filter by file pattern.

"Dashboard not accessible"

Check firewall rules and host configuration.

🤝 Contributing

We love contributions! See CONTRIBUTING.md

📄 License

MIT © 2025

🌟 Why Guardian?

Other tools:

  • ❌ Too complex (require deep V8 knowledge)
  • ❌ Too expensive (APM services)
  • ❌ Too limited (single-purpose)
  • ❌ Too slow (high overhead)

Guardian:

  • ✅ Zero-config
  • ✅ Framework-aware (NestJS first-class)
  • ✅ AI-powered suggestions
  • ✅ Beautiful UI
  • ✅ Minimal overhead
  • ✅ Open source

Made with ❤️ for the Node.js community

Star us on GitHub! ⭐