JAVASCRIPT

JavaScript setInterval: Syntax, Usage, and Examples

setInterval() lets you run a function repeatedly, with a fixed time delay between each run. It’s useful for things like timers, UI updates, and repeating background tasks.

How to Use setInterval

You call setInterval() with two main arguments:

  • a function to run again and again
  • a delay in milliseconds

Basic syntax

setInterval(callback, delay);

Here’s a simple example that prints a message every second:

setInterval(() => {
console.log("One second passed");
},1000);

Storing the interval ID

setInterval() returns an interval ID, which you can use later to stop the interval.

const intervalId =setInterval(() => {
console.log("Still running...");
},2000);

Passing arguments to the callback

You can also pass extra arguments after the delay, and they’ll be provided to the callback.

constsayHello = (name) => {
console.log(`Hello, ${name}!`);
};

setInterval(sayHello,3000,"Nina");

That runs every 3 seconds and prints Hello, Nina!.

Stopping an interval with clearInterval()

To stop repeating, call clearInterval() and give it the interval ID.

const intervalId =setInterval(() => {
console.log("This won't run forever");
},1000);

clearInterval(intervalId);

In that example, the interval stops immediately, so it may not run at all. Usually you stop it after some condition is met, which you’ll see in the examples section.

Common timing confusion

The delay is the pause between starts, not “run exactly every X milliseconds no matter what.”

If your callback takes longer than the delay to finish, the next run can be pushed back. JavaScript timers don’t interrupt a running task.

When to Use setInterval

setInterval() fits best when you need repeating behavior and you don’t know in advance how many times it should run.

1) Building a countdown timer

Timers and countdowns are one of the most common uses. You can update the number every second, and stop at 0.

2) Refreshing UI data

Some apps update the UI every few seconds, like refreshing a “last updated” label, showing a clock, or syncing unread message counts.

3) Polling an API

If a server doesn’t support push updates, polling can help. You ask for fresh data every X seconds until something changes.

4) Creating lightweight animations

You can create basic repeating animations by adjusting CSS classes or element positions on every tick. This is not the smoothest approach compared to requestAnimationFrame(), but it works for simple cases.

5) Running periodic cleanup

Another common use case is cleaning up something regularly, like removing expired items from an in-memory list, or checking if a user session is still active.

Examples of setInterval

Example 1: Countdown timer that stops at zero

This countdown prints numbers and stops automatically.

let secondsLeft =5;

const intervalId =setInterval(() => {
console.log(secondsLeft);
  secondsLeft--;

if (secondsLeft <0) {
clearInterval(intervalId);
console.log("Done!");
  }
},1000);

A tiny detail matters here: you stop the interval once the countdown finishes. Without clearInterval(), it would keep going into negative numbers.

Example 2: Updating a digital clock in the browser

This example updates a <p> element with the current time.

<pid="clock"></p>

<script>
const clock =document.querySelector("#clock");

constupdateClock = () => {
const now =newDate();
    clock.textContent = now.toLocaleTimeString();
  };

updateClock();// Set the first value immediately

setInterval(updateClock,1000);
</script>

Calling updateClock() once at the start avoids waiting a full second before the time shows up.

Example 3: Polling for new messages

Here’s a simplified polling example. It checks for new data every 5 seconds.

constcheckMessages =async () => {
try {
const response =awaitfetch("/api/messages");
const data =await response.json();
console.log("Messages:", data);
  }catch (error) {
console.log("Could not fetch messages:", error);
  }
};

const intervalId =setInterval(checkMessages,5000);

In real projects, you usually stop polling when the user leaves a page, logs out, or closes a modal.

Example 4: Auto-saving a form draft

This pattern saves the current draft every few seconds.

<textareaid="notes"></textarea>

<script>
const notes =document.querySelector("#notes");

constsaveDraft = () => {
localStorage.setItem("draftNotes", notes.value);
console.log("Draft saved");
  };

const autosaveId =setInterval(saveDraft,4000);

// Optional: stop autosave after 1 minute
setTimeout(() => {
clearInterval(autosaveId);
console.log("Autosave stopped");
  },60000);
</script>

That combo of setInterval() and setTimeout() is common when you want repeating behavior for a limited time.

Example 5: Running something a limited number of times

Sometimes you want an interval, but only for a fixed number of repeats.

let runCount =0;

const intervalId =setInterval(() => {
  runCount++;
console.log(`Run #${runCount}`);

if (runCount ===3) {
clearInterval(intervalId);
console.log("Stopped after 3 runs");
  }
},2000);

That’s a clean pattern for retry loops, short bursts of UI updates, or limited notifications.

Learn More About setInterval

setInterval vs setTimeout

Both functions work with time delays, but they behave differently:

  • setInterval() repeats until you stop it
  • setTimeout() runs once after a delay

A lot of developers use setTimeout() recursively instead of setInterval() because it gives more control over timing.

Here’s the same repeating behavior using recursive setTimeout():

constrepeatTask = () => {
console.log("Running...");

setTimeout(repeatTask,1000);
};

repeatTask();

This approach waits for the previous run to finish before scheduling the next one, which can feel more predictable.

Avoiding multiple intervals by accident

One of the most common bugs happens when you start an interval more than once.

Example: a user clicks “Start timer” three times, and now you have three timers running in parallel. The page starts acting haunted.

You can fix this by storing the interval ID and checking if it already exists:

let intervalId =null;

conststart = () => {
if (intervalId !==null)return;

  intervalId =setInterval(() => {
console.log("Timer running");
  },1000);
};

conststop = () => {
clearInterval(intervalId);
  intervalId =null;
};

That pattern prevents duplicates and makes the start/stop logic easier to manage.

Clearing intervals when you don’t need them anymore

For browser code, leaving intervals running in the background can drain performance and battery, especially on mobile devices.

If you start an interval inside a UI feature, stop it when the feature closes.

Example logic:

  • user opens a modal, start interval
  • user closes modal, stop interval

setInterval and the event loop

setInterval() uses the JavaScript event loop, so timing can drift.

Here are a few reasons you might see delays:

  • your callback takes too long to run
  • the browser tab is in the background (timers often slow down)
  • the main thread is busy with rendering or other code

That’s why setInterval() works well for UI updates, but it’s not ideal for precise timing like game physics or accurate stopwatch logic.

A more accurate timer approach

If you need better accuracy, measure time using Date.now() instead of trusting that “1000ms always means exactly one second.”

const startTime =Date.now();

const intervalId =setInterval(() => {
const secondsPassed =Math.floor((Date.now() - startTime) /1000);
console.log(`Seconds passed: ${secondsPassed}`);

if (secondsPassed >=5) {
clearInterval(intervalId);
  }
},250);

This checks more often, but calculates the time based on actual elapsed milliseconds.

Common mistake: expecting setInterval to run immediately

An interval waits for the first delay. If you want something to happen right away and then repeat, run the function once before starting the interval.

constlogStatus = () =>console.log("Checking status...");

logStatus();
setInterval(logStatus,3000);

Summary

setInterval() runs a function repeatedly with a fixed delay, and it keeps going until you stop it with clearInterval(). Use it for timers, simple polling, auto-save features, and UI updates, and store the interval ID so you can clean it up when the job is done.