A canned cycle packs a whole drilling, tapping or boring move into one line and repeats it at every new X/Y position until G80 (or any other motion code such as G00 or G01) cancels it. The common ones: G81 drill, G82 drill with a dwell, G83 peck drill (Q = peck depth, retracting to R between pecks), G73 high-speed peck that breaks the chip with a short retract, G84 right-hand tap and G74 left-hand tap (feed = rpm × pitch, e.g. 900 rpm ÷ 16 TPI = 56.25 in/min), G85, G86 and G89 boring. R is the retract plane, Z the hole bottom, P a dwell in seconds, and G98 / G99 choose whether Z returns to the start height or to R between holes. The same numbers mean different things on different controls: G76 is fine boring on a Haas mill but threading on LinuxCNC and Haas lathes, and Grbl has no canned cycles at all. Formats below are from Haas's mill manual and the LinuxCNC documentation; try the Drilling cycles preset in the G-code Explainer & Simulator to watch one run.
Which cycle is which, by controller
| Code | Haas mill | LinuxCNC | Haas lathe |
|---|---|---|---|
| G73 | High-speed peck drilling | Drilling with chip breaking | Irregular path stock removal |
| G74 | Reverse (left-hand) tap | Left-hand tapping, dwell | End face grooving |
| G76 | Fine boring | Threading (multi-pass) | Threading, multiple pass |
| G77 | Back boring | not listed | not listed |
| G80 | Cancel canned cycle | Cancel canned cycle | Cancel canned cycle |
| G81 | Drill | Drilling | Drill |
| G82 | Spot drill (dwell) | Drilling, dwell | Spot drill |
| G83 | Normal peck drilling | Peck drilling | Normal peck drilling |
| G84 | Tapping (right-hand) | Right-hand tapping, dwell | Tapping |
| G85 | Boring (feed in, feed out) | Boring, feed out | Boring |
| G86 | Bore and stop | Boring, spindle stop, rapid out | Bore and stop |
| G87 | not listed | Back boring (unimplemented) | not listed |
| G88 | not listed | Boring, manual out (unimplemented) | not listed |
| G89 | Bore in, dwell, bore out | Boring, dwell, feed out | Bore and dwell |
| G98 | Initial point return | Retract to original Z | Feed per minute |
| G99 | R plane return | Retract to R | Feed per revolution |
The address words
| Word | Meaning in a canned cycle | Unit |
|---|---|---|
| X Y | Hole position. A new X/Y line repeats the active cycle there. | in or mm (G20 / G21) |
| Z | Hole bottom (Haas: "position of the Z axis at the bottom of hole"). | in or mm |
| R | Retract (R) plane, where feeding starts; usually just above the part. LinuxCNC: R is always sticky and it is an error if R is below Z. | in or mm |
| F | Feed rate. For tapping it must equal rpm × pitch. | in/min or mm/min |
| Q | Peck depth for G73/G83 (and optional pecking in Haas G74/G84), always incremental and positive. Haas G76/G77: the tool shift before retracting. | in or mm |
| P | Dwell at the bottom (G82, G86, G89, LinuxCNC G74/G84; Haas G73/G76/G83/G89). | seconds (s) |
| L | Number of repeats. Used in G91 incremental mode to drill a row of equally spaced holes. LinuxCNC: L0 is not allowed and L is not sticky. | count |
| I J K | Haas G73/G83 only: first peck depth, reduction per peck, minimum peck (use instead of Q). Haas G76/G77: X/Y shift if Q is not given. | in or mm |
| E | Haas G81/G82/G83/G84: chip-clean rpm (the spindle reverses to throw chips after each cycle). | rpm |
| J | Haas G74/G84: retract multiple (J2 retracts twice as fast as the cutting speed). | ratio |
| S | Spindle speed; Haas G84 accepts S in the cycle block. | rpm |
Every cycle, step by step
- Haas mill
G81 X Y Z R F [L] [E]- LinuxCNC
G81 X Y Z R [L]
Rapid to X/Y, rapid to R, feed to Z, rapid out to the return height (initial Z with G98, R with G99).
Haas: "used for drilling shallow holes or for drilling with Through Spindle Coolant".
- Haas mill
G82 X Y Z R P F [L] [E]- LinuxCNC
G82 X Y Z R P [L]
As G81, but dwells for P seconds at the bottom before rapiding out. Haas calls it the spot drill cycle.
LinuxCNC example: G90 G82 G98 X4 Y5 Z1.5 R2.8 P2 dwells 2 s.
- Haas mill
G83 X Y Z R Q For… I J K F[P] [L] [E]- LinuxCNC
G83 X Y Z R Q [L]
Feed down by Q, rapid out to R to clear chips, rapid back down to just above the previous depth, repeat until Z, then rapid out.
LinuxCNC re-enters to 0.010 in (0.254 mm) above the last depth. Haas Setting 52 lets the chip-clearing move rise above R so R can sit closer to the part. Haas: P pauses at the end of the last peck; do not use Q with I/J/K.
- Haas mill
G73 X Y Z R Q For… I J K F[P] [L]- LinuxCNC
G73 X Y Z R Q [L]
Feed down by Q, back off a short distance to break the chip, repeat until Z, then rapid out.
LinuxCNC backs off 0.010 in (0.254 mm). Haas sets the back-off with Setting 22 (Can Cycle Delta Z). With K and Q both given, Haas returns to R after the pecks total K.
- Haas mill
G84 X Y Z R F [S] [J] [Q] [L] [E]- LinuxCNC
G84 X Y Z R P F [L] [$]
Feed in at F = rpm × pitch, reverse the spindle at the bottom, feed out.
Haas: no M03 needed, the cycle starts and stops the spindle. LinuxCNC: the move is not synchronised to the spindle, so use a floating tap holder; overrides are disabled during the cycle; P dwells at the bottom after the spindle reverses. LinuxCNC's rigid tap is G33.1.
- Haas mill
G74 X Y Z R F [J] [Q] [L]- LinuxCNC
G74 X Y Z R P F [L] [$]
As G84 with the spindle directions swapped: for left-hand threads.
On a Haas lathe G74 is the end-face grooving cycle; Haas lathes tap left-hand threads with G184.
- Haas mill
G85 X Y Z R F [L]- LinuxCNC
G85 X Y Z R [L]
Feed to Z and feed back out to R at the feed rate (no dwell). LinuxCNC: intended for boring or reaming.
LinuxCNC then rapids from R to the clear height if G98 is in effect.
- Haas mill
G86 X Y Z R F [L]- LinuxCNC
G86 X Y Z R P [L] [$]
Feed to Z, stop the spindle, rapid out, restart the spindle.
LinuxCNC dwells P seconds first and gives an error if the spindle is not turning.
- Haas mill
G89 X Y Z R P F [L]- LinuxCNC
G89 X Y Z R P [L]
Feed to Z, dwell P seconds, feed back out at the feed rate.
- Haas mill
G76 X Y Z R Q F [P] [L]or… I J …- LinuxCNC
G76 P Z I J R K Q H E L [$](threading)
Haas mill: bore to Z, shift the tool away from the wall by Q (direction from Setting 27) or by I/J, then retract so the tool does not mark the bore.
On LinuxCNC (and Haas lathes) G76 is a multi-pass threading cycle with completely different words: a G76 written for a Haas mill must not run on LinuxCNC.
- Haas mill
G77 X Y Z R Q F [L]or… I J …- LinuxCNC
- not listed
Shift off-centre to clear the hole, go down through it to R, shift back by Q, feed up to Z, then shift toward the centre and retract: it cuts a counterbore on the far side of the part.
Haas: R is negative and must go past the bottom of the part.
- Haas mill
G80- LinuxCNC
G80
Ends the cycle. Any other group-1 motion code (G00, G01, G02, G03) also cancels it.
LinuxCNC gives an error if axis words follow G80 without a motion code.
Tapping feed: F = spindle speed × pitch
| Example | Spindle speed (rpm) | Thread pitch | Feed F |
|---|---|---|---|
| Haas G84, 3/8-16 tap | 900 | 16 TPI = 0.0625 in/rev | 900 ÷ 16 = 56.25 in/min |
| LinuxCNC G84 / G74 | 100 | 1.25 mm/rev | 100 × 1.25 = 125 mm/min |
Controller differences that cause crashes
- Spindle direction (Haas). Unless told otherwise, G81, G82, G76, G77, G86 and G89 use the last spindle direction (M03, M04 or M05); with none given they assume M03. After an M05 they run as a "no-spin" cycle, which Haas warns can cause a crash.
- P is modal (Haas). A G04 Pnn or M97 Pnn inside an active cycle also changes the cycle's dwell P.
- Return plane (LinuxCNC). G98 returns to the Z held before the first cycle only if it is above R; otherwise to R. Switching from one cycle to another (G81 to G83) does not reset that height, but G80 or any non-cycle motion code does. In G83, every retract before the final depth goes to R even in G98.
- LinuxCNC errors. It refuses a cycle when R is below Z, cutter radius compensation is on, inverse-time feed (G93) is active, or a rotary axis is in the block. Z is sticky: later lines may omit it while the same cycle stays active.
- Incremental mode. In G91 with L, Haas and LinuxCNC repeat the cycle L times, each time shifted by X/Y, to drill a row of holes. On LinuxCNC, X, Y and R are then increments from the current position and Z is measured from the R height.
- Tapping. LinuxCNC G84/G74 are unsynchronised (floating holder needed) and rigid tapping is
G33.1 X Y Z K(K = pitch per revolution, I = optional faster-return multiplier). Haas lathes list live-tool rigid taps as G95 and G186. - Grbl and Marlin. Grbl 1.1 has no canned cycles: G81–G89 return error:20, and only G80 is accepted. Marlin 3D-printer firmware has none either; there G80 cancels the motion mode (with GCODE_MOTION_MODES) and G76 is probe temperature calibration. Have the CAM software expand the cycle into G0/G1 moves for these controls.
- When to peck. Haas advises peck cycles for holes deeper than 3 times the drill diameter, and a first peck (I) of about one tool diameter.
Example: G98 vs G99 around a clamp (Haas)
% O69899 (G98/G99 INITIAL POINT & R PLANE RETURN) ; (G54 X0 Y0 is top right corner of part) ; (Z0 is on top of the part) ; (T1 is a drill) ; T1 M06 (Select tool 1) ; G00 G90 G17 G40 G49 G54 (Safe startup) ; G00 G54 X1. Y-0.5 (Rapid to 1st position) ; S1000 M03 (Spindle on CW) ; G43 H01 Z2. (Tool offset 1 on) ; M08 (Coolant on) ; G81 G99 X1. Z-0.5 F10. R0.1 (Begin G81 using G99) ; G98 X2. (2nd hole and then clear clamp with G98) ; X4. (Drill 3rd hole) ; G00 Z2. M09 (Rapid retract, Coolant off) ; G53 G49 Z0 M05 (Z home, Spindle off) ; G53 Y0 (Y home) ; M30 (End program) ; %
Haas's own program (inch units; preparation and completion comment lines trimmed). The first hole returns only to R0.1 (G99) because the path to the second hole is clear; G98 on the second hole sends Z back to the initial Z2. so the drill clears the clamp on the way to X4. The final G00 cancels the cycle. Paste it into the simulator with the Haas dialect to see the two return heights; the Unit Converter turns the inch values into millimetres.
Sources
- Haas Automation, Mill Operator's Manual — 17: Mill G-Codes (canned-cycle introduction, R planes) and the Haas mill code pages for G73, G74, G76, G77, G80, G81, G82, G83, G84, G85, G86, G89, G98 and G99 (haascnc.com/service/codes-settings…), plus Lathe Operator's Manual — Lathe G-Codes for the lathe column. haascnc.com blocks automated downloads, so the pages were read from Internet Archive copies captured between October 2021 and August 2025 (web.archive.org). Used for: Haas formats, words, behaviour, the G84 and G98/G99 example programs, and the lathe meanings.
- LinuxCNC Project, G-Codes, sections G33.1, G73, G74, G76, G80–G89 and G98/G99 (linuxcnc.org/docs/html/gcode/g-code.html, last updated 13 September 2026). Used for: LinuxCNC formats, sticky words, errors, the 0.010 in (0.254 mm) peck retract, the S100 × 1.25 = F125 tapping example and the unimplemented G87/G88.
- gnea/grbl, Grbl 1.1h source grbl/gcode.c ("Not supported: Canned cycles"), 2019; MarlinFirmware, Marlin G-code index pages G076 and G080 (github.com/MarlinFirmware/MarlinDocumentation), downloaded 6 October 2026.
- All sources were read on 6 October 2026. Fanuc's manuals are not freely published; "Haas mill" behaviour is Haas's own and may differ on other Fanuc-style controls.
Frequently asked questions
What is the difference between G81 and G83?
G81 drills to Z in one feed move and rapids out. G83 is peck drilling: it feeds in by the peck depth Q, rapids back out to the R plane to clear chips, rapids back down to just above the last depth (0.010 in / 0.254 mm above on LinuxCNC) and repeats until Z. Haas recommends peck cycles for holes deeper than 3 times the drill diameter.
What do G98 and G99 do in a canned cycle?
They set where Z returns between holes. G98 returns to the initial Z (the height before the cycle started), so the tool can clear clamps; G99 returns only to the R plane, which is faster when nothing is in the way. On LinuxCNC, G98 uses the initial Z only if it is above R. On Haas lathes, G98 and G99 are instead feed per minute and feed per revolution.
How do I calculate the feed rate for G84 tapping?
Feed = spindle speed × thread pitch. In inches, divide rpm by threads per inch: Haas's example taps 3/8-16 at S900, so F = 900 ÷ 16 = 56.25 in/min. In millimetres multiply: LinuxCNC's example uses S100 with a 1.25 mm pitch, so F125 mm/min.
What does Q mean in G83 and G73?
Q is the peck depth, the distance fed in on each peck, always incremental and always positive. LinuxCNC gives an error if Q is zero or negative. On a Haas you can instead give I (first peck), J (reduction per peck) and K (minimum peck), but not together with Q in G83.
Is G76 a boring cycle or a threading cycle?
It depends on the control. On a Haas mill G76 is the fine boring cycle (it shifts the tool off the wall before retracting). On LinuxCNC and on Haas lathes G76 is the multi-pass threading cycle. In Marlin 3D-printer firmware it is probe temperature calibration. Check the manual of the machine the program will run on.