Difference between deregister job and stop=True?

A job was running, and now it is dead. Is there a difference between deregistering a job ( Jobs - HTTP API | Nomad | HashiCorp Developer ) and between: getting the job json, setting a job[“Stop”]=True and then registering the job?

So job/%s entrypoint is inside nomad/job_endpoint.go at main · hashicorp/nomad · GitHub and I am interested in jobUpdate and jobDelete.

Then using RPC request, the calls are forwarded to nomad/job_endpoint.go at main · hashicorp/nomad · GitHub to Register() or Deregister() functions.

Then the message is forwarded via raft.apply() to nomad/fsm.go at main · hashicorp/nomad · GitHub .

Then I see handleDeregisterJob() and handleUpsertJob() in nomad/fsm.go at main · hashicorp/nomad · GitHub .

It looks to me, from the comment in handleDeregisterJob() in nomad/fsm.go at main · hashicorp/nomad · GitHub stopping a job and deregistering is exactly the same:

// Get the current job and mark it as stopped and re-insert it.
		ws := memdb.NewWatchSet()
		current, err := n.state.JobByIDTxn(ws, namespace, jobID, tx)
		if err != nil {
			return fmt.Errorf("JobByID lookup failed: %w", err)

		if current == nil {
			return fmt.Errorf("job %q in namespace %q doesn't exist to be deregistered", jobID, namespace)

		stopped := current.Copy()
		stopped.Stop = true

		if err := n.state.UpsertJobTxn(index, stopped, tx); err != nil {
			return fmt.Errorf("UpsertJob failed: %w", err)

handleDeregisterJob() calls n.state.UpsertJobTxn, while handleUpsertJob() calls n.state.UpsertJob(). Reading the source code, Txn nomad/state_store.go at main · hashicorp/nomad · GitHub is a transaction, so it is used for synchronization.

Guessing from the comment and assuming that n.state.UpsertJobTxn does something exactly the same as n.state.UpsertJob(), I assume that both API calls are exactly the same (mind some edge cases with synchronization issues).