60fps vs 120fps — Frame Time Math r/gamedev Keeps Re-asking

(Updated: July 16, 2026 ) fps gamedev performance

Every month someone on r/gamedev asks “how many ms is one frame at 60fps” and five people reply “just divide 1000 by 60” while others argue about VSync, deltaTime, fixed timestep, and whether the question is even meaningful on variable refresh displays. All of them are partially right — here’s the consolidated answer so you can close the tab and go back to profiling.

  • Confusing frame time budget with wall-clock frame time — Your game logic budget might be 8ms of a 16.67ms frame; GPU + present eat the rest.
  • Using 60fps math on a 120Hz target — 120fps = 8.33ms per frame, not 16.67ms. Halving the budget isn’t optional.
  • “30fps is double 60fps ms” — 30fps ≈ 33.33ms, not 33.34 exactly; close enough for design, not for audio sync without drift correction.
  • Ignoring fixed vs variable timestepUpdate() with Time.deltaTime behaves differently from fixed 50Hz physics.

Core formulas

OperationFormulaExample @ 60fps
ms per frame1000 / FPS16.67ms
seconds per frame1 / FPS0.0167s
frames → secondsframes / FPS120 frames = 2s
seconds → framesseconds * FPS0.5s = 30 frames

Quick reference table:

FPSms/framesec/frameUse case
2441.670.0417Film cadence reference
3033.330.0333Console fallback, mobile save power
6016.670.0167Standard web / Switch docked target
9011.110.0111VR comfort zone for many users
1208.330.0083ProMotion, high-refresh PC

Unity-specific notes

// Frame time in seconds (variable)
float dt = Time.deltaTime;

// Fixed physics step — often 0.02 (50 Hz), NOT the same as render FPS
float fixedDt = Time.fixedDeltaTime;

If physics runs at 50Hz but you render at 60fps, don’t multiply animation keys by 1/60 when the rig expects fixed steps — match the system you’re tuning.

Target frame rate:

Application.targetFrameRate = 60; // hint only on some platforms
QualitySettings.vSyncCount = 1;   // ties to display refresh

VSync ON at 60Hz display ≈ 16.67ms cap. VSync OFF → you might measure 300fps in empty scene but input latency and tearing tradeoffs change.

Web / canvas / requestAnimationFrame

requestAnimationFrame fires at display refresh (often 60 or 120Hz). Your callback should finish before the next paint — budget is roughly 1000/refreshRate ms minus browser chrome and GPU work.

For CSS animations, 16.67ms per step at 60fps is why steps(60) and frame-based sprite sheets use discrete timing — off-by-one frame in a 12-frame walk cycle is visible at 60fps, invisible at 30fps.

Practical profiling workflow

  1. Identify target FPS (ship criteria, not peak empty-scene FPS).
  2. Compute budget: 1000 / targetFps ms.
  3. Allocate: logic / physics / render / present — leave headroom (don’t budget 16.0ms of work in a 16.67ms frame).
  4. Use fps calculator for reverse lookups — “how many frames in 2.5 seconds at 60?”
  5. Validate on lowest ship device, not dev PC.

Audio sync edge case

Audio buffers often use sample rate (44100 Hz) not frame rate. Converting “3 frames at 60fps” to audio samples requires an extra step — don’t assume frame math applies to DSP without conversion.

Tool: frame ↔ time

The fps calculator converts FPS ↔ ms ↔ frame counts — handy when tuning animation keys, network tick rates, or explaining lag to producers.

Try the fps-calculator tool

TL;DR

ms = 1000 / FPS. 60fps ≈ 16.67ms, 120fps ≈ 8.33ms, 30fps ≈ 33.33ms. Budget is not the same as measured frame time — leave headroom and profile on target hardware.