---
title: "G92 vs G54: Coordinate Shift vs Work Offsets"
description: "G54 stores part zero in a table; G92 declares it from wherever the tool stands. Why shops run on offsets, printers run on G92, and how to defuse legacy code."
url: https://gcodepractice.com/journal/g92-coordinate-shift-vs-g54-work-offsets/
canonical: https://gcodepractice.com/journal/g92-coordinate-shift-vs-g54-work-offsets/
author: "Lawrence Arya"
authorUrl: https://www.linkedin.com/in/vibecoding/
published: 2026-08-10
updated: 2026-08-10
category: "Code reference"
tags: ["g-code", "g92", "g54", "work-offsets", "3d-printing", "setup"]
lang: en
---

# G92 vs G54: Coordinate Shift vs Work Offsets

> **TL;DR** G54 selects a stored work offset, measured at setup, visible in the table, and independent of program history; it is the modern default. G92 declares the tool's current position to be the stated coordinates, shifting the whole coordinate system invisibly and history-dependently, which makes restarts hazardous, so it survives mainly in legacy mill code and in 3D printing, where G92 E0 zeroes the extruder as routine housekeeping. Clear stuck shifts with G92.1 or your control's documented method.

G92 and G54 both answer the same question, where is part zero, in opposite ways. G54 points to a stored offset: a number set during setup, saved in the control's offset table, active whenever the program selects it, and unchanged by anything the program does. G92 is a declaration made mid-program: it tells the control that the position the tool occupies right now shall be called whatever coordinates the line states, and the control shifts its entire coordinate world to make that true. The stored offset is deliberate, visible, and repeatable; the declaration is fast, invisible afterwards, and depends entirely on where the tool happened to be standing when it executed. Modern mill and lathe practice runs on G54-style offsets and treats G92 as a legacy tool with sharp edges, while 3D printers and some hobby setups still lean on G92 daily, which is exactly why the pair confuses people moving between those worlds.

## What G54 does: zero as a stored fact

A work offset is a measured fact about the setup, recorded once: the distance from the machine's home position to the part zero you chose. Setup finds that point, by edge finder, probe, or indicator, and stores it under G54; the program then simply says G54 and every coordinate that follows is interpreted relative to that stored zero. Six such offsets, G54 through G59, come standard on Fanuc-style controls, with extended sets beyond them, and the full mechanics are covered in [G54 work offsets explained](/journal/g54-work-offsets-explained/).

Three properties make stored offsets the professional default. They are visible: anyone can open the offset page and read exactly where every zero is, which makes setups auditable and handovers between shifts safe. They are independent of program flow: no matter what a program did, where it alarmed out, or how it was restarted, G54 means the same physical place tomorrow morning. And they are settable by code in a controlled way, through [G10 lines that write the offset table](/journal/how-to-use-g10-to-write-work-offsets-in-g-code/), which gives automation a clean route to adjust zeros without any of G92's history dependence. The [LinuxCNC G-code reference](https://linuxcnc.org/docs/html/gcode/g-code.html) documents the same architecture: G54 through G59.3 select stored systems, G10 writes them.

## What G92 does: zero as a declaration

G92 X0 Y0 Z1.0 says: from now on, call this current tool position X0 Y0 Z1.0. The control computes the offset needed to make that sentence true and applies it on top of everything else. No axis moves, nothing on the screen flashes. The line is over in a millisecond, and the entire coordinate system has silently shifted underneath every program on the machine.

The property that makes G92 dangerous in a machine shop is history dependence: the resulting coordinate system depends on where the tool actually was at execution. Run the same G92 line with the tool an inch to the left, and every zero lands an inch to the left, with nothing on the offset page to warn anyone. A program interrupted and restarted in the middle can execute its G92 from an unplanned position and relocate the whole job; the restart hazards described in [how to safely restart a program from the middle](/journal/how-to-safely-restart-a-cnc-program-from-the-middle/) get an extra chapter on machines where G92 is in play. Worse, on many controls the G92 shift persists after the program ends and even across resets, quietly offsetting the next program, until something clears it: G92.1 resets the shift on controls that follow the [LinuxCNC-style definitions](https://linuxcnc.org/docs/html/gcode/g-code.html), while Fanuc-family machines clear it via a fresh G92, specific resets, or power cycling depending on parameters.

G92 also has an unrelated namesake to defuse: on Fanuc lathes, G92 is a threading cycle, one box of an entirely different toolset, compared against its sibling in [G92 versus G76 threading](/journal/g92-vs-g76-threading-lathe-differences/). Same two characters; whether it shifts coordinates or cuts threads depends on machine type and context, one more entry in the mill-versus-lathe dialect list.

## Why 3D printers still run on G92

The place most people actually meet G92 today is additive. Printer firmware descends from [the RepRap G-code dialect](https://reprap.org/wiki/G-code), where G92 E0 appears before nearly every travel move: it zeroes the extruder axis so the next extrusion distance is expressed from zero rather than as an ever-growing total. Printers also use G92 for on-the-fly Z adjustments and for setups without reliable homing. The pattern works there because a printer's job runs start-to-finish from a known homing state, nobody restarts a print from line 40,000, and the axes being redefined move plastic rather than carbide toward fixtures.

That difference in context is the honest answer to why the same code is routine in one world and semi-banned in the other. A machinist moving to printers should read G92 E0 as normal housekeeping, not an alarm; a printer person moving to mills should learn the stored-offset workflow before touching a vise, a transition mapped in [how to set work zero on a CNC versus a 3D printer](/journal/how-to-set-work-zero-on-a-cnc-vs-3d-printer/) and in [what G54 means in 3D printing](/journal/what-is-g54-in-3d-printing/).

## The comparison, condensed

| | G54-style stored offset | G92-style position declaration |
| --- | --- | --- |
| Zero is defined by | A measured value in the offset table | Wherever the tool stood when the line ran |
| Visible afterwards | Yes, on the offset page | Often only as a hidden shift |
| Depends on program history | No | Completely |
| Survives interruption safely | Yes | No, restarts can relocate everything |
| Cleared by | Editing the table | G92.1, control-specific resets, or overwrite |
| Modern shop usage | Default for all setups | Legacy, special cases only |
| Printer/hobby usage | Rare | Routine, especially G92 E0 |

The historical note explains the table's shape: G92 predates cheap memory. Early NC controls could not store banks of offsets, so programs declared their own zero from a known tool position, often after a reference return. Stored offsets made that workaround obsolete on industrial machines decades ago, but the code remains implemented everywhere, teaching materials still mention it, and old programs still contain it, which is precisely why it must be understood even by people who will never write it.

A pair of tiny examples shows the mechanism difference at the coordinate level. Suppose machine home is at machine X-20.0 Y-10.0 relative to your intended part zero. The stored-offset route records that fact once, in the table, as the G54 entry; the program is then just:

```
G54 G90
G00 X0 Y0 (arrives at part zero, from anywhere)
```

The declaration route has to get the tool to a known point first and then declare:

```
G28 X0 Y0 (go to reference position)
G92 X20.0 Y10.0 (call this point X20 Y10, implying part zero 20,10 away)
G90 G00 X0 Y0
```

Both arrive at the same physical place on a good day. The difference is everything around a bad day: the G54 version contains no step that can silently go wrong, while the G92 version depends on the reference return actually happening, on nobody jogging between the two lines, and on the declared numbers matching a setup that may have changed since the program was written. Multiply that fragility by every program on the machine and the industry's verdict makes itself.

## Reading and defusing G92 in the wild

Inherited programs are where this knowledge pays. A G92 near the top of an old mill program, typically right after a return-to-reference like [G28](/journal/g28-return-to-home-position-explained/), is the legacy zero-setting idiom: the program went home, then declared the home position's coordinates, establishing the whole job's frame from the machine's reference point. Converting such a program to modern practice means measuring the intended part zero, storing it as G54, and deleting the G92 lines, after which the program becomes restartable and the setup becomes visible.

When a machine behaves as if its zeros drifted, all programs suddenly offset by the same amount, the diagnostic checklist starts with the possibility of a leftover G92 shift: check the control's position screens for an active coordinate shift entry (most controls display it separately from the work offsets), clear it with the control's method, and re-verify against a known reference. The symptom pattern, everything shifted equally and the offset table looks untouched, is the G92 signature, distinct from a crashed reference or a scrambled offset table where errors are uneven.

And in your own new work the guidance is short: on mills and lathes, do not write G92; use stored offsets, and use G10 when code needs to change them. The exceptions, temporary axis re-zeroing in special rigs, some rotary continuations, certain lathe conventions, are real but rare, and each is a deliberate engineering choice rather than a habit. On printers, keep using G92 E0 as the dialect intends.

## Bottom line: declare nothing, store everything

G54 makes part zero a stored, visible, history-independent fact; G92 makes it a declaration whose meaning depends on where the tool happened to be, persists invisibly, and turns program restarts into a gamble. Run shops on stored offsets, write offset changes through G10, and treat any G92 in inherited mill code as a candidate for modernization. Learn the printer idiom G92 E0 for what it is, sensible housekeeping in a different context, and remember the lathe's G92 threading cycle is an unrelated namesake. One question, where is zero, and the entire difference is whether the answer lives in a table or in a moment.

## Frequently asked questions

### What is the difference between G92 and G54?

G54 selects a stored work offset: a measured zero saved in the control's table during setup, visible, repeatable, and independent of what the program does. G92 declares that the tool's current position equals the coordinates on the line, shifting the whole coordinate system to make it true; the result depends on where the tool stood, persists invisibly, and can relocate everything if executed from an unplanned position. Modern machining uses G54-style offsets; G92 is the legacy approach.

### Why is G92 considered dangerous on a mill?

Because it is history-dependent and invisible. The shift it creates depends on the tool's actual position at execution, so an interrupted program restarted mid-stream can re-declare zero from the wrong place and offset the entire job, and on many controls the shift survives program end and reset, silently displacing the next program. Nothing appears in the offset table to warn anyone. Stored offsets have none of these behaviors, which is why they replaced G92 in industrial practice.

### What does G92 E0 mean in 3D printing?

It zeroes the extruder axis: the E value counts filament fed, and slicers reset it before travel moves so extrusion distances stay small and readable rather than accumulating. It is normal housekeeping in the RepRap dialect that printer firmware descends from, not a hazard, because a print runs start-to-finish from a homed state. The caution around G92 belongs to machine tools, where restarts, fixtures, and cutting forces change the stakes entirely.

### How do I clear a stuck G92 offset?

First confirm it: if every program is shifted by the same amount while the offset table reads correct, an active coordinate shift is the signature. On LinuxCNC and controls following its definitions, G92.1 clears the shift. On Fanuc-family machines, the method varies with parameters: a countering G92, a reset-and-rehome sequence, or power cycling. Check the control's position display for the shift entry, clear it by the documented method, then re-verify zero against a known reference before cutting.

### What is the best way to learn the offset and coordinate codes?

Drill them until the map is instant: G54-G59 stored offsets, G10 writes them, G92 declares, G92.1 clears, G28 references, and the lathe G92 threading namesake. A free app like G-Code Sprint quizzes exactly this family in short timed rounds and repeats the codes you miss, which builds the recall that prevents the classic accident, running someone else's G92 without recognizing what it is about to redefine.

## Sources

- [LinuxCNC G-code reference](https://linuxcnc.org/docs/html/gcode/g-code.html)
- [RepRap G-code dialect documentation](https://reprap.org/wiki/G-code)
- [CNC Cookbook: G-code program format and structure](https://www.cnccookbook.com/g-code-basics-program-format-structure-blocks/)

---

Source: https://gcodepractice.com/journal/g92-coordinate-shift-vs-g54-work-offsets/
Author: Lawrence Arya — https://www.linkedin.com/in/vibecoding/
