CNC M Codes — Machine Functions in G-Code Programs

M codes control machine functions that happen outside of axis movement — starting the spindle, turning on coolant, calling a tool change, or ending the program. While G codes define geometry and motion, M codes handle everything else the machine needs to do.

Most M codes are standardized across controllers, but some are manufacturer-specific. This guide covers the most common M codes for CNC milling, with notes on controller differences where they matter.

Program Control

M00 — Program Stop

Pauses the program and waits for the operator to press Cycle Start to continue. The spindle stops, coolant stops, and the feed hold lamp activates.

Use M00 when you need to measure, flip the part, or inspect a feature mid-program.

G1 X100. F400
M00              (stop here — operator checks dimension)
G1 X0. F400      (continues when operator presses Cycle Start)

M01 — Optional Stop

Behaves like M00, but only activates when the Optional Stop button on the control panel is turned on. If Optional Stop is off, M01 is ignored and the program continues.

Use M01 at inspection points during development — turn it on when testing the program, off when running production.

M02 — Program End (legacy)

Marks the end of the program. On most modern controls, M30 is preferred.

M30 — Program End and Rewind

Ends the program, stops the spindle, turns off coolant, and rewinds to the beginning of the program so it is ready to run again. This is the standard way to end a milling program.

G28 G91 Z0.
G28 X0. Y0.
M30

M99 — Return from Subprogram

Returns execution to the main program after a subprogram (called with M98) completes. Also used to create infinite loops when placed at the end of the main program.

Spindle Control

M03 — Spindle On, Clockwise

Starts the spindle in the forward direction at the speed set by the S word. Standard for right-hand cutting tools.

S5000 M3     (5000 RPM, clockwise)

M04 — Spindle On, Counterclockwise

Starts the spindle in reverse. Used for left-hand tools, some boring operations, or when the G84 tapping cycle reverses the spindle internally.

M05 — Spindle Stop

Stops the spindle without ending the program. Use before tool changes, probing, or any operation where spindle rotation is unsafe.

M9    (coolant off)
M5    (spindle stop)
G28 G91 Z0.

M19 — Spindle Orient

Stops the spindle at a specific angular position. Required before some boring cycles and for oriented tool changes on certain machines.

Coolant Control

M08 — Coolant On (Flood)

Activates flood coolant. Program M08 after positioning above the part and before the first cut.

M09 — Coolant Off

Turns off all coolant. Program M09 before spindle stop and tool change.

M07 — Mist Coolant On

Activates mist coolant where available. Not supported on all machines.

M50, M51 — Coolant Through Spindle (machine-specific)

Some machining centers route coolant through the spindle and tool. The exact M code varies by machine — check your controller manual. On Haas machines, M08 can activate through-spindle coolant if configured.

T1 M6
G0 G54 X0. Y0. S8000 M3
G43 H1 Z50.
M08              (flood coolant)

Tool Change

M06 — Tool Change

Commands the automatic tool changer to exchange the current tool for the tool number specified by the preceding T word.

T3 M6     (exchange current tool for tool 3)

The T word and M06 can appear on the same line or on separate lines depending on the controller. On Fanuc, it is common to call T on the previous line (pre-select) so the carousel is ready:

T3            (pre-select tool 3)
...           (cutting with current tool)
T3 M6         (execute tool change to tool 3)

On Haas, T and M06 on the same line is standard.

Subprogram Call

M98 — Call Subprogram

Jumps to a subprogram and executes it. The P word specifies the subprogram number, and L (or repeating P format) specifies the number of repetitions.

M98 P2000       (call subprogram O2000 once)
M98 P2000 L4    (call subprogram O2000 four times)

M99 — Return / End of Subprogram

Returns to the main program from the subprogram. Placed at the end of every subprogram.

Controller-Specific M Codes

M codes above M30 are manufacturer-defined. Common examples:

CodeFanucHaas
M30Program end + rewindProgram end + rewind
M48Feed/speed override enableFeed/speed override enable
M49Feed/speed override disableFeed/speed override disable
M97Local subprogram call
M98Subprogram callSubprogram call
M109Interactive input (Haas)User message + input

Always verify controller-specific M codes in your machine manual before using them in a new program — the same number can mean different things on different machines.

M Code Sequencing

Some M codes cannot appear on the same line as axis moves. Others must appear in a specific order. General rules:

  • M03/M04 (spindle on) should appear before any cutting moves
  • M08 (coolant) should appear after spindle start
  • M09 (coolant off) and M05 (spindle stop) should appear before G28 (home)
  • M06 (tool change) requires the spindle to be stopped

A safe end-of-tool sequence:

G0 Z50.         (retract to safe height)
M9              (coolant off)
M5              (spindle stop)
G28 G91 Z0.     (Z to home)
T2 M6           (tool change)

Verify M Code Behavior in Simulation

M code behavior is controller-specific, and the wrong M code in the wrong place can leave coolant running during a tool change, start the spindle before the tool is clamped, or skip a critical stop. Eureka3X simulates M code behavior as your controller interprets it — not as a generic approximation — so you can verify program flow before running on the machine.

Try Eureka3X free for 30 days →

Related Articles

Start verifying your real G-code today.

Ensure your programs are safe and accurate with Eureka 3X Pro.

Start 30-Day Free Trial