Close Menu
GeekBlog

    Subscribe to Updates

    Get the latest creative news from FooBar about art, design and business.

    What's Hot

    YouTube Rewrote Its Gameplay Violence Rules Before GTA 6, and It All Comes Down to 15 Seconds

    September 9, 2026

    OpenAI Says It Built an Automated Research Intern. It Also Wrote the Test and Graded Its Own Paper.

    September 9, 2026

    Bernie Sanders Wants a Corporate Death Penalty for AI Labs. The Hard Part Is Defining What He Is Banning.

    September 9, 2026
    Facebook X (Twitter) Instagram Threads
    GeekBlog
    • Home
    • Mobile
    • Tech News
    • Blog
    • Gaming
    • Smartwatch
    • How-To Guides
    • AI & Software
    Facebook
    GeekBlog
    Home»Blog»How to Add a Delay in C++ (Sleep and Timers)
    Blog

    How to Add a Delay in C++ (Sleep and Timers)

    Ethan CaldwellBy Ethan CaldwellSeptember 4, 202610 Mins Read
    Share Facebook Twitter Pinterest LinkedIn Tumblr Email Copy Link
    Share
    Facebook Twitter LinkedIn Pinterest Email Copy Link

    The correct way to pause a C++ program is std::this_thread::sleep_for(std::chrono::milliseconds(500)), from <thread> and <chrono>. It is portable, it releases the CPU while it waits, and unlike the old platform specific calls it takes a typed duration rather than a bare integer whose unit you have to remember. If you know the exact moment you want to wake up rather than how long to wait, use sleep_until instead.

    Quick answer: Include <thread> and <chrono>, add using namespace std::chrono_literals;, then write std::this_thread::sleep_for(2s); or sleep_for(250ms);. Compile with g++ -std=c++20 -Wall -Wextra -pthread. Never spin in an empty loop to pass time.

    Every program below was compiled and run with GCC 13.3 using g++ -std=c++20 -Wall -Wextra -pthread and produced the output shown. Sleep durations are always a lower bound: the standard promises you will sleep at least as long as requested, never that you will wake up exactly then.

    sleep_for with chrono literals

    The chrono literals turn a duration into something readable. Bring them into scope with a using declaration inside the function, not at namespace scope in a header.

    #include <iostream>
    #include <thread>
    #include <chrono>
    
    int main() {
        using namespace std::chrono_literals;
    
        std::cout << "start\n" << std::flush;
        std::this_thread::sleep_for(2s);
        std::cout << "two seconds later\n";
    
        std::this_thread::sleep_for(250ms);
        std::this_thread::sleep_for(std::chrono::microseconds(500));
        std::cout << "done\n";
        return 0;
    }
    g++ -std=c++20 -Wall -Wextra -pthread delay.cpp -o delay
    ./delay
    # start
    # two seconds later
    # done

    Note the std::flush on the first line. Standard output to a terminal is line buffered, but redirect it to a file and it becomes fully buffered, so without the flush all three lines appear at once when the program exits. That trips people up when they are using a delay to watch progress.

    LiteralLong formMeaning
    2hstd::chrono::hours(2)Two hours
    30minstd::chrono::minutes(30)Half an hour
    2sstd::chrono::seconds(2)Two seconds
    250msstd::chrono::milliseconds(250)A quarter second
    500usstd::chrono::microseconds(500)Half a millisecond
    100nsstd::chrono::nanoseconds(100)Below scheduler resolution

    You can mix them freely, because chrono durations compose: sleep_for(1s + 500ms) compiles and means what it looks like. That is the real advantage over an integer API where you have to know whether the argument is seconds or milliseconds.

    sleep_until for absolute deadlines

    When you are pacing work rather than pausing between steps, sleeping until a point in time avoids accumulating drift.

    #include <iostream>
    #include <thread>
    #include <chrono>
    
    int main() {
        using namespace std::chrono_literals;
    
        auto deadline = std::chrono::steady_clock::now() + 1500ms;
    
        for (int i = 0; i < 3; ++i) {
            std::cout << "tick " << i << '\n' << std::flush;
            std::this_thread::sleep_for(300ms);
        }
    
        std::this_thread::sleep_until(deadline);
        std::cout << "deadline reached\n";
        return 0;
    }

    The loop takes about 900 ms, then the final sleep_until waits out whatever remains of the 1500 ms budget. Had the loop overrun the deadline, sleep_until would have returned immediately rather than adding more delay, which is exactly the behavior you want in a frame loop.

    A fixed rate loop without drift

    This is the pattern to reach for whenever you need something to happen every N milliseconds. Advance a target time by the period each iteration instead of sleeping for the period.

    #include <iostream>
    #include <chrono>
    #include <thread>
    
    int main() {
        using namespace std::chrono_literals;
    
        const auto period = 200ms;
        auto next = std::chrono::steady_clock::now();
        auto origin = next;
    
        for (int i = 0; i < 5; ++i) {
            next += period;
            std::this_thread::sleep_until(next);
            std::chrono::duration<double, std::milli> since = std::chrono::steady_clock::now() - origin;
            std::cout << "frame " << i << " at " << static_cast<long>(since.count()) << " ms\n";
        }
        return 0;
    }

    Recommended for you:

    Can You Use Movie Clips in YouTube Videos? What the Law Actually Says
    Blog·Sep 3, 2026

    Can You Use Movie Clips in YouTube Videos? What the Law Actually Says

    # frame 0 at 200 ms
    # frame 1 at 400 ms
    # frame 2 at 600 ms
    # frame 3 at 800 ms
    # frame 4 at 1000 ms

    Exactly on the multiples of 200. Write the same loop with sleep_for(200ms) and each iteration adds the work time plus the scheduler’s overshoot, so by frame 100 you are visibly behind. The absolute deadline absorbs both.

    Measuring how long you actually slept

    Use steady_clock for any duration measurement. It is monotonic, so an NTP correction or a user changing the system clock cannot make your interval negative.

    #include <iostream>
    #include <thread>
    #include <chrono>
    
    int main() {
        using namespace std::chrono_literals;
    
        auto t0 = std::chrono::steady_clock::now();
        std::this_thread::sleep_for(200ms);
        auto t1 = std::chrono::steady_clock::now();
    
        auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(t1 - t0);
        std::chrono::duration<double, std::milli> exact = t1 - t0;
    
        std::cout << "requested 200 ms\n";
        std::cout << "slept " << ms.count() << " ms (integer)\n";
        std::cout << "slept " << exact.count() << " ms (double)\n";
        return 0;
    }
    # requested 200 ms
    # slept 200 ms (integer)
    # slept 200.132 ms (double)

    An overshoot of a fraction of a millisecond on an idle machine is typical. On a loaded machine, or on a general purpose desktop kernel, expect single digit milliseconds of jitter. Any design that needs tighter guarantees than that needs a real time kernel, not a different sleep function.

    Note: Three clocks, three jobs. steady_clock measures elapsed time and never goes backward. system_clock gives wall clock time you can convert to a date, and it can jump. high_resolution_clock is an alias for one of the other two on most implementations, so prefer naming the one you actually want.

    Why busy waiting is wrong

    Spinning in a loop until a deadline passes does produce a delay. It also pins a CPU core at 100 percent for the entire interval, which on a laptop means the fan spins up and the battery drains, and in a container means you burn your CPU quota for nothing.

    #include <iostream>
    #include <chrono>
    #include <thread>
    
    // Busy wait: burns a full CPU core for the whole interval. Do not do this.
    void busy_wait_ms(int ms) {
        auto end = std::chrono::steady_clock::now() + std::chrono::milliseconds(ms);
        while (std::chrono::steady_clock::now() < end) {
            // spin
        }
    }
    
    int main() {
        using namespace std::chrono_literals;
    
        auto a = std::chrono::steady_clock::now();
        busy_wait_ms(100);
        auto b = std::chrono::steady_clock::now();
        std::this_thread::sleep_for(100ms);
        auto c = std::chrono::steady_clock::now();
    
        std::chrono::duration<double, std::milli> spin = b - a;
        std::chrono::duration<double, std::milli> slept = c - b;
        std::cout << "spin  " << spin.count()  << " ms\n";
        std::cout << "sleep " << slept.count() << " ms\n";
        return 0;
    }
    # spin  100 ms
    # sleep 100.101 ms
    Warning: An empty while (true) {} loop with no side effects is worse than wasteful, it is undefined behavior in C++. A loop with no observable effect and no volatile access may be assumed to terminate, so the optimizer is permitted to delete it or to treat the code after it as unreachable. The version above is safe only because the clock read counts as an observable effect.

    The legacy platform calls

    You will still meet these in older code. They work, but there is no reason to write new code with them.

    CallPlatformUnitStatus
    Sleep(500)Windows, <windows.h>MillisecondsWorks, not portable
    sleep(2)POSIX, <unistd.h>SecondsWorks, whole seconds only
    usleep(500000)POSIX, <unistd.h>MicrosecondsRemoved from POSIX, avoid
    nanosleep(&ts, nullptr)POSIX, <ctime>NanosecondsThe modern POSIX call
    sleep_forStandard C++11 and laterAny chrono durationUse this

    The unit column is the argument for switching. Reading Sleep(500) and usleep(500) side by side, one is half a second and the other half a millisecond, and nothing in the call site tells you which. sleep_for(500ms) cannot be misread and cannot be miscompiled into the wrong unit.

    Waiting for an event instead of a fixed time

    Very often a fixed delay is a workaround for not having a signal to wait on. If another thread will tell you when something is ready, wait on a condition variable with a timeout: you wake immediately when the work is done and still have an upper bound.

    #include <iostream>
    #include <chrono>
    #include <thread>
    #include <condition_variable>
    #include <mutex>
    
    std::condition_variable cv;
    std::mutex m;
    bool ready = false;
    
    int main() {
        using namespace std::chrono_literals;
    
        std::jthread producer([]{
            std::this_thread::sleep_for(300ms);
            {
                std::lock_guard<std::mutex> lock(m);
                ready = true;
            }
            cv.notify_one();
        });
    
        std::unique_lock<std::mutex> lock(m);
        if (cv.wait_for(lock, 2s, []{ return ready; })) {
            std::cout << "woke early on the signal\n";
        } else {
            std::cout << "timed out after 2 s\n";
        }
        return 0;
    }

    This printed woke early on the signal after about 300 ms rather than sitting through the full two seconds. The predicate form of wait_for also handles spurious wakeups for you, which the plain overload does not. For more on the threading pieces here, see our guide to using threads in C++.

    Troubleshooting

    The delay is ignored and everything prints at once. The sleep happened; the output did not flush. Add << std::flush or use std::endl on the lines you want to see as they happen. This is almost always the explanation when output is redirected to a file or a pipe.

    error: ‘sleep_for’ is not a member of ‘std::this_thread’. Missing #include <thread>. Including <chrono> alone is not enough, and some standard libraries pull one in through the other, so a program can compile on one toolchain and fail on the next.

    error: unable to find numeric literal operator ‘operator””ms’. The chrono literals are not in scope. Add using namespace std::chrono_literals; inside the function, or write the long form std::chrono::milliseconds(250).

    The program sleeps far longer than requested. On Windows the default timer resolution is coarse, historically around 15 ms, so a request for 1 ms can take considerably longer. Batch small waits into one larger wait rather than issuing many tiny ones.

    Recommended for you:

    Why Is Jack the Black Cat Squishmallow So Rare?
    Blog·Sep 3, 2026

    Why Is Jack the Black Cat Squishmallow So Rare?

    Sleeping in a GUI or game loop freezes the window. You blocked the thread that pumps events. Never sleep on a UI thread. Do the waiting on a worker thread, or let the framework’s own timer or vertical sync mechanism pace the loop.

    Frequently asked questions

    Is sleep_for accurate to the millisecond?

    It guarantees a minimum, not a maximum. On a normally loaded Linux desktop, overshoot is typically well under a millisecond, and my test run of a 200 ms sleep measured 200.132 ms. Under load, or on Windows with its coarser default timer, expect several milliseconds of jitter.

    What is the difference between sleep_for and sleep_until?

    The first takes a duration relative to now, the second an absolute point on a clock. Use sleep_until in loops that must run at a fixed rate, because it absorbs the time your work took instead of adding to it. Use sleep_for for one off pauses.

    Can I sleep for less than a millisecond?

    You can request it, and the call accepts nanoseconds. Whether you get it depends on the scheduler, and a request below roughly the timer tick usually rounds up. If you truly need sub microsecond timing, you need a busy wait with a pause instruction and a good reason.

    Does sleep_for block other threads?

    No. It blocks only the thread that calls it, which is why it is spelled this_thread. Other threads keep running and the operating system reuses the core. That is the core difference from a busy wait, which occupies the core the whole time.

    Do I need -pthread to use sleep_for?

    On Linux with GCC or Clang, yes, because <thread> pulls in the threading runtime. Leaving it out may produce a link error or a binary that aborts at run time. On Windows with MSVC no extra flag is required.

    Wrapping up

    Reach for sleep_for with a chrono literal for a one off pause, and sleep_until with an advancing deadline whenever something has to happen at a steady rate. Measure with steady_clock, never with system_clock, and treat every sleep duration as a floor rather than a promise.

    The bigger question is usually whether you need a delay at all. A fixed sleep waiting for a file to appear or a service to start is a race condition with a comfortable margin. Wait on the actual event with a condition variable and a timeout and you get both correctness and an upper bound. The cppreference page for sleep_for documents the exact guarantees, and our guides on declaring float variables in C++ and joining two vectors in C++ cover the numeric and container fundamentals that sit alongside it.

    Share. Facebook Twitter Pinterest LinkedIn Tumblr Telegram Email Copy Link
    Previous ArticleThe Updated Google Ads Keyword Planner: What Changed
    Next Article Best Google Ads Books to Read in 2026
    Ethan Caldwell

      Ethan Caldwell is GeekBlog's resident Apple specialist, covering the entire Apple ecosystem - iPhone, iPad, Mac, Apple Watch, AirPods and the software that ties them together. A longtime iOS user and gadget collector, Ethan tracks Cupertino's every move, breaking down Apple keynotes, A- and M-series chip benchmarks, iOS feature updates and the rumor mill into clear, practical takes that help readers decide whether the latest Apple hardware is worth the upgrade.

      Related Posts

      11 Mins Read

      South Carolina vs Michigan: Which State Is Better to Live In?

      11 Mins Read

      Are There Cordless Vacuums With Replaceable Batteries?

      12 Mins Read

      How to Use Parabolic SAR (Stop and Reverse) for Day Trading

      10 Mins Read

      Michigan vs Illinois: Which State Is Better to Live In?

      11 Mins Read

      California or Florida: Which State Is Better to Move To?

      11 Mins Read

      Best Front End Development Books to Learn From in 2026

      Top Posts

      How to Change HEIC to JPG on iPhone, Mac, Android and Windows (No Software Needed)

      September 3, 20266 Views

      How to Use YouTube: A Beginner’s Guide

      July 7, 20266 Views

      Gal Gadot’s Lawyers Spent Six Months on One AI Clause. Then SAG Called Them for Pointers.

      September 2, 20265 Views
      Stay In Touch
      • Facebook

      Subscribe to Updates

      Get the latest tech news from FooBar about tech, design and biz.

      Most Popular

      How to Change HEIC to JPG on iPhone, Mac, Android and Windows (No Software Needed)

      September 3, 20266 Views

      Gal Gadot’s Lawyers Spent Six Months on One AI Clause. Then SAG Called Them for Pointers.

      September 2, 20265 Views

      Best Android Smartwatches in 2026: Which One Actually Fits Your Phone

      September 7, 20262 Views
      Our Picks

      YouTube Rewrote Its Gameplay Violence Rules Before GTA 6, and It All Comes Down to 15 Seconds

      September 9, 2026

      OpenAI Says It Built an Automated Research Intern. It Also Wrote the Test and Graded Its Own Paper.

      September 9, 2026

      Bernie Sanders Wants a Corporate Death Penalty for AI Labs. The Hard Part Is Defining What He Is Banning.

      September 9, 2026

      Subscribe to Updates

      Get the latest creative news from FooBar about art, design and business.

      HEICJPG.online - Convert HEIC to JPG online
      Facebook
      • About Us
      • Contact us
      • Privacy Policy
      • Disclaimer
      • Terms and Conditions
      • Editorial Policy
      • Cookie Policy
      © 2026 GeekBlog

      Type above and press Enter to search. Press Esc to cancel.