<p>I use a python script that grabs <a href="http://blockchain.info/q/getblockcount">http://blockchain.info/q/getblockcount</a> and compares it to the output of <code>bitcoind getblockcount</code>.</p>

<p>As others have said, there is no absolute way of telling if your blockchain is up to date.</p>

<p>Anyway, here is my script:</p>

<pre><code>    import httplib2
    from bitcoinrpc.authproxy import AuthServiceProxy
    access = AuthServiceProxy('#########')
    try:
            blockCount = access.getblockcount()
    except Exception as e:
            print "Problems connecting to bitcoin wallet:"
    else:
            try:
                    response, trueBlockCount = httplib2.Http().request("http://blockexplorer.com/q/getblockcount/")
            except Exception as e:
                    print "Unable to get true blockcount from blockexplorer:"+str(e)
            else:
                    if (int(trueBlockCount) - 5) &gt; blockCount :
                            print "blockchain not up to date: true block count is: "+str(trueBlockCount)+", while bitcoind is at: "+str(blockCount)
</code></pre>

CC BY-SA 3.0
2015-02-09T15:21:25.950Z
pip install httplib2 and git clone https://github.com/jgarzik/python-bitcoinrpc.git and python setup.py install helped me run this code
greg121
CC BY-SA 4.0
2018-09-07T05:43:20.450Z
rather than `bitcoind getblockcount` don't you mean `bitcoin-cli getblockcount`?
matvore
CC BY-SA 3.0
2013-09-17T01:22:05.950Z
2013-09-17T06:13:08.490Z
2013-09-17T06:13:08.490Z
Konstantin Schubert
<p>There is no way for checking whether syncing is done, simply because it isn't <em>known</em>.</p>

<p>Slightly abstractly, and probably not useful in your case, the client is <em>always</em> syncing: there is no real difference between "having all blocks" and "not having all blocks" - it always has all blocks that it knows about, and doesn't know whether there are blocks which it misses.</p>

<p>What the GUI shows you is a guess. It checks the age of the last known block, and if it is (IIRC) more than 90 minutes ago, it assumes it's out of sync. This is usually a good indicator, but it will rarely yet certainly randomly fail from time to time.</p>

<p>The core code has another heuristic built-in, which uses block heights reported by other nodes (without verifying that information in any way, so it's easily cheated). This information is used to determine whether it should optimize cache behaviour for many fast operations, or reliability. It's not exposed directly either, but the getwork() and getblocktemplate() RPCs will fail in this mode.</p>

CC BY-SA 3.0
2014-11-17T19:29:47.770Z
What is the benefit of the heuristic built-in over checking the age of the last known block?
Jori
CC BY-SA 3.0
2013-05-01T00:58:39.220Z
2013-05-01T00:58:39.220Z
Pieter Wuille
<p>Bitcoind no longer supports RPC calls. Try:</p>

<p><code>watch bitcoin-cli getblockchaininfo</code></p>

<p>When the displayed number of blocks equals the displayed number of headers, you're synced!</p>

CC BY-SA 3.0
2017-11-21T01:33:06.747Z
This doesn't seem to work in all cases.  I have a bitcoin-abc (BCH) testnet node which is synced, but headers is still significantly larger than blocks.  I think maybe it is getting header counts from BTC nodes.
Nate Eldredge
CC BY-SA 3.0
2017-11-21T15:11:50.393Z
@NateEldredge - how do you know it is synced?
Hannah Vernon
CC BY-SA 3.0
2017-11-21T23:05:30.480Z
@MaxVernon: The `debug.log` has an `UpdateTip` message showing a block with a recent timestamp, which agrees with the latest block shown by block explorers.
Nate Eldredge
CC BY-SA 3.0
2017-12-15T06:36:36.690Z
If you could include info about how to double check using the age of the last known block, I think this would be the best answer. You know you're not up to date until your latest verified block is the same as your number of headers, but you don't quite know you're up to date even when that happens until you check blocks timestamps vs network time (and your own time)
B T
CC BY-SA 3.0
2015-11-22T11:37:28.233Z
2015-11-22T11:37:28.233Z
Chris
<p>Considering that you are always somewhat out of sync, here is how you can get by how long in seconds, and then you can divide by 60 or 3600 to get it in minutes or hours.</p>

<p>If you want to do it manually:</p>

<pre><code># bitcoin-cli getblockcount
2345
# bitcoin-cli getblockhash 2345
000000007024f233aa44bc7784a78926fb1c325f9985c936ae57b94530505062
# bitcoin-cli getblock 000000007024f233aa44bc7784a78926fb1c325f9985c936ae57b94530505062 | grep "time"
    "time" : 1233313208,
# echo $((`date +%s`-1233313208))
&lt;number of seconds&gt;
</code></pre>

<p>Or the same in two steps</p>

<pre><code>bitcoin-cli getblock `bitcoin-cli getblockhash \`bitcoin-cli getblockcount\`` | grep time
    "time" : 1233313208,
echo $((`date +%s`-1233313208))
&lt;number of seconds&gt;
</code></pre>

<p>I didn't find a way to do it in one call, so here is a script that does the whole thing, with no error checking as you can see:</p>

<pre><code>#!/bin/bash
cnt=`bitcoin-cli getblockcount`
hash=`bitcoin-cli getblockhash ${cnt}`
timeline=`bitcoin-cli getblock $hash | grep '"time"'`
ltrimtime=${timeline#*time\" : }
newest=${ltrimtime%%,*}
echo $((`date +%s`-$newest))
</code></pre>

<p>Then you can replace</p>

<pre><code>echo $((`date +%s`-$newest))
</code></pre>

<p>To get the number of minutes like this:</p>

<pre><code>echo $(((`date +%s`-$newest)/60))
</code></pre>

<p>Or the number of hours like that:</p>

<pre><code>echo $(((`date +%s`-$newest)/3600))
</code></pre>

<p>Or, assuming you have perl (which you probably have) and that you prefer to have the date of the last block:</p>

<pre><code>perl -le "print scalar localtime $newest;"
</code></pre>

CC BY-SA 3.0
2015-01-15T23:16:03.713Z
The time that is in the block is the time that a miner reported, while it will probably be close to the correct time, it may not be correct. See [this question](http://bitcoin.stackexchange.com/questions/915/why-dont-the-timestamps-in-the-block-chain-always-increase).
morsecoder
CC BY-SA 4.0
2020-07-02T09:09:37.977Z
I'm trying to use this method to determine the age of the newest block in my wallet's chain, to estimated up-to-date-ness. via RPC calls, I run `getblockcount` and it returns the block number. Then I run `getblockhash $count` to get the hash. Everything seems to be going well. But then when I run `getblock $hash` it throws a parse error, every time (-32700). Any thoughts on why? Despite my variables in this comment, I have confirmed the commands being sent are correct. For example:
`getblock 000000000000000000114801309313f1fa84f8ce4e6f6e0bcc23eea91aeca343` throws a parse error :(
l008com
CC BY-SA 3.0
2014-02-07T22:32:34.757Z
2016-03-12T22:07:50.660Z
2016-03-12T22:07:50.660Z
user13239
<p><strong>Update</strong> August 7 2015 ~ start</p>

<p>So after having an IP or two banned because of checking to often... so, I'll provide some options on how to avoid getting banned.
First don't use the script under this update; the variable expansion Bash preforms causes multiple calls to <a href="https://blockchain.info" rel="nofollow">https://blockchain.info</a> in to short of a time frame. You can try adding <code>sleep 120</code> between the assignment and calls but that would be very slow.
Second the key things are; Checking local count <code>$(bitcoin-cli getblockcount)</code> and Checking a well known node <code>$(wget -q -O - http://blockchain.info/q/getblockcount)</code> and Checking local sync state <code>$(bitcoin-cli getblocktemplate)</code></p>

<p>To combine the Blockchain from your node to another in one line</p>

<pre><code>$($(wget -q -O - http://blockchain.info/q/getblockcount)-$(bitcoin-cli getblockcount))
# To print this with echo and date stamp
echo "    $(date) : $($(wget -q -O - http://blockchain.info/q/getblockcount)-$(bitcoin-cli getblockcount))"
# To redirect and exit with 0 : ie place in crontab
echo "$($(wget -q -O - http://blockchain.info/q/getblockcount)-$(bitcoin-cli getblockcount))" &gt; /var/log/btc_blocks_left_to_sync.log 2&gt;&amp;1
</code></pre>

<p>The last one above is likely the best for scripting as the file it saves to can be read for just the number inside or the last time it was modifide.</p>

<p><strong>Update</strong> August 7 2015 ~ end</p>

<p>Indeed the correct function call is shown there, @BinaryMage, thank you.</p>

<blockquote>
  <p>possible duplicate of When downloading the blockchain for the first time, how do I know when it's done? –  BinaryMage Apr 4 '13 at 0:50</p>
</blockquote>

<p>The person to show the correct function was @LoHoris, however, the updates to Bitcoin node software now uses <code>bitcoin-cli getblocktemplate</code> and not <code>bitcoind</code> for these lookups.</p>

<p>Thanks to both of them it is possible to offer you all a combination of both answers wrapped into a checker script; ready for your customization and updated for the year 2015</p>

<hr>

<pre><code>    #!/bin/bash
    timed_wait=600
    vars_to_load(){
        ## Set vars to function such that they are set upon every call
        localCheck=$(bitcoin-cli getblockcount)
        crossCheck=$(wget -q -O - http://blockchain.info/q/getblockcount)
        diffBlocks=$(($crossCheck-$localCheck))
        localSize=$(ls -hal ~/.bitcoin/blocks | awk '/total/{print $2}')
    }
    check_sync(){
        while true
        do
            current_time=$(date)
            echo $current_time
            bitcoin-cli getblocktemplate
            if [ $? = 0 ]
            then
                echo "All synced up"
            else
                echo "Uh oh, running available checks"
                ## call function that runs it all on a timer
                networked_sync
                echo "Node has $localCheck of $crossCheck blocks available."
                echo "Size of local blockchain is $localSize"
            fi
            echo "Sleeping for $timed_wait seconds or $(($timed_wait/60)) minuets."
            sleep $timed_wait
        done
    }
    networked_sync(){
        vars_to_load
        ## Function to print difference in node sync
        if [ $diffBlocks -eq 0 ]
        then
            echo "Sync is good with $diffBlocks blocks off"
        else
            echo "Sync has $diffBlocks blocks left to download"
        fi
    }
    check_sync
</code></pre>

<hr>

<p>This script first checks the exit status of <code>bitcoin-cli getblocktemplate</code> because anything other than <code>0</code> is usually an error it'll run the other parts only if <code>bitcoin-cli getblocktemplate</code> shows an error. Of course it is possible to check for specific error codes instead and do things for specific error codes... but this works fine as a template for me when setting up BTC nodes in a headless environment.
The other checks then compare local block count verses <a href="https://blockchain.info" rel="nofollow">https://blockchain.info</a> and prints out how many blocks your system is off. These only run when local check of sync status error out thus if you're on a slower like @Steven Roose mentioned then this script is ideal.</p>

<p>By default the wait time between checks is <code>600</code> seconds (10 minuets) to keep network checks and local checks to a minimum, however, for logging and better resource management it is easy enough to comment out the <code>while</code>, <code>do</code>, and <code>done</code> and <code>sleep $timed_wait</code> lines. And add one line to crontab to accomplish running on a schedule. Last modify the very end of the script to write output to a file.</p>

<hr>

<p>The function modified;</p>

<pre><code>    check_sync(){
    #   while true
    #   do
            current_time=$(date)
            echo $current_time
            bitcoin-cli getblocktemplate
            if [ $? = 0 ]
            then
                echo "All synced up"
            else
                echo "Uh oh, running available checks"
                ## call function that runs it all on a timer
                networked_sync
                echo "Node has $localCheck of $crossCheck blocks available."
                echo "Size of local blockchain is $localSize"
            fi
            echo "Sleeping for $timed_wait seconds or $(($timed_wait/60)) minuets."
    #       sleep $timed_wait
    #   done
    }
</code></pre>

<hr>

<p>And to run every 10 minuets</p>

<pre><code>    sudo nano /etc/crontab
        */10 *  * * *   root    /pathTo/script.sh 2&gt;&amp;1
</code></pre>

<p>Then to enable logging modify the call that starts every thing within the script;</p>

<pre><code>    check_sync | tee -a /tmp/BTCsync_log.txt
</code></pre>

<p>Hopefully this is acceptable enough of an answer to mark this question as [Solved] such that future  web searchers can have an easier time of this. </p>

CC BY-SA 3.0
2015-07-01T09:03:08.080Z
2015-08-08T03:58:18.437Z
2015-08-08T03:58:18.437Z
S0AndS0
<p>Not seeing any trivial answers here. Here's what i did.</p>

<p>Use API CALL "getblockchaininfo"
Parameter "verificationprogress" will be ~= 1.0, if you are synced.</p>

<p>Warning: this appears to be based on time, your clock will need to be somewhat accurate.</p>

<p>I check that it is >= 0.999 to determine if i'm in sync.</p>

CC BY-SA 4.0
2020-07-06T12:49:07.047Z
This seems like a pretty simple, logical way to determine this. Any second or third opinions about using this method? Potential pitfalls?
l008com
CC BY-SA 3.0
2016-03-12T22:47:21.270Z
2016-03-12T22:47:21.270Z
Damin
<p>A bit hacky, but the debug log shows your "progress" as far as bitcoind is concerned.</p>

<pre><code>tail -n 1 ~/.bitcoin/debug.log
</code></pre>

<p>Gives you something like </p>

<pre><code>2016-04-26 19:02:21 UpdateTip: new best=000000000000000002a9b8f81c231c99b86f79fae383fb1fc046974f7fdcf118  height=405098  log2_work=84.399379  tx=119389857  date=2016-03-31 10:06:53 
progress=0.982752  cache=0.5MiB(0tx)
</code></pre>

<p>In this case, I'm 98 percent "done".</p>

CC BY-SA 3.0
2016-04-26T19:03:53.257Z
2016-04-26T19:03:53.257Z
Thax
<p>There are some neat solutions here, and maybe this is just overly simple but, if you're legitimately catching up to the blockchain and not basically at the end so only getting that new block once every ~ 10 minutes, look at your cpu usage.</p>

<p>If you're on linux, run "top".  bitcoind will be working its butt off calculating every hash of every block through the blockchain.  Once it's caught up, it's basically idle.</p>

CC BY-SA 3.0
2015-01-18T13:01:49.187Z
Does not work when your internet connection is having issues. Or when your connection is just slow. bitcoind iterates between downloading blocks and verifying them, so in a period of downloading and a slow connection, CPU usage will be low as well.
Steven Roose
CC BY-SA 3.0
2015-01-21T03:33:08.817Z
Yes that's true.  If you have a slow enough internet connection such that your CPU is only busy hashing every 10 minutes or so, you can't tell the difference between that problem and actually being caught up.  However you'll never catch up if you don't outrace the rate at which blocks are created.  Even if you're only seeing activity once a minute that's still a clear indiciation that you're catching up.  As once you're caught up you'll only have real activity once every 10 minutes.
seijirou
CC BY-SA 3.0
2015-01-15T02:42:06.167Z
2015-01-15T02:42:06.167Z
seijirou
<p>just use the standard <code>bitcoin-cli getblockchaininfo</code></p>
<p>then check the <strong>initialblockdownload</strong> field in the response, if this is <strong>true</strong>, then the node is still synchronizing:</p>
<pre><code>{
  &quot;chain&quot;: &quot;main&quot;,
  &quot;blocks&quot;: 813280,
  &quot;headers&quot;: 814250,
  &quot;bestblockhash&quot;: &quot;0000000000000000000296fddea58647bc01598bf91f391d081c06ada148efce&quot;,
  &quot;difficulty&quot;: 61030681983175.59,
  &quot;time&quot;: 1697941840,
  &quot;mediantime&quot;: 1697939028,
  &quot;verificationprogress&quot;: 0.9981760872613284,
  &quot;initialblockdownload&quot;: true,
  &quot;chainwork&quot;: &quot;000000000000000000000000000000000000000059f423ba44c0a97786f959b1&quot;,
  &quot;size_on_disk&quot;: 590414048660,
  &quot;pruned&quot;: false,
  &quot;warnings&quot;: &quot;&quot;
}
</code></pre>

CC BY-SA 4.0
2023-11-12T06:48:19.437Z
I don't think this is correct. Not sure, I thought once the flag was set to false, it would never go back to zero. So if you start up a node that had been down for some time, it would no longer be an indicator.
Steven Roose
CC BY-SA 4.0
2023-10-28T16:06:25.483Z
2023-10-28T16:06:25.483Z
Captain Fantastic
<p>Throw the script below into your /home/$USER/.bashrc file and restart your shell.<br/></p>

<p><code>
alias bitcoindSynced='<br/><br/>
bitcoindSynced() {<br/>
blockCount=`bitcoind getblockcount`<br/>
blockChain=`wget -O - http://blockchain.info/q/getblockcount`<br/>
blockDiff=`expr $blockChain - $blockCount`<br/><br/>
if [ $blockDiff = 0 ]<br/>
then<br/>
&nbsp;&nbsp;&nbsp;&nbsp;echo "up to date"<br/>
else<br/>
&nbsp;&nbsp;&nbsp;&nbsp;echo "$blockDiff blocks behind"<br/>
fi<br/>
}<br/><br/>
bitcoindSynced 2>/dev/null'<br/>
</code>
<br/></p>

<p>Then when you run the command<br/></p>

<p><code>
bitcoindSynced<br/>
</code></p>

<p>you will be provided with the number of blocks left to sync,<br/>
or if your client is up to date it will let you know.</p>

<p><br/>
Also, if you don't want to restart your shell you can just run the command</p>

<p><code>
source /home/$USER/.bashrc
</code></p>

<p>and it will do the same thing.</p>

CC BY-SA 3.0
2013-05-01T00:39:41.160Z
That's a really strange way of doing a bash function definition.
Tom van der Woerdt
CC BY-SA 3.0
2013-05-01T00:57:41.043Z
And I have problems to believe this is the way the Bitcoin-Qt client does it...
Steven Roose
CC BY-SA 3.0
2013-05-01T16:45:16.640Z
How would you do it?
It's alised because you need to call the function after with '2>/dev/null' after defining it and you can't do that inside the function or it will repeat forever when the shell starts. I'm no linux guru, if there is a correct way to do it then please teach me :)
derrend
CC BY-SA 3.0
2013-05-01T16:52:55.507Z
Also this is not how the Bitcoin-Qt client does it, it's a hack for the bitcoind daemon.
derrend
CC BY-SA 3.0
2013-04-30T23:49:33.130Z
2013-05-01T00:02:32.963Z
2013-05-01T00:02:32.963Z
derrend
<p>More rudimentary but useful to know if the wallet is synchronized or not</p>

<p>By using the commands:</p>

<ul>
<li>"getinfo" (give your current block height) </li>
<li>"getpeerinfo" (give the
block height with the "startingheight" field for each connection).</li>
</ul>

<p>Then, you can easly compare values and find out how many percent you are for downloading the blockchain.</p>

CC BY-SA 4.0
2020-07-06T12:53:44.010Z
By `getinfo` I assume you mean `getblockchaininfo`. If that's true, this doesn't seem to work as the median number from peers right now is 637967 yet `getblockchaininfo` shows me as having 637974 blocks. So I'm magically ahead of all of my peers. Somethings not right with this method.
l008com
CC BY-SA 3.0
2017-03-14T12:45:30.590Z
2017-03-14T12:45:30.590Z
Anemol
<p>I read the <a href="https://en.bitcoin.it/wiki/Original_Bitcoin_client/API_calls_list">full api method list</a> and did not seem to find one.</p>

<p>I suppose there is no command specifically for that purpose, so what is the general way of doing this?</p>

<p>I would consider checking the time stamp of the last generated block, but the <code>getblock</code> method is not really explained in much detail.</p>

<p><strong>EDIT:</strong></p>

<p>Some people answer that I should compare the block count with one of an online block chain monitor. That is not really a practical solution. <em>The Bitcoin-Qt client has a way of knowing when syncing is done (the V-sign vs the syncing icon), so why doesn't bitcoind?</em> <strong>How does the Bitcoin-Qt get this information?</strong></p>

CC BY-SA 3.0
2013-04-04T00:50:58.760Z
possible duplicate of [When downloading the blockchain for the first time, how do I know when it's done?](http://bitcoin.stackexchange.com/questions/4394/when-downloading-the-blockchain-for-the-first-time-how-do-i-know-when-its-done)
BinaryMage
CC BY-SA 3.0
2013-04-04T00:53:01.270Z
In short: run bitcoind getinfo, compare the number after 'block count:' to the number [here](http://blockexplorer.com/q/getblockcount).
BinaryMage
CC BY-SA 3.0
2013-04-04T18:50:53.477Z
@BinaryMage That question does not make clear that it is about the daemon in the headline. I would have ignored it if I had seen it when I was looking for an answer.
Steven Roose
CC BY-SA 3.0
2013-04-04T18:54:43.817Z
Check out my edit.
Steven Roose
CC BY-SA 3.0
2013-04-04T19:25:00.333Z
[The getwork call will fail if you aren't up to date.](http://bitcoin.stackexchange.com/a/9139/2306)
Nick ODell
CC BY-SA 3.0
2013-04-05T16:48:51.110Z
@StevenRoose Good point. I edited the other question to make clear that it applied to the headless client (bitcoind).
BinaryMage
<blockchain><bitcoind><json-rpc>
How to check if the block chain is up to date using bitcoind or json-rpc?
Steven Roose
# How to check if the block chain is up to date using bitcoind or json-rpc?

(Asked by: username_0 on 2013-04-03)

I read the [full api method list](https://en.bitcoin.it/wiki/Original_Bitcoin_client/API_calls_list) and did not seem to find one.

I suppose there is no command specifically for that purpose, so what is the general way of doing this?

I would consider checking the time stamp of the last generated block, but the `getblock` method is not really explained in much detail.

**EDIT:**

Some people answer that I should compare the block count with one of an online block chain monitor. That is not really a practical solution. *The Bitcoin-Qt client has a way of knowing when syncing is done (the V-sign vs the syncing icon), so why doesn't bitcoind?* **How does the Bitcoin-Qt get this information?**

**Tags:** blockchain, bitcoind, json-rpc

> **Comments:**
> **username_1**: possible duplicate of [When downloading the blockchain for the first time, how do I know when it's done?](http://bitcoin.stackexchange.com/questions/4394/when-downloading-the-blockchain-for-the-first-time-how-do-i-know-when-its-done)  
> **username_1**: In short: run bitcoind getinfo, compare the number after 'block count:' to the number [here](http://blockexplorer.com/q/getblockcount).  
> **username_0**: @username_1 That question does not make clear that it is about the daemon in the headline. I would have ignored it if I had seen it when I was looking for an answer.  
> **username_0**: Check out my edit.  
> **username_2**: [The getwork call will fail if you aren't up to date.](http://bitcoin.stackexchange.com/a/9139/2306)  
> **username_1**: @username_0 Good point. I edited the other question to make clear that it applied to the headless client (bitcoind).  

---

## 11 answers

### Answer by username_3 on 2013-09-17. Score: 20

I use a python script that grabs <http://blockchain.info/q/getblockcount> and compares it to the output of `bitcoind getblockcount`.

As others have said, there is no absolute way of telling if your blockchain is up to date.

Anyway, here is my script:

```
    import httplib2
    from bitcoinrpc.authproxy import AuthServiceProxy
    access = AuthServiceProxy('#########')
    try:
            blockCount = access.getblockcount()
    except Exception as e:
            print "Problems connecting to bitcoin wallet:"
    else:
            try:
                    response, trueBlockCount = httplib2.Http().request("http://blockexplorer.com/q/getblockcount/")
            except Exception as e:
                    print "Unable to get true blockcount from blockexplorer:"+str(e)
            else:
                    if (int(trueBlockCount) - 5) > blockCount :
                            print "blockchain not up to date: true block count is: "+str(trueBlockCount)+", while bitcoind is at: "+str(blockCount)

```

> **Comments:**
> **username_4**: pip install httplib2 and git clone https://github.com/jgarzik/python-bitcoinrpc.git and python setup.py install helped me run this code  
> **username_5**: rather than `bitcoind getblockcount` don't you mean `bitcoin-cli getblockcount`?  

---

### Answer by username_6 on 2013-05-01. Score: 16

There is no way for checking whether syncing is done, simply because it isn't *known*.

Slightly abstractly, and probably not useful in your case, the client is *always* syncing: there is no real difference between "having all blocks" and "not having all blocks" - it always has all blocks that it knows about, and doesn't know whether there are blocks which it misses.

What the GUI shows you is a guess. It checks the age of the last known block, and if it is (IIRC) more than 90 minutes ago, it assumes it's out of sync. This is usually a good indicator, but it will rarely yet certainly randomly fail from time to time.

The core code has another heuristic built-in, which uses block heights reported by other nodes (without verifying that information in any way, so it's easily cheated). This information is used to determine whether it should optimize cache behaviour for many fast operations, or reliability. It's not exposed directly either, but the getwork() and getblocktemplate() RPCs will fail in this mode.

> **Comments:**
> **username_7**: What is the benefit of the heuristic built-in over checking the age of the last known block?  

---

### Answer by username_8 on 2015-11-22. Score: 12

Bitcoind no longer supports RPC calls. Try:

`watch bitcoin-cli getblockchaininfo`

When the displayed number of blocks equals the displayed number of headers, you're synced!

> **Comments:**
> **username_9**: This doesn't seem to work in all cases.  I have a bitcoin-abc (BCH) testnet node which is synced, but headers is still significantly larger than blocks.  I think maybe it is getting header counts from BTC nodes.  
> **username_10**: @username_9 - how do you know it is synced?  
> **username_9**: @MaxVernon: The `debug.log` has an `UpdateTip` message showing a block with a recent timestamp, which agrees with the latest block shown by block explorers.  
> **username_11**: If you could include info about how to double check using the age of the last known block, I think this would be the best answer. You know you're not up to date until your latest verified block is the same as your number of headers, but you don't quite know you're up to date even when that happens until you check blocks timestamps vs network time (and your own time)  

---

### Answer by username_12 on 2014-02-07. Score: 11

Considering that you are always somewhat out of sync, here is how you can get by how long in seconds, and then you can divide by 60 or 3600 to get it in minutes or hours.

If you want to do it manually:

```
# bitcoin-cli getblockcount
2345
# bitcoin-cli getblockhash 2345
000000007024f233aa44bc7784a78926fb1c325f9985c936ae57b94530505062
# bitcoin-cli getblock 000000007024f233aa44bc7784a78926fb1c325f9985c936ae57b94530505062 | grep "time"
    "time" : 1233313208,
# echo $((`date +%s`-1233313208))
<number of seconds>

```

Or the same in two steps

```
bitcoin-cli getblock `bitcoin-cli getblockhash \`bitcoin-cli getblockcount\`` | grep time
    "time" : 1233313208,
echo $((`date +%s`-1233313208))
<number of seconds>

```

I didn't find a way to do it in one call, so here is a script that does the whole thing, with no error checking as you can see:

```
#!/bin/bash
cnt=`bitcoin-cli getblockcount`
hash=`bitcoin-cli getblockhash ${cnt}`
timeline=`bitcoin-cli getblock $hash | grep '"time"'`
ltrimtime=${timeline#*time\" : }
newest=${ltrimtime%%,*}
echo $((`date +%s`-$newest))

```

Then you can replace

```
echo $((`date +%s`-$newest))

```

To get the number of minutes like this:

```
echo $(((`date +%s`-$newest)/60))

```

Or the number of hours like that:

```
echo $(((`date +%s`-$newest)/3600))

```

Or, assuming you have perl (which you probably have) and that you prefer to have the date of the last block:

```
perl -le "print scalar localtime $newest;"

```

> **Comments:**
> **username_13**: The time that is in the block is the time that a miner reported, while it will probably be close to the correct time, it may not be correct. See [this question](http://bitcoin.stackexchange.com/questions/915/why-dont-the-timestamps-in-the-block-chain-always-increase).  
> **username_14**: I'm trying to use this method to determine the age of the newest block in my wallet's chain, to estimated up-to-date-ness. via RPC calls, I run `getblockcount` and it returns the block number. Then I run `getblockhash $count` to get the hash. Everything seems to be going well. But then when I run `getblock $hash` it throws a parse error, every time (-32700). Any thoughts on why? Despite my variables in this comment, I have confirmed the commands being sent are correct. For example: `getblock 000000000000000000114801309313f1fa84f8ce4e6f6e0bcc23eea91aeca343` throws a parse error :(  

---

### Answer by username_15 on 2015-07-01. Score: 2

**Update** August 7 2015 ~ start

So after having an IP or two banned because of checking to often... so, I'll provide some options on how to avoid getting banned.
First don't use the script under this update; the variable expansion Bash preforms causes multiple calls to <https://blockchain.info> in to short of a time frame. You can try adding `sleep 120` between the assignment and calls but that would be very slow.
Second the key things are; Checking local count `$(bitcoin-cli getblockcount)` and Checking a well known node `$(wget -q -O - http://blockchain.info/q/getblockcount)` and Checking local sync state `$(bitcoin-cli getblocktemplate)`

To combine the Blockchain from your node to another in one line

```
$($(wget -q -O - http://blockchain.info/q/getblockcount)-$(bitcoin-cli getblockcount))
# To print this with echo and date stamp
echo "    $(date) : $($(wget -q -O - http://blockchain.info/q/getblockcount)-$(bitcoin-cli getblockcount))"
# To redirect and exit with 0 : ie place in crontab
echo "$($(wget -q -O - http://blockchain.info/q/getblockcount)-$(bitcoin-cli getblockcount))" > /var/log/btc_blocks_left_to_sync.log 2>&1

```

The last one above is likely the best for scripting as the file it saves to can be read for just the number inside or the last time it was modifide.

**Update** August 7 2015 ~ end

Indeed the correct function call is shown there, @username_1, thank you.

> possible duplicate of When downloading the blockchain for the first time, how do I know when it's done? – username_1 Apr 4 '13 at 0:50

The person to show the correct function was @LoHoris, however, the updates to Bitcoin node software now uses `bitcoin-cli getblocktemplate` and not `bitcoind` for these lookups.

Thanks to both of them it is possible to offer you all a combination of both answers wrapped into a checker script; ready for your customization and updated for the year 2015

---

```
    #!/bin/bash
    timed_wait=600
    vars_to_load(){
        ## Set vars to function such that they are set upon every call
        localCheck=$(bitcoin-cli getblockcount)
        crossCheck=$(wget -q -O - http://blockchain.info/q/getblockcount)
        diffBlocks=$(($crossCheck-$localCheck))
        localSize=$(ls -hal ~/.bitcoin/blocks | awk '/total/{print $2}')
    }
    check_sync(){
        while true
        do
            current_time=$(date)
            echo $current_time
            bitcoin-cli getblocktemplate
            if [ $? = 0 ]
            then
                echo "All synced up"
            else
                echo "Uh oh, running available checks"
                ## call function that runs it all on a timer
                networked_sync
                echo "Node has $localCheck of $crossCheck blocks available."
                echo "Size of local blockchain is $localSize"
            fi
            echo "Sleeping for $timed_wait seconds or $(($timed_wait/60)) minuets."
            sleep $timed_wait
        done
    }
    networked_sync(){
        vars_to_load
        ## Function to print difference in node sync
        if [ $diffBlocks -eq 0 ]
        then
            echo "Sync is good with $diffBlocks blocks off"
        else
            echo "Sync has $diffBlocks blocks left to download"
        fi
    }
    check_sync

```

---

This script first checks the exit status of `bitcoin-cli getblocktemplate` because anything other than `0` is usually an error it'll run the other parts only if `bitcoin-cli getblocktemplate` shows an error. Of course it is possible to check for specific error codes instead and do things for specific error codes... but this works fine as a template for me when setting up BTC nodes in a headless environment.
The other checks then compare local block count verses <https://blockchain.info> and prints out how many blocks your system is off. These only run when local check of sync status error out thus if you're on a slower like @username_0 mentioned then this script is ideal.

By default the wait time between checks is `600` seconds (10 minuets) to keep network checks and local checks to a minimum, however, for logging and better resource management it is easy enough to comment out the `while`, `do`, and `done` and `sleep $timed_wait` lines. And add one line to crontab to accomplish running on a schedule. Last modify the very end of the script to write output to a file.

---

The function modified;

```
    check_sync(){
    #   while true
    #   do
            current_time=$(date)
            echo $current_time
            bitcoin-cli getblocktemplate
            if [ $? = 0 ]
            then
                echo "All synced up"
            else
                echo "Uh oh, running available checks"
                ## call function that runs it all on a timer
                networked_sync
                echo "Node has $localCheck of $crossCheck blocks available."
                echo "Size of local blockchain is $localSize"
            fi
            echo "Sleeping for $timed_wait seconds or $(($timed_wait/60)) minuets."
    #       sleep $timed_wait
    #   done
    }

```

---

And to run every 10 minuets

```
    sudo nano /etc/crontab
        */10 *  * * *   root    /pathTo/script.sh 2>&1

```

Then to enable logging modify the call that starts every thing within the script;

```
    check_sync | tee -a /tmp/BTCsync_log.txt

```

Hopefully this is acceptable enough of an answer to mark this question as [Solved] such that future web searchers can have an easier time of this.


---

### Answer by username_16 on 2016-03-12. Score: 2

Not seeing any trivial answers here. Here's what i did.

Use API CALL "getblockchaininfo"
Parameter "verificationprogress" will be ~= 1.0, if you are synced.

Warning: this appears to be based on time, your clock will need to be somewhat accurate.

I check that it is >= 0.999 to determine if i'm in sync.

> **Comments:**
> **username_14**: This seems like a pretty simple, logical way to determine this. Any second or third opinions about using this method? Potential pitfalls?  

---

### Answer by username_17 on 2016-04-26. Score: 2

A bit hacky, but the debug log shows your "progress" as far as bitcoind is concerned.

```
tail -n 1 ~/.bitcoin/debug.log

```

Gives you something like

```
2016-04-26 19:02:21 UpdateTip: new best=000000000000000002a9b8f81c231c99b86f79fae383fb1fc046974f7fdcf118  height=405098  log2_work=84.399379  tx=119389857  date=2016-03-31 10:06:53 
progress=0.982752  cache=0.5MiB(0tx)

```

In this case, I'm 98 percent "done".


---

### Answer by username_18 on 2015-01-15. Score: 1

There are some neat solutions here, and maybe this is just overly simple but, if you're legitimately catching up to the blockchain and not basically at the end so only getting that new block once every ~ 10 minutes, look at your cpu usage.

If you're on linux, run "top". bitcoind will be working its butt off calculating every hash of every block through the blockchain. Once it's caught up, it's basically idle.

> **Comments:**
> **username_0**: Does not work when your internet connection is having issues. Or when your connection is just slow. bitcoind iterates between downloading blocks and verifying them, so in a period of downloading and a slow connection, CPU usage will be low as well.  
> **username_18**: Yes that's true.  If you have a slow enough internet connection such that your CPU is only busy hashing every 10 minutes or so, you can't tell the difference between that problem and actually being caught up.  However you'll never catch up if you don't outrace the rate at which blocks are created.  Even if you're only seeing activity once a minute that's still a clear indiciation that you're catching up.  As once you're caught up you'll only have real activity once every 10 minutes.  

---

### Answer by username_19 on 2023-10-28. Score: 1

just use the standard `bitcoin-cli getblockchaininfo`

then check the **initialblockdownload** field in the response, if this is **true**, then the node is still synchronizing:

```
{
  "chain": "main",
  "blocks": 813280,
  "headers": 814250,
  "bestblockhash": "0000000000000000000296fddea58647bc01598bf91f391d081c06ada148efce",
  "difficulty": 61030681983175.59,
  "time": 1697941840,
  "mediantime": 1697939028,
  "verificationprogress": 0.9981760872613284,
  "initialblockdownload": true,
  "chainwork": "000000000000000000000000000000000000000059f423ba44c0a97786f959b1",
  "size_on_disk": 590414048660,
  "pruned": false,
  "warnings": ""
}

```

> **Comments:**
> **username_0**: I don't think this is correct. Not sure, I thought once the flag was set to false, it would never go back to zero. So if you start up a node that had been down for some time, it would no longer be an indicator.  

---

### Answer by username_20 on 2013-04-30. Score: 0

Throw the script below into your /home/$USER/.bashrc file and restart your shell.

`alias bitcoindSynced='  
  
bitcoindSynced() {  
blockCount=`bitcoind getblockcount`  
blockChain=`wget -O - http://blockchain.info/q/getblockcount`  
blockDiff=`expr $blockChain - $blockCount`  
  
if [ $blockDiff = 0 ]  
then  
    echo "up to date"  
else  
    echo "$blockDiff blocks behind"  
fi  
}  
  
bitcoindSynced 2>/dev/null'`

Then when you run the command

`bitcoindSynced`

you will be provided with the number of blocks left to sync,  
or if your client is up to date it will let you know.

Also, if you don't want to restart your shell you can just run the command

`source /home/$USER/.bashrc`

and it will do the same thing.

> **Comments:**
> **username_21**: That's a really strange way of doing a bash function definition.  
> **username_0**: And I have problems to believe this is the way the Bitcoin-Qt client does it...  
> **username_20**: How would you do it? It's alised because you need to call the function after with '2>/dev/null' after defining it and you can't do that inside the function or it will repeat forever when the shell starts. I'm no linux guru, if there is a correct way to do it then please teach me :)  
> **username_20**: Also this is not how the Bitcoin-Qt client does it, it's a hack for the bitcoind daemon.  

---

### Answer by username_22 on 2017-03-14. Score: 0

More rudimentary but useful to know if the wallet is synchronized or not

By using the commands:

* "getinfo" (give your current block height)
* "getpeerinfo" (give the
  block height with the "startingheight" field for each connection).

Then, you can easly compare values and find out how many percent you are for downloading the blockchain.

> **Comments:**
> **username_14**: By `getinfo` I assume you mean `getblockchaininfo`. If that's true, this doesn't seem to work as the median number from peers right now is 637967 yet `getblockchaininfo` shows me as having 637974 blocks. So I'm magically ahead of all of my peers. Somethings not right with this method.  

---

