I am looking for the most performant way to to tail a file using Node.js.

There are some libaries that do this, but they seem to use polling as they ask for an interval to check for file changes.

I am wondering if I can just spawn a process that does tail -f and read from the stdout out that process. Does anyone know if the tail -f command on a linux machines uses polling or does it somehow hook into lower level observables? How does tail -f work?

In Node.js, I can do this:

const cp = require('child_process');

module.exports = function(file){

    const n = cp.spawn('tail',['-f',file]);

    n.on('error', function(err){
        console.error(err.stack || err);

    return n.stdout;


but I am wondering if there as a more efficient way to do this


1 Answer 1


On Linux, the GNU coreutils version of tail uses inotify to block waiting for changed to the file. With FreeBSD, tail uses kevent to do the same. This will be better than repeatedly checking for changes and sleeping. Depending on how often you need to do this and the frequency with which changes occur, it may or may not be worth the trouble to spawn an external process from node.js just to call tail.

If you are not using Linux or FreeBSD (or possibly MacOS?), the tail utility is probably no better than what you can do directly in JavaScript by repeatedly checking and sleeping.

Alternatively, if you are using Linux or FreeBSD, you may be able to use inotify or kevent directly from node.js with some sort of extension/plugin/module without spawning a process. I don't know if that exists.

  • that's a good answer I think...but I think using inotify in Node.js would involve spawning separate processes, so either way you will spawning extra processes. Commented Dec 24, 2016 at 23:03
  • 2
    FreeBSD tail uses kevent() of course. (-: With -fit waits for file length changes. With -F it waits for file length changes, file deletions, and file renames.
    – JdeBP
    Commented Dec 25, 2016 at 3:52
  • @JdeBP I suspect that would be true, but didn't want to say it without experience with FreeBSD. I edited that into the answer. Please feel free to review and edit further to correct if necessary.
    – Celada
    Commented Dec 27, 2016 at 23:52
  • Glad to help. I'll leave checking the MacOS code to someone else in this instance, though. (-:
    – JdeBP
    Commented Dec 28, 2016 at 0:22
  • @Christopher I looked at follow() in forward.c at the link you provided. It looks like it uses kqueue().
    – Celada
    Commented Dec 28, 2016 at 19:23

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .