Basic Knowledge of M Codes for CNC Milling
This page covers the basic knowledge of M codes for CNC milling: which commands do what, how modal and non-modal behavior differs, and where machine builders deviate from the standard. It is written for engineers and buyers who read programs, review setups, or quote milling work. After reading it, you can tell whether a program's M code sequence is safe, portable, and worth running on a given machine.

What M Codes Actually Control
These commands switch machine functions on and off. The cutting path comes from G codes, but the spindle, coolant, tool changer, and doors answer to M codes.
M Codes vs G Codes: A Simple Split
G codes describe geometry. They tell the control where to move, at what feed, along which arc or line. The machine can follow that path perfectly and still cut nothing, because no spindle is turning and no coolant is flowing. The commands that start the spindle, open the coolant valve, and index the tool magazine sit in a separate family. Engineers often learn G code first and treat the other family as housekeeping. That habit causes scrapped parts and broken tools.
A clean way to think about it: G code is the drawing, M code is the machine state. The drawing says the tool should pass 0.5 mm below the top face. The machine state decides whether that pass happens with a spinning cutter or a stationary one dragging across the surface. When a program runs unexpectedly, the fault is often a missing or misplaced machine-state command rather than a wrong coordinate.
This split also explains why the same program can behave differently on two machines. G code geometry is standardized enough to move between controls with minor edits. Machine-state commands depend on how the builder wired the spindle, the coolant pump, the tool changer, and the safety circuit. Two mills from different builders can share almost all their G code and almost none of their uncommon M codes.
- 1Geometry vs stateG codes shape the path; M codes set spindle, coolant, and tool state.
- 2Independent faultsA correct path can still fail if the spindle or coolant command is wrong.
- 3Portability gapCommon commands travel between controls; uncommon ones usually do not.
The Commands You See in Almost Every Milling Program
A handful of commands appear in nearly every milling program. M03 starts the spindle clockwise, which is the normal direction for right-hand tooling. M04 runs it counterclockwise, used for left-hand taps and some back-facing operations. M05 stops the spindle. M08 turns flood coolant on and M09 turns it off. M06 calls a tool change, and M00 is a program stop that waits for the operator. These are the commands an engineer should recognize on sight before touching a control.
The spindle command usually carries an S word on the same block: M03 S8000. The control reads the speed and starts rotation. Direction matters more than most people expect. Running a right-hand end mill in reverse dulls the edge quickly and can pull the part out of the vise. On a rigid setup with a light cut it may survive a few seconds. On a deep pocket in stainless it will not.
Coolant commands look trivial until chips pile up. M08 flood coolant is the default for steel, stainless, and most aluminum roughing. M07, where available, selects mist coolant for light cuts and for materials that dislike thermal shock. Through-spindle coolant is usually a separate command, often M88 or a builder-specific code. If a deep hole program runs without through-tool coolant, chips pack in the flutes and the drill snaps.
Tool change commands are where programs get fragile. M06 alone tells the control to swap tools, but it does not guarantee the spindle is stopped, oriented, and clear of the part. A safe sequence stops the spindle, orients it, moves to a safe Z height, then calls the change. Controls that enforce this internally are forgiving. Older or lower-cost controls are not.
- 1SpindleM03 clockwise, M04 counterclockwise, M05 stop. Pair with an S word.
- 2CoolantM08 flood on, M09 off. Mist and through-tool codes vary by builder.
- 3Tool changeM06 indexes the tool. Stop and orient the spindle first.
- 4Program controlM00 stops and waits. M01 stops only when optional stop is active.
Modal and Non-Modal: Why State Lingers
Modal commands stay active until something cancels or replaces them. M03 is the classic example. Once the spindle starts clockwise, it keeps turning through every following block. It stops only when M05 appears or when M04 reverses it. M08 behaves the same way: coolant stays on until M09. This is convenient for long cuts and dangerous when programmers forget to cancel. A spindle left running into a rapid move is a crash waiting to happen.
Non-modal commands fire once and are done. M00, M01, and M06 belong to this group. They do not persist. The control executes the action in that block and moves on. Mixing the two types in one program is normal, but the sequence matters. Calling M06 while the spindle is still modal-active from M03 will trigger an alarm on most controls, because the tool changer cannot engage a spinning spindle.
The practical rule is simple. Before any tool change, cancel the spindle and coolant explicitly. Before a program end, cancel everything. Write M09 M05 before M06, and end with M30. Controls differ in how strictly they enforce this, but a program that states cancellations clearly will run on more machines. It also reads better when a colleague reviews the setup six months later.
Modal state also crosses subprogram boundaries. If a subprogram turns coolant on and returns without turning it off, the main program inherits that state. On a long run this can flood a dry operation or leave a finishing pass without cooling. Naming the state at the start of each subprogram avoids the confusion.
- 1ModalM03, M04, M08 stay active until cancelled or replaced.
- 2Non-modalM00, M01, M06 act once in the block where they appear.
- 3Safe habitCancel spindle and coolant before every tool change.
- 4SubprogramsState carries across calls. Set it explicitly at each entry.
Common Milling M Codes at a Glance
Standard meanings for the commands most programs use. Confirm uncommon codes in the machine manual before running.
| Code | Function | Modal? | Notes |
|---|---|---|---|
| M00 | Program stop | No | Spindle and coolant stop; waits for operator |
| M01 | Optional stop | No | Active only when the panel switch is on |
| M03 | Spindle clockwise | Yes | Needs an S word on the same block |
| M04 | Spindle counterclockwise | Yes | For left-hand taps and back-facing |
| M05 | Spindle stop | Yes | Cancels M03 or M04 |
| M06 | Tool change | No | Stop and orient the spindle first |
| M08 | Flood coolant on | Yes | Default for steel and stainless |
| M09 | Coolant off | Yes | Cancels M07 and M08 |
| M19 | Spindle orientation | Yes | Often required before M06 |
| M30 | Program end and rewind | No | Returns control to the start |
| M98 | Subprogram call | No | Used with M99 to return |
| M99 | Subprogram return | No | Ends the called subprogram |
Where Machines Disagree With the Standard
The codes above are widely shared, but the standard stops there. Builders reuse the same numbers for different functions all the time. M10 clamps a rotary axis on one mill and opens a chuck on another. M51 might drive a pallet changer or a probe arm depending on the builder. If you copy a program from a forum or an older job and run it without checking, you are trusting a stranger's machine configuration.
Safety interlocks are the second area of divergence. Some machines require an explicit command to confirm the door is closed before a cycle starts. Others tie the door to the spindle and ignore program commands entirely. A program that ran unattended on one mill may refuse to start on another because the control wants a confirmation code it never receives. Neither machine is wrong. They were wired to different safety philosophies.
The only authority is the programming manual shipped with the machine. Read the M code list before the first setup, not after the first alarm. For high-value five-axis work, this is not optional. A mistaken M code on a five-axis machine can rotate a trunnion into the spindle or drive a pallet into a fixture. The cost of that mistake is measured in weeks of downtime, not minutes.
When we program a job at GreatLight, the post processor is mapped to each machine's manual, not to a generic code list. Uncommon codes are tested on a scrap blank before they touch a production part. That step adds a few minutes per setup and removes a whole class of surprises.
- 1Builder reuseSame number, different function. Check the manual for each machine.
- 2Safety circuitsDoor and interlock commands vary. Some are enforced, some ignored.
- 3Five-axis riskA wrong code can drive a rotary axis into the spindle.
- 4Our practicePost processors follow each machine manual; new codes are dry-run first.
When a Program Should Not Be Moved Between Machines
A program with only M03, M05, M08, M09, and M06 is fairly portable. Those commands behave the same on most vertical mills. If the tolerances are open and the material is forgiving, moving that program to another mill is usually a matter of re-posting for the control and checking the work offsets. It is a reasonable shortcut for a one-off job.
A program becomes machine-specific as soon as it uses uncommon codes, through-spindle coolant, pallet changers, probing, or bar feeders. Each of those functions is wired and interpreted differently. A job with a Ø400 mm rotary table and a trunnion is not portable at all, because the safe positions depend on the exact machine envelope. Moving that program means re-verifying every retract and every rotary move.
Material choice pushes the same decision. A roughing pass in 6061 aluminum tolerates a loosely ordered sequence. The same sequence in Inconel or Ti-6Al-4V does not, because coolant failure for a few seconds damages the tool and the surface. On hard or gummy materials, explicit coolant control around every cut is worth the extra program lines.
The honest answer for most shops is a middle path. Keep a portable core of common commands for simple work, and treat anything with special functions as belonging to one machine until proven otherwise. That habit costs little and prevents the expensive failure mode: a program that ran fine yesterday and crashes today because it moved to a different control.
- 1PortableCommon spindle and coolant codes on simple 3-axis work.
- 2Machine-boundPallet changers, probing, through-tool coolant, rotary trunnions.
- 3Material mattersDifficult alloys punish loose coolant and sequence control.
Common Questions About M Codes
Do I need to cancel the spindle before a tool change?
Yes. Write M05 before M06, and add M19 if the control expects spindle orientation. A tool changer cannot engage a spinning spindle, so most controls raise an alarm or, worse, fault mid-change.
Some controls insert the stop and orient automatically. Others rely on the program. Stating M05 M19 M06 explicitly is safe on both, and it makes the intent readable during setup review.
Why does the same program alarm on a different machine?
Uncommon codes are builder-specific. A number that drives a pallet changer on one mill may mean something else entirely on another, or be undefined. The control then raises an alarm rather than guessing.
Check the machine's M code list and compare it line by line with the program. Common codes usually match; anything outside the core set needs confirmation.
What is the difference between M00 and M01?
M00 stops the program unconditionally and waits for the operator to resume. M01 stops only when the optional stop switch on the panel is active. Both are non-modal.
M01 is useful for mid-run inspection without editing the program. Leave it in, and the operator decides whether the stop happens.
Is M08 always flood coolant?
On most vertical mills, yes. Mist is often M07 where the builder supports it, and through-spindle coolant is usually a separate code such as M88. The exact assignment depends on the machine.
Confirm in the manual before relying on a coolant code in a deep-hole or hard-material program, where coolant failure damages the tool quickly.
Can I leave the spindle running between operations?
Technically yes, because M03 is modal and stays active. Practically, it is a bad habit. A spindle left running into a rapid move or a fixture approach turns a positioning error into a crash.
Cancel the spindle at the end of each operation unless the next block genuinely continues the same cut.
How do M codes relate to machine safety?
They interact with the safety circuit on many machines. Door interlocks, chuck clamps, and rotary locks may require a confirmation command before a cycle starts, and the codes differ by builder.
Treat any program that overrides or bypasses a safety function as suspect. Verify with the machine manual and the shop's safety procedure before running it.
Send Us Your Drawing and We Will Quote the Milling Work
We review the geometry, the material, and the machine setup, then send a quotation with free DFM analysis within 12 hours. Uploads stay secure and confidential, and an NDA is available on request.
12-hour quote100% inspectionNo minimum order quantityNDA on request