Contact Us

Keystroke Counter Tool

Posted on 8/5/07 by Tim Koschützki

Today I felt like finding out how many keystrokes I do during the day. For that I made a little program that counts them. Maybe this can be an indicator for lame days and for very productive days.

I would love it if some of you could share their keystroke counts here via the commenting system. :) I for one will start to record mine tomorrow.

You can download it here.

Edit: Thanks to Michael Proctor the tool now has a great logging capability that tracks your keystrokes on an hourly and daily basis. It saves appropriate log files in your c:\keycounter\ directory. Enjoy and kudos to Michael for that!


You can skip to the end and add a comment.

Tim Koschuetzki said on May 15, 2007:

Hrm I made a total of 36,789 keystrokes today. :O

Michael Proctor  said on May 22, 2007:

Awesome little app, what language did you do that up in?

Would love to extend it a bit by making it keep a hourly count for reporting for my boss. If it was in .NET 1.1 or .NET 2.0 that would be great. :)

Hopefully he can appreciate what exactly happen behind the scenes.

Only had it installed for 10 minutes and have racked up 1264 :)

Again thanks for the contribution.


Tim Koschuetzki said on May 23, 2007:

Hi there, Michael. Glad you are liking the application. :)

I did it with AutoIt, a new easy-to-learn windows scripting language. I can send you the source code if you want to.

Or I may add your idea myself and release it here. What do you think? :)

Michael Proctor  said on May 23, 2007:

never heard of AutoIt before, seems pretty cool though.

It is wierd I would have thought that someone would have had something out there, but I can't seem to find anything :(

Then I found your tool :)

How hard you reckon it would be to get it to store "hourly" values into a text file?

I was thinking of having daily log text files with the ,
inside it.

The idea was to have a variable holding the last hour written into the file.

On each keystroke check the variable against current hour, if the current hour is > 1, store the last keystroke count into the file with the just passed hour and set the variable to the just passed hour.

On first run if there is no day log yet create the file and fill it with
, 0

up until the hour just passed.

Your thoughts?

If you could send the source that would be cool, be interested in seeing how you achieved what you did. :) *envy*, can't find a way to do it in VB.NET :)


Michael Proctor  said on May 23, 2007:

Umm wierd your blogger doesn't like me, those bits where the sentance seems to "blank" is because I used < > signs, and it interpretted them as “ ”

All I was saying it I was thinking of storing it as comma delimited with hour, keystrokecount

Have a good one

Tim Koschuetzki said on May 23, 2007:

Hi Michael,

hrm will give it a try this evening. :] This sure sounds like some fun and you more or less provided the code already. ;)

Tim Koschuetzki said on May 23, 2007:

Actually I was a little worried that people could think the tool is a keylogger. :p Of course, it is not.

Will post the source code this evening, so everybody can enjoy it.

Tim Koschuetzki said on May 23, 2007:

Okay here is the source code. Couldn't work on the hourly rates, because I had to watch the Champions League Final. :)


;Copyright by Tim Koschuetzki


HotKeySet('!q', '_Terminate')
Local $output = FileOpen('c:\log.htm', 2)

Global $bGoing = 1

Global $aKeys[166]

Global $DllUser32 = DllOpen('user32')

Func _IsPressed($hexKey)
Local $aR

$aR = DllCall($DllUser32, "int", "GetAsyncKeyState", "int", $hexKey)

If Not @error And BitAND($aR[0], 0x8000) = 0x8000 Then

Return 1


Return 0


EndFunc ;==>_IsPressed

Func _ShiftState()
Local $aR

$aR = DllCall($DllUser32, "int", "GetKeyState", "int", 0xA0)

If Not @error And BitAND($aR[0], 0x8000) = 0x8000 Then

Return 1


Return 0



Func _Terminate()
$bGoing = 0

EndFunc ;==>_Terminate

Func init_keylog()
$aKeys[0x01] = 'Left mouse button ' & @CRLF

$aKeys[0x02] = 'Right mouse button ' & @CRLF

$aKeys[0x04] = 'Middle mouse button ' & @CRLF

$aKeys[0x05] = 'X1 mouse button ' & @CRLF

$aKeys[0x06] = 'X2 mouse button ' & @CRLF

$aKeys[0x08] = 'BACKSPACE '

$aKeys[0x09] = 'TAB ' & @CRLF

$aKeys[0x0C] = 'CLEAR ' & @CRLF

$aKeys[0x0D] = 'ENTER' & @CRLF

$aKeys[0x10] = 'SHIFT '

$aKeys[0x11] = 'CTRL '

$aKeys[0x12] = 'ALT '

$aKeys[0x13] = 'PAUSE '

$aKeys[0x14] = 'CAPS LOCK '

$aKeys[0x1B] = 'ESC ' & @CRLF

$aKeys[0x20] = ' '

$aKeys[0x21] = 'PAGE UP ' & @CRLF

$aKeys[0x22] = 'PAGE DOWN ' & @CRLF

$aKeys[0x23] = 'END ' & @CRLF

$aKeys[0x24] = 'HOME ' & @CRLF

$aKeys[0x25] = 'LEFT ARROW ' & @CRLF

$aKeys[0x26] = 'UP ARROW ' & @CRLF

$aKeys[0x27] = 'RIGHT ARROW ' & @CRLF

$aKeys[0x28] = 'DOWN ARROW ' & @CRLF

$aKeys[0x29] = 'SELECT '

$aKeys[0x2A] = 'PRINT ' & @CRLF

$aKeys[0x2B] = 'EXECUTE ' & @CRLF

$aKeys[0x2C] = 'PRINT SCREEN ' & @CRLF

$aKeys[0x2D] = 'INS '

$aKeys[0x2E] = 'DEL '

$aKeys[0x30] = '0'

$aKeys[0x31] = '1'

$aKeys[0x32] = '2'

$aKeys[0x33] = '3'

$aKeys[0x34] = '4'

$aKeys[0x35] = '5'

$aKeys[0x36] = '6'

$aKeys[0x37] = '7'

$aKeys[0x38] = '8'

$aKeys[0x39] = '9'

$aKeys[0x41] = 'a'

$aKeys[0x42] = 'b'

$aKeys[0x43] = 'c'

$aKeys[0x44] = 'd'

$aKeys[0x45] = 'e'

$aKeys[0x46] = 'f'

$aKeys[0x47] = 'g'

$aKeys[0x48] = 'h'

$aKeys[0x49] = 'i'

$aKeys[0x4A] = 'j'

$aKeys[0x4B] = 'k'

$aKeys[0x4C] = 'l'

$aKeys[0x4D] = 'm'

$aKeys[0x4E] = 'n'

$aKeys[0x4F] = 'o'

$aKeys[0x50] = 'p'

$aKeys[0x51] = 'q'

$aKeys[0x52] = 'r'

$aKeys[0x53] = 's'

$aKeys[0x54] = 't'

$aKeys[0x55] = 'u'

$aKeys[0x56] = 'v'

$aKeys[0x57] = 'w'

$aKeys[0x58] = 'x'

$aKeys[0x59] = 'y'

$aKeys[0x5A] = 'z'

$aKeys[0x5B] = 'Left Windows ' & @CRLF

$aKeys[0x5C] = 'Right Windows ' & @CRLF

$aKeys[0x60] = 'Numeric pad 0'

$aKeys[0x61] = 'Numeric pad 1'

$aKeys[0x62] = 'Numeric pad 2'

$aKeys[0x63] = 'Numeric pad 3'

$aKeys[0x64] = 'Numeric pad 4'

$aKeys[0x65] = 'Numeric pad 5'

$aKeys[0x66] = 'Numeric pad 6'

$aKeys[0x67] = 'Numeric pad 7'

$aKeys[0x68] = 'Numeric pad 8'

$aKeys[0x69] = 'Numeric pad 9'

$aKeys[0x6A] = 'Multiply'

$aKeys[0x6B] = 'Add'

$aKeys[0x6C] = 'Separator'

$aKeys[0x6D] = 'Subtract'

$aKeys[0x6E] = 'Decimal'

$aKeys[0x6F] = 'Divide'

$aKeys[0x70] = ' F1 '

$aKeys[0x71] = ' F2 '

$aKeys[0x72] = ' F3 '

$aKeys[0x73] = ' F4 '

$aKeys[0x74] = ' F5 '

$aKeys[0x75] = ' F6 '

$aKeys[0x76] = ' F7 '

$aKeys[0x77] = ' F8 '

$aKeys[0x78] = ' F9 '

$aKeys[0x79] = ' F10 '

$aKeys[0x7A] = ' F11 '

$aKeys[0x7B] = ' F12 '

$aKeys[0x7C] = ' F13 '

$aKeys[0x7D] = ' F14 '

$aKeys[0x7E] = ' F15 '

$aKeys[0x7F] = ' F16 '

$aKeys[0x80] = ' F17 '

$aKeys[0x81] = ' F18 '

$aKeys[0x82] = ' F19 '

$aKeys[0x83] = ' F20 '

$aKeys[0x84] = ' F21 '

$aKeys[0x85] = ' F22 '

$aKeys[0x86] = ' F23 '

$aKeys[0x87] = ' F24 '

$aKeys[0x90] = 'NUM LOCK ' & @CRLF

$aKeys[0x91] = 'SCROLL LOCK ' & @CRLF

$aKeys[0xA0] = ' LSHIFT '

$aKeys[0xA1] = ' RSHIFT '

$aKeys[0xA2] = ' LCNTRL '

$aKeys[0xA3] = ' RCTRL '

$aKeys[0xA4] = ' LMENU '

$aKeys[0xA5] = ' RMENU '

EndFunc ;==>OnAutoItStart

Func disable_keylog()

EndFunc ;==>OnAutoItExit



;Copyright by Tim Koschuetzki


#include 'log.au3'


func keylog()
Local $bP = 0,$char = "",$buffer = "",$begin = TimerInit()

Local $overallCount = 0;

While 1
For $c = 8 To 165

if _IsPressed($c) Then

if $c <> 0xA0 and $c <> 0x10 then


until not _IsPressed($c) or $c == 0xA0 or $c == 0x10

$overallCount = $overallCount+1

TrayTip("Number of keystrokes",$overallCount & " -",20)









Michael Proctor  said on May 25, 2007:

This is my code

Didn't have to change keys.au3

this logs the file as I originally thought, what ya think?

;Copyright by Tim Koschuetzki


#include 'log.au3'


func keylog()
Local $bP = 0,$char = "",$buffer = "",$begin = TimerInit()

Local $overallCount = 0

local $dailycount = 0

Local $currenthourupdate = -1

local $hourlycount = 0

local $currentdayupdate = -1

$currenthourupdate = @HOUR
$currentdayupdate = @YEAR & "-" & @MON & "-" & @MDAY

While 1
For $c = 8 To 165

if _IsPressed($c) Then

if $c 0xA0 and $c 0x10 then



until not _IsPressed($c) or $c == 0xA0 or $c == 0x10

$overallCount += 1

$hourlycount += 1

$dailycount +=1

if $currenthourupdate @HOUR Then

WriteLog($currentdayupdate, $currenthourupdate, $hourlycount)

$hourlycount = 0

$currenthourupdate = @HOUR

if $currentdayupdate @YEAR & "-" & @MON & "-" & @MDAY Then


$dailycount = 0

$currentdayupdate = @YEAR & "-" & @MON & "-" & @MDAY



TrayTip("Number of keystrokes","Overall: " & $overallCount & @crlf & "Today: " & $dailycount & @Crlf & "This Hour: " & $hourlycount,20)







func WriteLog($daytolog, $hourtolog, $hourtotal)
local $logfile, $logline

$logfile = "c:\keycounter\" & $daytolog & ".txt"
$logline = $hourtolog & ":00," & $hourtotal

$myfile = fileopen($logfile,9)
if $myfile -1 then




msgbox(0,"KeyCounter Error","Couldn't open/write file: " & $logfile & ", you may not have permission to that folder")



func WriteDayLog($daytolog, $daytotal)
local $logfile, $logline

$logfile = "c:\keycounter\" & $daytolog & "-daytotal.txt"
$logline = $daytotal

$myfile = fileopen($logfile,9)
if $myfile -1 then




msgbox(0,"KeyCounter Error","Couldn't open/write file: " & $logfile & ", you may not have permission to that folder")




Michael Proctor  said on May 25, 2007:

So it actually writes a line in a log file yy-mm-dd.txt on every hour and once the day changes also writes a yy-mm-dd-daytotal.txt file with just the days total in it.

This AutoIt this is pretty flexible, thanks for the intro into it! :)

Michael Proctor  said on May 25, 2007:

Also I noticed you thought about logging the keystrokes by the line in the keys.au3

Local $output = FileOpen('c:\log.htm', 2)

however noticed you never used the filehandle, I took this out of my keys.au3 so that the user doesn't need permissions to c:\ to write a log.htm which doesn't get used :)

also it will create the folder c:\logcounter\ if you haven't got it and have permissions to do so.

Have fun ;)

Tim Koschuetzki said on May 25, 2007:

Awesome, Michael!

Very cool! In fact I am going to add it to the download link within the post if you allow me to do so. What do you think? :)

The reason why you see the log.html there is because I assemble the keystroke counter from a keylogger that I made earlier. I should have put that line out, I agree.

Tim Koschuetzki said on May 25, 2007:

Okay I added your version and also edited the post. Thanks a lot, Michael. This is a very cool tool now!

PS: Argh I have to do something about the < and > in the code. :/

Michael Proctor  said on May 28, 2007:

hehehe :) glad to help, I am using now at work for some KPI (key performance indicators), just gives an idea on how much coding a person has done.

also yeah the thing is annoying! ;)

if anyone else has any ideas for this little tool just comment here, it would be interesting to know what else poeple who want/need in a tool like this.



David Allan  said on May 31, 2007:

How about limiting it to count in only a single application?

Tim Koschuetzki said on May 31, 2007:

Sure that is also a good idea... Maybe Michael wants to implement this? Or I will...

Michael Proctor  said on Jun 29, 2007:

It is possible using the WinActive Function.

Just need to make a config file section for it, then we could have the file location of the logs also customisable.

Will see if I get some time over the next couple of weeks I might implement it.

Tim Koschuetzki said on Jun 29, 2007:

Great, Michael. :)

Looking forward to it. :)

Z-Man said on Jul 08, 2007:

I highly doubt I'll get a reply to this but I'll first start out by saying thank you for providing the source code, although it does me no good as I'm the hardware side. Anyway, I found this site while I was looking for a program that had a similar UI to DU Meter what with the transparancy, has 5 lines (adjustable) that will tell you how many CPM you typed every time you hit enter.

Thank you again for providing the source code and if I have someone else so this I will certainly contact you (it will be GPL freeware).

Tim Koschuetzki said on Jul 08, 2007:

Of course. :) Please do it!

Thank you for stopping by. :]

BigOlB  said on Aug 06, 2007:

This is a great little tool!

I would love to have a way to hide the pop-up that has the keystrokes in it. Is there a simnple way to do this?

Tim Koschuetzki said on Aug 07, 2007:

Yes, simply uncomment with a ';' the line that has the call to the TrayTip() function. : ]

Michael Proctor  said on Aug 07, 2007:

On the 24th I finish up my current job and move onto a new one, hopefully I will have some more "play" time and will be able to get back to this one :)

I see your comments email me now when a new post occurs, thanks Tim, makes life easier :)

Tim Koschuetzki said on Aug 08, 2007:

Alright, Michael. : ]

Have a good one! Would love to see an improved version of this!

Sandra Roberts  said on Sep 15, 2007:

Can you please tell me if this tool would work in the Oracle system? We have been trying to find a tool that is a more accurate judge of how many keystrokes are being done every hour and on a weekly and monthly basis.. We do data entry for a HEALTH corporaton and at the present time data is not being recorded as keystrokes, but is instead counted as lines. For example, if there are 2 keystrokes used to enter one line of medical data it gets the same merit as a line where there has been 9 keystrokes or more (or 70 keystrokes are sometimes used to enter these service logs of data but when you enter the last item on the page it does not work and the whole thing has to be taken out, which deletes any 'lines' recorded as work done, becoming zero instead). It is being used to count staff productivity and at this present time staff who are fast typists are working through their breaks etc on difficult data in order to make the required line quotas and still falling short of their goals because complicated or incorrect data cannot be entered. It would be more accurate to show how much physical keyboarding has been done as this is a more accurate method of determining who has been working hard versus those who have been hardly working (just surfing the net, doing emails, meeting friends in chat rooms like Facebook)...If this could work in Oracle it would be the great equalizer for all staff. Can it be done? I am not a web designer so if you can reply it would be best to speak to me on a lower level (yeah, I know). This however has been an ongoing problem in our department for several years so it would be fantastic if we could utilize this tool for Oracle (and is it possible to have it not work in the instance where it is being used for anything else, like email/hotmail and web surfing. Just the Oracle itself?) Many hardworking staff who only work all day are being told they will be losing their jobs to new people as they cannot 'keep up' which is technically wrong as mentioned with the 2 keystrokes vesus the 9, which is almost 5 times more work to get one line. I would truly appreciate any help you can provide in this matter (also is there a way to have this keystroke counter show up on individual PCs into a folder where the numerical stats cannot be manipulated/changed in any way?). Right now the boss has a counter for lines on her computer which only she can access. The staff are thinking she has been manipulating the stats so if there was no way to do this it would be the perfect tool!

Please reply as soon as possible. Thanks so much...

Tim Koschuetzki said on Sep 15, 2007:

Yes it is possible, as long as the operating system is WIndows.

I could customize it to your needs if you want me to. Please get in touch with me via tkoschuetzki [at] aol [dot] com.

Thank you!

Greg  said on Sep 27, 2007:

Hey this is a great tool. I want to use it to make sure my elderly father is ok without being too intrusive. Essentially, I want an e-mail every once in awhile with the count. If he has not been on in a day I will no something is wrong and give him a call.

My only issue is the pop thing that gives that pop up noise. Is there a way to disable this?



Stephen  said on Nov 27, 2007:

This is kind of like the awesome app "Whatpulse" That has a whole community. Was doing pretty well in it untill I stopped using it.

Someone needs to write a linux version =/

Thanks for posting the source though :)

Hector  said on May 07, 2008:

i get a 404 error when i try to dl thing. is the link broken?

Tim Koschützki said on May 07, 2008:

Thank for the heads up. Download link has been fixed.

Werner  said on May 21, 2008:

I read with much delight and interest your blog here. I would like to know if a slight modification to your program will allow the keystroke capturing to work with only certain applications? Possibly it can look up the valid exe's in an ini file or something. Any suggestions?

Tim Koschützki said on May 21, 2008:

Hi Werner, sure we could do that. Although we are quite busy at the moment with client work. Do you have a company that would be interested in major modifications?

werner  said on Jun 01, 2008:


Depending on your rate, I would like to have the application count keystrokes with an option in an ini file to state which applications it should record.

Next, I would like to have the text file data with date, time, username, application and count inserted into either an MS Access database or into something else that would handle multiple inserts from multiple users. We are doing performance measurements on data capturers to see if OCR would be an option instead of data capturing.

If you are interested in writing the script and letting me have the source, name your fee, and I will get things going here.

my email is

Thanks very much.

Mark Damen  said on Jun 17, 2008:


I really love this app and it will sort a problem out for me, but I need to disable to pop-up tooltip. I have tried copying and pasting the code provided here into the AutoIT editor, but cannot make it complile without an error. Should I be copying it into 1 file, or 2? Please help!


Tim Koschützki said on Jun 18, 2008:

Mark Damen: What is the error reported?

Mark  said on Jul 10, 2008:

How about mouse clicks too ?

stan  said on Aug 06, 2008:

I would like mouse clicks too... Awsome little app. Thanks

Tim Koschützki said on Aug 06, 2008:

Mark: stan : Hrm sound like a good idea actually.

stan  said on Aug 06, 2008:

I just downloaded AutoIt... thanks for the heads up on this program... I'll report back any sucess I have with it.

I'm a sucker for stats. After a game of AOE I spend 15 min. looking over number of quick keys, ect. I love stuff that tracks things like that.

Thanks again.

Tim Koschützki said on Aug 06, 2008:

Hey stan, I also love AoE, actually my programming started with it when I made an AI for it (The Duke-AI). :)

stan  said on Aug 06, 2008:

The sound is a setting from Windows Sounds. Change the System Notification to None and you will no longer have a sound when keystroke pops up the little balloon.

I teach and trouble shoot Autodesk software now so I have little time to mod games anymore. Seems as fast as I get the new software under my belt the next years release is out.

Someday I want to take a racing game and create all the roads around my house.
I made a map for Quake 2 that was a small version of our small town. My friends had a blast with that because we could use known landmarks... "He's behind the post office" "I'm in Bill's backyard"

ahhhh that was back when I had free time lol

stan  said on Aug 06, 2008:

By the way where can I download the AoE AI you created? I would love to try it out as well.

Tim Koschützki said on Aug 06, 2008:

stan: Try this

Then look into Aok:TC projects and AI.

Tim Koschützki said on Aug 07, 2008:

stan: Yeah well back when we all had freetime.. that was good. I remember spending nearly three years in my free time on the AI. :D

Rich Cook said on Aug 14, 2008:

Awesome app. I just downloaded it so I can track how many words I write (across blogs, emails, articles, you-name-it) and I think it'll work great.

I'd like to add something to it - a word count. Basically, I'm taking my total keystrokes count and dividing by 5 (standard way of counting words, figure each word as an average character count of 5). I'd love to have this built in (save me 10 keystrokes).

Thanks for creating it. Saves me the trouble!!


Justice  said on Oct 08, 2008:

I was a bit bothered by the little pop up window, so I opened up the source code, did what was said above, and broke SOMETHING.

The error said something about "#include depth exceeded".

Coding and I are like eternal nemeses.

janet  said on Oct 21, 2008:

Hi there - this is a great tool - I was looking to purchase some hardware to count keystrokes, but all I can find is keyloggers, which give me way more information than I want. Is there any hardware that does what your tool here does - a simple count of keystrokes/characters? If so, do you know of any that also count mouse clicks?


Andy McMahon said on Nov 18, 2008:

Is there a way to make it not pop up the entire time and every time I'm typing. It's a little frustrating, but this tool is great! Thank you for finally creating it!

Feel free to E-mail me with answers. Thanks man!

said on Dec 08, 2008:

I'd like to try this but cannot figure out how to install it.

Mgccl said on Feb 24, 2009:

Very nice thing, except it uses like 30% CPU on my computer xD.
I think I will see if I can improve on your source...

Tim Koschützki said on Feb 24, 2009:

M: Are you on a windows machine? If so, simply starting the .exe should work. Does it not?

Mgccl: yeah, it could use some improvement. :D Bad thing is, I am working on a Mac now, so I hardly get a chance to improve it. Though I should take some time to do it.

Tim Koschützki said on Feb 24, 2009:

Rich Cook: Yeah, see my previous comment. As I improve the performance I will definitely put in a word count.

cent nonan  said on Mar 09, 2009:

Hi Tim! Thanks for this. It's a great application, I just could not figure out how I would segregate or at least have a count on a certain application. Is it possible to do this?

Anand Subramanian  said on Apr 07, 2009:

Hey there Tim!

Thanks a ton to this rocking tool of yours. Was extremely useful to serve my purpose. Great!


Tony  said on Apr 16, 2009:

Why is the sleep(1) in there? It is causing me to miss many keystrokes when I type fast.

Mgccl said on Apr 16, 2009:

Sleep is there because it reduce CPU usage.
miss many keystrokes is more likely because of the key counting algorithm.

Only a few keystrokes suppose to be missed even at sleep 20 level.

It's very likely that:

When you type fast, you don't lift your finger up as soon as you stroke another key.

This keycounter made sure at any instance, it can only track one key, try press a button, hold it, then press another button repeatedly, you can see as long as the first button is not released, all other button pressed gets ignored.

btw I wrote a keycounter, the sqlite version are written in C. It have no GUI at all. It's open source, you can do w/e you want with it.

Mark - Bolero Web Services said on May 20, 2009:

Cool app! But any way to disable to the pop-up? Can you add an option to hide pop up? It is annoying. Also would be nice to count words instead of keystrokes. Anyone?

CEO, Bolero Innovations Inc

www boleroinc dotcom

Mark - Bolero Web Services said on May 20, 2009:

Can someone email me the version with pop up disabled? I don't have anything to compile with on this machine.

This post is too old. We do not allow comments here anymore in order to fight spam. If you have real feedback or questions for the post, please contact us.