A tiny FPS counter for Windows games. It never injects into the game, it only appears in the applications you choose, and you can change its colour, size and position in two clicks.
One 72 KB executable. No installer, no service, no runtime to download, no telemetry.
Every existing option gives up something. Steam's counter only works for games you launched through Steam. Fraps still works but has not been updated since 2013. RivaTuner and Afterburner are excellent and injecting a DLL into your game is how they get there, which is heavier than most people need and something anti-cheat users would rather avoid. Game Bar is built in but barely configurable.
| FpsCounterLite | Steam overlay | Fraps | RTSS / Afterburner | Game Bar | |
|---|---|---|---|---|---|
| Injects a DLL into the game | No | Yes | Yes | Yes | No |
| Works outside its own launcher | Yes | Steam only | Yes | Yes | Yes |
| Per-application on/off | Yes | No | No | Yes (profiles) | No |
| Colour, size, font, position | Yes | Position only | Position only | Yes | Minimal |
| Download size | 72 KB | Part of Steam | ~2 MB | Tens of MB | Built in |
| Still maintained | Yes | Yes | No (2013) | Yes | Yes |
- Download
FpsCounterLite.zipfrom Releases. - Right-click the zip, choose Properties, tick Unblock, then extract it anywhere.
- Open PowerShell in that folder and run:
powershell -ExecutionPolicy Bypass -File .\install.ps1The -ExecutionPolicy Bypass is needed because Windows blocks downloaded scripts by default.
It applies to that one command only and changes nothing on your system.
The installer self-elevates (expect one UAC prompt), registers a scheduled task that starts the
counter at logon, and launches it. uninstall.ps1 removes the task the same way.
Prefer not to run a script? Everything it does by hand:
# from the folder you extracted, in an elevated PowerShell
schtasks /create /tn FpsCounterLite /tr "$PWD\FpsCounterLite.exe" /sc onlogon /rl highest /f
.\FpsCounterLite.exeOr skip installing altogether: run FpsCounterLite.exe as administrator whenever you want it.
It is portable and writes only to its own folder.
The tray icon lands under the ^ arrow next to the clock. Right-click it for everything.
Frame rates come from an ETW trace session, and Windows only lets administrators start one. Running from a scheduled task with highest privileges is what avoids a UAC prompt at every logon. Nothing is installed into the system, no service is registered, and the whole source is in this repository if you would rather build it yourself.
Nothing is switched on by default. The first time an application renders, it is added to the list switched off and a tray balloon offers to turn it on. Click the balloon, or right-click the tray icon and use Applications.
Your choices are written to apps.ini the moment you make them, so they survive restarts:
[Apps]
eldenring.exe=1
chrome.exe=0The Applications menu lists everything seen so far, most recently played first. Desktop
components that render constantly (dwm.exe, explorer.exe and friends) are filtered out.
Forget switched-off applications clears entries you never enabled.
To have everything new turn on automatically instead, tick Turn new applications on automatically.
Use the tray menu, or edit config.ini and save. The file is watched, so edits apply within
half a second with no reload step.
| Setting | Notes |
|---|---|
Color |
#RRGGBB, or use the colour picker under Appearance |
FontSize |
Pixels at 96 DPI, scaled automatically on higher DPI monitors |
FontFamily, Bold |
Any installed font |
Opacity |
10 to 100 |
Outline |
Dark edge around the glyphs so they stay readable over a bright scene |
Background |
A rounded box behind the number |
ShowSuffix |
Appends FPS after the number |
Decimals |
0, 1 or 2 |
Corner |
TopLeft TopRight BottomLeft BottomRight TopCenter BottomCenter Custom |
OffsetX, OffsetY |
Gap from the screen edge, 0 sits flush in the corner |
Monitor |
Foreground follows the active window, or Primary, or a screen index |
Hotkey |
Default Ctrl+Alt+F, toggles the counter. Leave empty to disable |
SmoothingWindowMs |
Averaging window. Lower reacts faster, higher reads steadier |
For a spot that is not a corner, use Position, Move mode: the counter gains a border and
becomes draggable. Drag it, then untick Move mode. The coordinates save as Corner=Custom.
Settings live next to the executable so the app stays portable. If that folder is not writable,
they move to %LOCALAPPDATA%\FpsCounterLite instead.
Every time a game finishes a frame it calls Present on its swap chain, and Windows raises an
ETW event for it. FpsCounterLite runs a real-time trace session, counts those events per
process, and divides by time. That is the same signal Intel's PresentMon reports as
"Presented FPS".
Nothing is loaded into the game. There is no DLL injection, no API hooking, no reading or writing of another process's memory, and no kernel driver.
Three details that are easy to get wrong, in case you are reading the source:
- The DXGI provider raises two events per frame, the analytic
Presentand the API traceIDXGISwapChain_Present. Counting both reports double the real frame rate. DxgKrnl's present is anInfoopcode, notStart, and it fires for Direct3D frames too. So the API rate is preferred per process and the kernel rate is only a fallback, never a sum.- Enabling the DXGI provider with keyword
0x1delivers nothing on current Windows builds. The keyword has to be0.
- Exclusive fullscreen bypasses the desktop compositor, so no overlay that does not inject can draw over it. Borderless or windowed fullscreen works, which is the default in most modern games. If the counter disappears when a game goes fullscreen, switch the game to borderless.
- Vulkan and OpenGL titles do not raise the Direct3D present events. Tick Vulkan / OpenGL support for those. It is off by default because it raises roughly 35,000 events per second instead of about 1,000.
- It shows the frame rate of the foreground application only.
- The released executable is not code signed, so SmartScreen will warn on first run. Choose More info, then Run anyway, or build it yourself from source.
.\FpsCounterLite.exe --probeRun it elevated. It animates a small window for a few seconds so there is guaranteed load, samples every process that renders, and opens a report. If your game appears there with a plausible frame rate, the name in the left column is what to tick under Applications. If it does not appear at all, turn on Vulkan / OpenGL support and probe again.
Errors are appended to error.log next to the executable.
It does not inject a DLL, hook any API, or touch the game's memory. It reads a Windows event stream that any administrator can subscribe to, exactly as PresentMon and Task Manager's own telemetry do. That is a materially smaller footprint than any overlay that injects.
That said, nobody outside an anti-cheat vendor can promise how their software will classify a given tool. If you play something with an aggressive kernel anti-cheat and you are worried, the safest answer is always to run nothing extra.
.\build.ps1Requires nothing but Windows: it compiles with csc.exe from the .NET Framework 4 directory,
which is present on every supported Windows version. scripts\make-icon.ps1 regenerates the
application icon.
| File | Purpose |
|---|---|
src/Program.cs |
Tray menu, sampling loop, the --probe diagnostic |
src/PresentMonitor.cs |
ETW session and per-process present counting |
src/OverlayForm.cs |
The layered click-through window and its text rendering |
src/Config.cs |
config.ini, apps.ini, paths and logging |
src/Native.cs |
P/Invoke declarations and ETW structure offsets |
MIT. See LICENSE.