<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/wait-longer-wnionl7cc" -->

---
title: Wait Longer | daily.dev
description: A developer named Karen encountered intermittently failing specification tests in TypeScript/Node.js, occurring 3-4 times per thousand runs. After extensive...
canonical: https://daily.dev/posts/wait-longer-wnionl7cc
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: Wait Longer | daily.dev
og:description: A developer named Karen encountered intermittently failing specification tests in TypeScript/Node.js, occurring 3-4 times per thousand runs. After extensive...
og:url: https://daily.dev/posts/wait-longer-wnionl7cc
og:image: https://api.daily.dev/og/posts/WniONl7cc.png
og:image:alt: Wait Longer
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Wait Longer

**[The Daily WTF](https://daily.dev/sources/thedailywtf)** · 2 min read · 22 upvotes · 3 comments

## Summary

A developer named Karen encountered intermittently failing specification tests in TypeScript/Node.js, occurring 3-4 times per thousand runs. After extensive debugging, she discovered that Node.js's setTimeout can fire before the specified delay has elapsed — unlike browser JavaScript which guarantees a minimum wait. The fix required replacing a simple setTimeout-based wait function with a polling loop that checks performance.now() every millisecond to ensure the minimum duration has actually passed. The post highlights a subtle but painful difference between Node.js timer behavior and standard JavaScript scheduler guarantees.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://thedailywtf.com/articles/wait-longer>

## Questions this post answers

### Does Node.js setTimeout guarantee it waits at least the specified delay?

No, Node.js documentation makes no guarantee about exact timing and the timeout callback can fire before the requested delay has fully elapsed. This differs from the browser's setTimeout, whose documentation warns it may wait longer than requested but never less, causing flaky tests when code assumes a minimum wait time.

_Debugging timing-sensitive Node.js tests gets easier when you compare notes with other developers on daily.dev._

### How do you guarantee a minimum wait time in Node.js when setTimeout can fire early?

Wrap the timeout in a polling loop that checks performance.now() against a target timestamp and re-schedules a 1ms setTimeout until the target time has actually passed, only resolving the promise once the elapsed time meets or exceeds the requested duration, rather than trusting a single setTimeout call.

_Developers working around Node.js timer quirks can find similar workarounds shared on daily.dev._

## Community discussion

Top comments from developers on daily.dev.

**@pdfopsdev** · 5 upvotes

> hit something adjacent — Node's timer phase runs after the poll/I-O phase in the same tick, so a setTimeout(fn, 0) racing an fs.readFile callback isn't deterministic either. the polling-against-performance.now() fix is right, libuv timers are best-effort not a contract.

**@ajaychoudhary80** · 1 upvotes

> This is a great reminder that assumptions about timers don't always hold across environments.

## Similar posts on daily.dev

- [All About Jest, Timers, and Mocks](https://daily.dev/posts/all-about-jest-timers-and-mocks-uvpmlenzh) · Liran Tal · 0 upvotes · 0 comments
- [Stop Calling Node.js “Single-Threaded”: A Look Under the Hood](https://daily.dev/posts/stop-calling-node-js-single-threaded-a-look-under-the-hood-ofsmhbjmm) · Medium · 6 upvotes · 0 comments
- [20 Mistakes That Quietly Destroy JavaScript/TypeScript Codebases \(Part 2\)](https://daily.dev/posts/20-mistakes-that-quietly-destroy-javascript-typescript-codebases-part-2--lgbflmz2i) · The T-Shaped Dev · 59 upvotes · 1 comments
- [How the JavaScript Runtime Schedules Callbacks: A Look at the Event Loop](https://daily.dev/posts/how-the-javascript-runtime-schedules-callbacks-a-look-at-the-event-loop-qkr1ufg7o) · Medium · 4 upvotes · 0 comments

---

Tags: [#javascript](https://daily.dev/tags/javascript), [#nodejs](https://daily.dev/tags/nodejs), [#typescript](https://daily.dev/tags/typescript)

[View this post on daily.dev](https://daily.dev/posts/wait-longer-wnionl7cc)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"Wait Longer","url":"https://daily.dev/posts/wait-longer-wnionl7cc","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/wait-longer-wnionl7cc"},"datePublished":"2026-07-16T10:57:56.896Z","dateModified":"2026-09-14T08:28:40.356Z","description":"A developer named Karen encountered intermittently failing specification tests in TypeScript/Node.js, occurring 3-4 times per thousand runs. After extensive...","image":"https://media.daily.dev/image/upload/s--qPvKM23u--/f_auto/v1722860399/public/Placeholder%2009","thumbnailUrl":"https://media.daily.dev/image/upload/s--qPvKM23u--/f_auto/v1722860399/public/Placeholder%2009","isAccessibleForFree":true,"articleSection":"The Daily WTF","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"The Daily WTF","logo":"https://media.daily.dev/image/upload/t_logo,f_auto/v1/logos/d21a6aa61a7244d893a3b3284df8e2ef","url":"https://daily.dev/sources/thedailywtf"},"commentCount":3,"discussionUrl":"https://daily.dev/posts/wait-longer-wnionl7cc","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":22},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":3}],"keywords":"javascript,nodejs,typescript","timeRequired":"PT2M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"The Daily WTF","item":"https://daily.dev/sources/thedailywtf"},{"@type":"ListItem","position":3,"name":"Wait Longer"}]}
{"@context":"https://schema.org","@type":"WebPage","@id":"https://daily.dev/posts/wait-longer-wnionl7cc","comment":[{"@type":"Comment","text":"hit something adjacent — Node’s timer phase runs after the poll/I-O phase in the same tick, so a setTimeout(fn, 0) racing an fs.readFile callback isn’t deterministic either. the polling-against-performance.now() fix is right, libuv timers are best-effort not a contract.","datePublished":"2026-07-16T18:07:27.522Z","url":"https://daily.dev/posts/WniONl7cc#c-RCHDAOKeS","author":{"@type":"Person","name":"PDFops","url":"https://daily.dev/pdfopsdev","image":"https://media.daily.dev/image/upload/s---8isRBKc--/f_auto/v1782922291/avatars/avatar_orjMeK8QKaaVZwGq7ScPz?_a=BAMAMicg0"},"interactionStatistic":{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":5}},{"@type":"Comment","text":"This is a great reminder that assumptions about timers don’t always hold across environments.","datePublished":"2026-07-18T04:24:21.374Z","url":"https://daily.dev/posts/WniONl7cc#c-ur68w9Pfq","author":{"@type":"Person","name":"Ajay Choudhary","url":"https://daily.dev/ajaychoudhary80","image":"https://media.daily.dev/image/upload/s--WkX8wDW2--/f_auto/v1780989706/avatars/avatar_QNZlI2SgVnNSx5PSRpCVx?_a=BAMAMiWQ0"},"interactionStatistic":{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":1}}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/wait-longer-wnionl7cc#faq","mainEntity":[{"@type":"Question","name":"Does Node.js setTimeout guarantee it waits at least the specified delay?","acceptedAnswer":{"@type":"Answer","text":"No, Node.js documentation makes no guarantee about exact timing and the timeout callback can fire before the requested delay has fully elapsed. This differs from the browser's setTimeout, whose documentation warns it may wait longer than requested but never less, causing flaky tests when code assumes a minimum wait time. Debugging timing-sensitive Node.js tests gets easier when you compare notes with other developers on daily.dev."}},{"@type":"Question","name":"How do you guarantee a minimum wait time in Node.js when setTimeout can fire early?","acceptedAnswer":{"@type":"Answer","text":"Wrap the timeout in a polling loop that checks performance.now() against a target timestamp and re-schedules a 1ms setTimeout until the target time has actually passed, only resolving the promise once the elapsed time meets or exceeds the requested duration, rather than trusting a single setTimeout call. Developers working around Node.js timer quirks can find similar workarounds shared on daily.dev."}}]}
```

