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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@tgrziminiar/singleflight

v1.0.0

Published

A TypeScript utility that solves the Thundering Herd Problem by deduplicating concurrent operations

Readme

SingleFlight

A TypeScript/JavaScript utility class that solves the Thundering Herd Problem by ensuring that multiple concurrent requests for the same resource execute only once, with all callers receiving the same result.

The Problem: Thundering Herd

When multiple clients simultaneously request the same expensive resource (like a database query or API call), traditional caching can fail if the cache is empty. This results in:

  • Multiple identical database queries executing simultaneously
  • Resource waste and increased server load
  • Database connection pool exhaustion
  • Degraded performance for all users

Example of the Problem:

// Without SingleFlight - BAD ❌
async function getUserData(userId: string) {
  const cached = cache.get(userId)
  if (cached) return cached

  // If cache is empty, ALL concurrent requests will hit the database
  const userData = await database.query(
    "SELECT * FROM users WHERE id = ?",
    userId
  )
  cache.set(userId, userData)
  return userData
}

// 100 concurrent requests = 100 database queries! 😱

The Solution: SingleFlight

SingleFlight ensures that only one execution happens per unique key, regardless of how many concurrent requests are made.

// With SingleFlight - GOOD ✅
async function getUserData(userId: string) {
  return SingleFlight.do(`user:${userId}`, async () => {
    const cached = cache.get(userId)
    if (cached) return cached

    // Only ONE database query executes, even with 100 concurrent requests
    const userData = await database.query(
      "SELECT * FROM users WHERE id = ?",
      userId
    )
    cache.set(userId, userData)
    return userData
  })
}

// 100 concurrent requests = 1 database query! 🎉

Installation

npm install your-package-name
# or
yarn add your-package-name

Quick Start

import { SingleFlight } from "your-package-name"

// Basic usage
const result = await SingleFlight.do("expensive-operation", async () => {
  // This expensive operation will only run once,
  // even if called simultaneously by multiple requests
  return await fetchDataFromDatabase()
})

API Reference

SingleFlight.do<T>(key: string, fn: () => Promise<T>): Promise<T>

Executes the provided function only once per unique key, regardless of concurrent calls.

Parameters:

  • key: Unique identifier for the operation
  • fn: Async function to execute

Returns: Promise that resolves to the function's result

Example:

const userData = await SingleFlight.do("user:123", async () => {
  return await database.getUser("123")
})

SingleFlight.hasLock(key: string): boolean

Checks if an operation is currently running for the given key.

Parameters:

  • key: The key to check

Returns: true if operation is in progress, false otherwise

Example:

if (SingleFlight.hasLock("user:123")) {
  console.log("User data fetch is already in progress")
}

SingleFlight.clear(): void

Clears all active locks. Useful for testing or cleanup.

Example:

// Clear all locks (typically used in tests)
SingleFlight.clear()

Usage Examples

1. Database Query Deduplication

class UserService {
  async getUser(userId: string) {
    return SingleFlight.do(`user:${userId}`, async () => {
      console.log(`Fetching user ${userId} from database`)
      return await this.database.findUser(userId)
    })
  }
}

// Even if called 100 times simultaneously, database query runs only once
const userService = new UserService()
const promises = Array.from({ length: 100 }, () => userService.getUser("123"))
const results = await Promise.all(promises) // Only 1 database query!

2. API Call Deduplication

class WeatherService {
  async getWeather(city: string) {
    return SingleFlight.do(`weather:${city}`, async () => {
      console.log(`Calling weather API for ${city}`)
      const response = await fetch(`https://api.weather.com/${city}`)
      return response.json()
    })
  }
}

// Multiple concurrent requests for the same city = single API call

Performance Benefits

Before SingleFlight:

  • 100 concurrent requests → 100 database queries
  • High CPU usage, memory consumption
  • Database connection pool exhaustion
  • Slower response times

After SingleFlight:

  • 100 concurrent requests → 1 database query
  • Reduced resource usage
  • Better database performance
  • Faster overall response times

Testing

The package includes comprehensive tests. To run them:

pnpm test

Common Use Cases

  • Database query deduplication
  • API call optimization
  • Expensive computation results
  • Third-party service calls

TypeScript Support

SingleFlight is written in TypeScript and provides full type safety:

// Type is automatically inferred
const user: User = await SingleFlight.do(
  "user:123",
  async (): Promise<User> => {
    return await userRepository.findById("123")
  }
)