Skip to content
OneKitly

Frame Rates, Timecode, and the Drop-Frame That Drops Nothing

Published 8/26/2025 · 18 min read · Developer tools

Daniel Okonkwo

Daniel OkonkwoFront-end developer and tech writer at OneKitly

Web performance · File formats

Checked against 6 sources

View profile
In short

Counting frames is multiplication until the frame rate stops being a whole number. At 24, 25 or 30 frames per second, a minute holds 1440, 1500 or 1800 frames and there is nothing more to say. At 29.97 — which is exactly 30 × 1000/1001, or 30000/1001 — an hour holds 107,892.108 frames, and a timecode counter that labels 30 frames to the second is lying by a growing amount. Compute it two ways and both give the same answer. An hour of labels is 108,000 frames, which at 1001/30000 seconds each takes 3603.600000 seconds of real time. Equivalently, an hour of wall clock advances the counter only 107,892 frames, so it reads 00:59:56:12. Either way the error is 108 frames, which at 30 labels per second is exactly 3.6 seconds per hour. Drop-frame timecode fixes this by skipping frame numbers, never frames: two labels are omitted at the start of each minute except every tenth minute, giving 54 × 2 = 108 skipped labels an hour — precisely the deficit. No picture is discarded and no footage is lost. The correction is very good but not exact: walking every frame of an hour shows drop-frame still runs 3.6 milliseconds slow.

Frames = duration × rate is trivial until the rate is 29.97. Non-drop timecode then drifts exactly 3.6 seconds an hour. Drop-frame corrects it by skipping 108 frame numbers — the same 108 — but the correction is not perfect: counting every frame shows a residual of 3.6 milliseconds per hour.

Frames = duration × rate, until the rate is 29.97

For an integer frame rate the arithmetic is closed and exact. At 24 frames per second a minute is 1440 frames and an hour is 86,400. At 25 a minute is 1500 and an hour is 90,000. At 30 a minute is 1800 and an hour is 108,000. Every duration maps to a whole number of frames, every frame count maps back to a duration, and a timecode label that counts hours, minutes, seconds and frames is simply a base-conversion of the frame number.

At 29.97 the closure breaks. A second holds 29.97002997 frames, a minute holds 1798.202 and an hour holds 107,892.108. There is no whole number of frames in an hour, so no labelling scheme that counts thirty frames to a second can stay aligned with a clock. Every tool in the chain then has to decide what to do about the mismatch, and the various answers to that question are the entire subject of timecode.

One notational convention is worth learning immediately, because it carries the whole distinction. Non-drop timecode is written with colons throughout, 01:00:00:00. Drop-frame timecode replaces the last separator with a semicolon, 01:00:00;00. If you see a semicolon you are looking at a drop-frame count, and if a tool reports one duration and your notes say another, the separator is the first thing to check.

Where 29.97 comes from

The number is the residue of a compatibility problem solved in 1953. Monochrome television in the 525-line system ran at exactly 30 frames per second, with a line rate of 15,750 Hz and a sound carrier 4.5 MHz above the picture carrier. When colour was added, the chrominance information had to be carried on a subcarrier inside the existing channel, and it had to interleave with the luminance spectrum rather than beat visibly against it. That constraint fixed the subcarrier at an odd multiple of half the line rate — specifically 455/2 times it.

The remaining problem was the sound carrier. At the original line rate the ratio of the 4.5 MHz sound carrier to the line frequency was 2855/7, which is 407.857 — not an integer, so the new colour subcarrier would beat audibly against the sound. Multiplying that ratio by 1001/1000 raises it to 408.265, close enough that the standards body could instead redefine the line rate so the sound carrier sat at the 286th harmonic exactly. That is the whole manoeuvre: hold the sound carrier at 4.5 MHz, declare it the 286th harmonic, and let the line rate fall to 4,500,000 ÷ 286 = 15,734.2657 Hz.

From there the frame rate follows mechanically. Divide the line rate by the 525 lines in a frame: 15,734.2657 ÷ 525 = 29.970029970 frames per second. The identity with 30000/1001 is exact rather than approximate, and you can see why in the factorisation — 286 × 525 = 150,150, which is 150 × 1001, so 4,500,000 ÷ 150,150 reduces to 30,000 ÷ 1,001. The colour subcarrier lands at 455/2 × 15,734.2657 = 3.579545 MHz, the figure printed on every NTSC crystal ever made. The same 1000/1001 factor propagates to 23.976 = 24000/1001 and 59.94 = 60000/1001, which is why those numbers travel together.

Non-drop timecode drifts 3.6 seconds an hour

Non-drop timecode does the naive thing: it labels every frame in sequence and rolls the seconds field over every thirty frames, regardless of how long thirty frames actually take. Since a frame lasts 1001/30000 of a second rather than 1/30, the label runs slow against the clock, and the size of that error is easy to compute in either direction.

Start from the labels. One hour of non-drop timecode is 108,000 frame labels, because 60 × 60 × 30 = 108,000. Those 108,000 frames each last 1001/30000 of a second, so together they occupy 108,000 × 1001 ÷ 30,000 = 3603.600000 seconds. A tape that reads exactly one hour of non-drop timecode has been running for one hour and 3.6 seconds.

Now start from the clock instead. In one hour of real time the camera has produced 3600 × 30000 ÷ 1001 = 107,892.108 frames, so the counter has advanced 107,892 whole frames. Divide by 30 labels per second and that is 3596.400000 seconds of label — the display reads 00:59:56:12 when the wall clock says an hour. The two derivations agree: the discrepancy is 108,000 − 107,892 = 108 frames, and 108 ÷ 30 = 3.6 seconds. Hold onto that 108. It is the number the whole drop-frame scheme is built around.

The drift accumulates linearly and gets alarming fast. At the thirty-minute mark non-drop is already 1.8 seconds out. At ten hours it is 36 seconds out. For a broadcaster assembling a programme to a fixed slot length, that is not a rounding detail; it is the difference between hitting the network junction and being cut off mid-sentence.

Drop-frame drops labels, not frames — proved by counting

The name is the single worst piece of terminology in post-production. Drop-frame timecode discards no picture whatsoever. Every frame the camera recorded is present in the file, is played back, and is available to cut on. What is dropped is two entries from the numbering scheme at the start of most minutes — labels that are simply never issued, in the same way that a building with no thirteenth floor has not lost a storey.

The rule, as written in the SMPTE timecode standard, is short. At the start of every minute, skip frame numbers 00 and 01, so the minute begins at frame 02 — except when the minute number is a multiple of ten, in which case no numbers are skipped and the minute begins at 00 as usual. So 00:00:59;29 is followed by 00:01:00;02, and the labels 00:01:00;00 and 00:01:00;01 never exist. But 00:09:59;29 is followed by 00:10:00;00, because minute 10 is exempt.

Now count, rather than assert. Walk a counter forward one frame at a time from 00:00:00;00, applying that rule at every minute boundary, and stop when the display next reads 01:00:00;00. The walk emits 107,892 frames and skips 108 frame numbers. That skip count is not a coincidence and does not need to be looked up: an hour has 60 minutes, six of which are exempt because 0, 10, 20, 30, 40 and 50 are multiples of ten, leaving 54 minutes that drop two numbers each, and 54 × 2 = 108. The closed-form conversion used inside editing software — frames = 108000h + 1800m + 30s + f − 2 × (totalMinutes − floor(totalMinutes ÷ 10)) — returns 107,892 for the same label, matching the walk exactly.

Set that against the previous section and the design becomes obvious. Non-drop loses exactly 108 frames per hour against the clock. Drop-frame skips exactly 108 labels per hour. The two 108s are the same 108, chosen for that reason, and that is why a drop-frame hour lands on the wall clock while a non-drop hour lands 3.6 seconds late. The scheme is a calendar-style correction, structurally identical to the leap-year rule: a small periodic adjustment with a periodic exception, sized to cancel a known accumulating error.

The correction is very good, and not exact

It is often said that drop-frame makes timecode match wall clock exactly. The counting shows otherwise, and the discrepancy is worth stating because it is the kind of thing that surfaces once a year in a long-running installation. An hour of real time contains 107,892.108 frames, not 107,892. Drop-frame supplies 107,892 labels an hour, so it is short by 0.1078921 of a frame — a fraction it cannot possibly skip, because labels come in whole numbers.

Convert that fraction to time and it is 0.003600 seconds, so a drop-frame hour occupies 3599.996400 seconds of real time rather than 3600. Drop-frame runs 3.6 milliseconds fast per hour — in the opposite direction to the error it corrects, and a thousand times smaller. Over a day that is 0.0864 seconds, over a month about 2.6 seconds, and over a year 31.5 seconds. For editing, for broadcast slots, for anything measured in frames, this is irrelevant. For a facility running a timecode generator continuously as a house reference against an atomic clock, it is exactly the sort of slow divergence that gets noticed and misdiagnosed.

The comparison is what matters. Drop-frame reduces the error by a factor of a thousand: from 3.6 seconds an hour to 3.6 milliseconds an hour. Tracking the accumulated error at intervals makes the shape clear — at ten minutes drop-frame is 0.6 milliseconds out, at thirty minutes 1.8, at one hour 3.6, at ten hours 36 milliseconds. Non-drop over the same spans is out by 1.8 seconds at thirty minutes, 3.6 seconds at an hour and 36 seconds at ten hours. The scheme was never claimed to be perfect; it was designed to be good enough that no programme would miss its slot.

23.976, pulldown, and the PAL speed-up

Film runs at 24 frames per second and the 525-line video system runs at 30, so putting film onto video needs five video frames for every four film frames — 24 × 5/4 = 30 exactly. The mechanism is 2:3 pulldown, sometimes written 3:2. Take four film frames A, B, C, D and lay them into ten video fields: A gets two fields, B gets three, C gets two, D gets three, totalling 2 + 3 + 2 + 3 = 10 fields, which is five interlaced video frames. Two of those five frames are composites of different film frames, which is why pulled-down material looks slightly stuttery and why removing pulldown before editing is standard practice.

That works when the video system runs at 30. It runs at 29.97, so the film has to be slowed by the same 1000/1001 factor first, from 24 to 24,000 ÷ 1,001 = 23.976023976 frames per second. That is the entire origin of 23.976: it is 24 slowed just enough to sit in a 29.97 world. The slowdown is small but real — a hundred-minute reel run at 23.976 lasts 100.1 minutes, six seconds longer than at 24 — and audio recorded at 24 must be pulled down by the same factor or it will drift out of sync by those six seconds over the reel.

The 625-line world took a blunter route. With video at 25 and film at 24, the easiest transfer is simply to run the film one frame per second faster and use one video frame per film frame. The speed change is 25/24 = 1.041667, an increase of 4.1667 percent — usually rounded to the familiar four percent, though the extra sixth matters over a feature. A 120-minute film runs 115.2 minutes, 288 seconds shorter. The audio goes up in pitch by the same ratio: 12 × log2(25/24) = 0.7067 of a semitone, or 70.67 cents, which is close enough to a quarter-tone to be audible to anyone who knows the score. Modern transfers usually correct the pitch digitally and leave the running time short.

Cutting audio to picture

Audio is sampled and picture is framed, and the two only line up neatly when the number of samples in a frame is a whole number. At 48 kHz the arithmetic is friendly for most rates: 24 frames per second gives exactly 2000 samples per frame, 25 gives 1920, 30 gives 1600. The pleasant surprise is 23.976, which gives 48,000 × 1001 ÷ 24,000 = 2002 samples per frame, also a whole number — one of the reasons 23.976 and 48 kHz are such a comfortable pair.

29.97 is the awkward one. At 48 kHz a frame holds 48,000 × 1001 ÷ 30,000 = 1601.6 samples, which is not a whole number, so no single frame boundary falls on a sample boundary. The pattern closes after five frames: 5 × 1601.6 = 8008 samples exactly. That five-frame cycle is the practical unit for anything that must be sample-accurate against picture at 29.97, and 59.94 inherits it — 800.8 samples per frame, whole after the same five frames at 4004 samples. At 44.1 kHz the situation is far worse: 1471.47 samples per frame, and the pattern does not close until 100 frames have passed. That is one concrete reason post-production runs at 48 kHz and not 44.1.

The practical rule that falls out of all this is short. Establish the project frame rate before anything is imported, run audio at 48 kHz, and make every cut point a frame boundary rather than a sample offset, so that the five-frame cycle at 29.97 never has to be reasoned about. When material arrives at a different rate, conform it deliberately with an explicit pull-up or pull-down of 1000/1001 rather than letting a timeline reinterpret it silently — a mismatch of that factor drifts by one frame roughly every 33 seconds, which reads as a sync error that slowly gets worse and is one of the most commonly misdiagnosed faults in post.

Frames in 1 minute
Frame rates as exact fractions, with frame counts and audio samples per frame at 48 kHz
RateExact valueFrames in 1 minuteFrames in 1 hourSamples per frame at 48 kHz
23.97624000/1001 = 23.9760239761438.56186,313.6862002 (whole)
2424 exactly144086,4002000 (whole)
2525 exactly150090,0001920 (whole)
29.9730000/1001 = 29.9700299701798.202107,892.1081601.6 — whole after 5 frames (8008)
3030 exactly1800108,0001600 (whole)
59.9460000/1001 = 59.9400599403596.404215,784.216800.8 — whole after 5 frames (4004)

Worked with our own calculator

Video frame count calculator

Given

Duration (seconds)
60
Frame rate (fps)
30

Result

Total frames
1,800

These figures are produced by the calculator below, not typed in by hand — they are recomputed whenever the tool changes.

Run it on your own figures

Frequently asked questions

Does drop-frame timecode lose any picture?
No. Not one frame. Drop-frame changes only the labels attached to frames, never the frames themselves, and this is the single most persistent misunderstanding in post-production. A one-hour drop-frame programme contains 107,892 frames, and a one-hour non-drop programme contains 108,000 — but those are different amounts of running time, not the same footage with some removed. The drop-frame hour genuinely lasts an hour of wall clock; the non-drop hour lasts an hour and 3.6 seconds. Both contain every frame that was shot. The useful analogy is a building with no thirteenth floor: the numbering skips a value, the building has the same number of storeys, and nobody has been evicted. If you convert a project from non-drop to drop-frame in an editor, the picture is untouched — only the numbers displayed on the timeline change, and any note written as a timecode value will now point somewhere slightly different. That last part is the real hazard, and it is why frame counts rather than timecode strings are the safe currency for exchanging edit points between systems.
Should I use drop-frame or non-drop?
Use drop-frame whenever the running time has to match a clock, and non-drop whenever it does not. Broadcast is the clearest case for drop-frame: a programme cut to a 60-minute slot in non-drop timecode will actually run 3603.6 seconds and overrun the junction by 3.6 seconds, which is enough to be cut off. Advertising is the same, since a spot is sold by duration. Drop-frame gets you to within 3.6 milliseconds an hour, which no scheduling system cares about. Non-drop is preferable everywhere the label is an index rather than a duration: visual-effects handoffs, archival masters, dailies, anything where a shot is identified by a timecode value and consistency of numbering matters more than agreement with a clock. Non-drop has the advantage that every arithmetic operation on it is simple and no label is ever missing, which removes a whole class of off-by-one errors when scripts parse timecode. Two practical notes. Drop-frame exists only at 29.97 and 59.94; it is meaningless at 24, 25 or 23.976, and a tool offering it there is confused. And whichever you choose, set it once at project creation and never change it mid-project, because every note anyone has written down becomes wrong.
Why does my editor reject 00:01:00;00 as an invalid timecode?
Because in drop-frame that label genuinely does not exist. The rule skips frame numbers 00 and 01 at the start of every minute whose number is not a multiple of ten, so minute one begins at 00:01:00;02. The labels 00:01:00;00 and 00:01:00;01 are never issued to any frame, and an editor that accepted them would have to invent a frame to attach them to. The same holds at minutes 2 through 9, 11 through 19, and so on — 54 minutes an hour, two labels each, 108 labels an hour that simply are not part of the counting system. Minutes 0, 10, 20, 30, 40 and 50 are exempt, so 00:10:00;00 is perfectly valid and so is 00:00:00;00. If a script or spreadsheet is generating timecode values arithmetically and feeding them to an editor, this is the failure it will hit, and the fix is to convert through frame numbers rather than manipulating the string: compute the frame index, apply the closed-form conversion, and format the result. Generating labels by incrementing text fields will produce values that no drop-frame frame carries.
How many frames is a 30-second spot at 29.97?
It depends on whether the thirty seconds are clock seconds or timecode seconds, and confusing the two is how spots get rejected. Thirty seconds of real time at 29.97 is 30 × 30000 ÷ 1001 = 899.101 frames, so the longest whole-frame cut that fits inside thirty seconds is 899 frames, lasting 29.9966 seconds. Thirty seconds of timecode labels — a duration written 00:00:30;00 — is 900 frames, because minute zero drops nothing, and 900 frames actually last 900 × 1001 ÷ 30,000 = 30.03 seconds. That is 30 milliseconds over, which many broadcast specifications will fail. The safe habit is to deliver against a frame count agreed in writing rather than a duration in seconds, and 899 frames is the conventional answer for a thirty-second spot at 29.97. The same care applies at other lengths: a 60-second spot is 1798 frames rather than 1800, and a 15-second spot is 449 rather than 450. If a delivery spec states seconds, ask whether it means clock time or timecode duration before rendering, because the two differ by exactly one frame per thirty seconds and no amount of re-exporting will reconcile them.
Why does my audio drift out of sync over a long clip?
Almost always a 1000/1001 mismatch somewhere in the chain. If picture is being played at 23.976 while audio was recorded assuming 24, or picture is at 29.97 while a timeline believes 30, the two run at ratios differing by that factor and separate at a predictable rate: one frame roughly every 33 seconds, six seconds over a hundred-minute reel. The signature is unmistakable — sync is perfect at the head, visibly wrong at the tail, and the error grows linearly, which distinguishes it from a fixed offset caused by a mislabelled start point. The fix is to conform the audio explicitly with a pull-up or pull-down of 1000/1001 rather than nudging clips by hand, because a manual offset corrects one point and leaves the slope intact. Two related causes are worth checking before reaching for pulldown. Material transferred from a 25 fps origin will run 4.1667 percent fast or slow, a far larger and faster divergence, about one frame every 24 frames. And recorders whose clocks are not locked to a common reference drift on their own, typically a few frames an hour, which no arithmetic fix will repair — that one is solved by feeding the same word clock or timecode reference to every device before the take.

Articles you may find interesting

All guides
ExplainerHow Big Is That Audio File?Uncompressed audio size is exact arithmetic: sample rate × bit depth × channels × seconds ÷ 8. CD audio is 176,400 bytes per second. A 320 kbps MP3, by contrast, is bitrate × duration and does not depend on the sample rate at all — 2,400,000 bytes a minute whether it came from 44.1 or 48 kHz.ExplainerScreen Resolution, Pixel Density, and the Numbers Marketing UsesA diagonal plus an aspect ratio gives you width and height by Pythagoras, and the answer is not what the marketing implies: a 27-inch 21:9 has 16.2% less area than a 27-inch 16:9. Then pixels per degree, which shows the highest-PPI phone is not the sharpest thing you own.ExplainerCrop Factor: What It Changes and What It Does NotCrop factor is a ratio of sensor diagonals. It changes framing, not the lens — proved by computing field of view both ways — and it applies to the f-number as well as the focal length, which is the half most articles leave out.ExplainerDepth of Field: What Actually Controls ItFour variables set depth of field, and subject distance dominates the other three. The exact formulas, a computed table, why the circle of confusion is a decision rather than a measurement, and what "full frame has less depth of field" really means.ExplainerWhat an Availability Percentage Actually AllowsThree nines sounds like a promise until you divide it into minutes. What 99.9 % buys per year, per month, per week and per day; why the measurement window matters far more than the extra nine; and the two different months this tool uses for the same slug.ExplainerThe Golden Hour and the Blue Hour Are Angles, Not HoursGolden hour runs from +6° to −4° of solar elevation and blue hour from −4° to −6°, which is why it lasts forty minutes at the equator, over an hour at mid-latitudes, and above 72.6° in June does not happen at all. The thresholds this calculator uses, checked against its own output.

Related tools

Sources

Spotted a mistake in this article?