Helix Core is now P4. Product user interfaces will be updated soon. Learn more >>

P4 Server Administration Documentation | 2026.1

# Server extension callbacks

This section compares the function syntax of a server extension to the equivalent logic in a trigger.

### Example usage of a server extension compared to a trigger

Triggers | Server extension
--- | ---
    Triggers:
    name form-in change script.pl
    function InstanceConfigEvents()
        return { ["form-in"] = "change" }
    end
    function FormIn()
        ...
    end
    Triggers:
    ... change-submit //a/b/c/... script.sh
    ... change-submit //a/c/d/... script.sh
    ... change-submit -//a/d/e/... script.sh
    function InstanceConfigEvents()
        return { ["change-submit"] = { "//a/b/c/...", "//a/c/d/...", "-//a/d/e/..." } }
    end
    function ChangeSubmit()
        ...
    end

## Event Callbacks

The following table lists the P4 events that can cause a server extension to run. Instead of managing a trigger table, the server extensions use InstanceConfigFields() function to bind themselves to events.

In the following table,

- a form type can be: "branch", "change", "client", "depot", "group", "job", "label", "protect", "server", "spec", "stream", "triggers", "typemap", "user"

- server IDs might be similar to “build-123”, "commit1"

- a “pre-user-” and “post-user-” example might be similar to {“pre-user-obliterate”, “post-user-add”}

Event (same as trigger name) | Param | Method | Returns
--- | --- | --- | ---
archive | depot paths | Archive() | boolean
auth-check-sso | "auth" | AuthCheckSSO() | boolean
auth-invalidate | "auth" | AuthInvalidate() | boolean
auth-pre-sso | "auth" | AuthPreSSO() | boolean, optional string, optional boolean
auth-init-2fa | "auth" | MFABegin() | Helix.Core.Server.MFA.Status, Helix.Core.Server.MFA.Scheme, string, string
auth-check-2fa | "auth" | MFACheck() | Helix.Core.Server.MFA.Status, string
auth-pre-2fa | "auth" | MFAPre() | Helix.Core.Server.MFA.Status, table
bgtask | unset | BGTask() | boolean
change-commit | depot paths | ChangeCommit() | boolean
change-content | depot paths | ChangeContent() | boolean
change-failed | depot paths | ChangeFailed() | boolean
change-submit | depot paths | ChangeSubmit() | boolean
command | “pre-user-*” and “post-user-*” | Command() | boolean
edge-content | depot paths | EdgeContent() | boolean
edge-submit | depot paths | EdgeSubmit() | boolean
fix-add | "fix" | FixAdd() | boolean
fix-delete | "fix" | FixDelete() | boolean
form-commit | a form type | FormCommit() | boolean
form-delete | a form type | FormDelete() | boolean
form-in | a form type | FormIn() | boolean
form-out | a form type | FormOut() | boolean
form-save | a form type | FormSave() | boolean
graph-fork-repo | repo paths | GraphForkRepo() | boolean
graph-lfs-push | repo paths | GraphLFSPush() | boolean
graph-push-complete | repo paths | GraphComplete() | boolean
graph-push-reference-complete | repo paths | GraphPushReferenceComplete() | boolean
graph-push-reference | repo paths | GraphPushReference() | boolean
graph-push-start | repo paths | GraphPushStart() | boolean
heartbeat-missing | heartbeat | HeartbreatMissing() | boolean
heartbeat-resumed | heartbeat | HeartbreatResumed() | boolean
heartbeat-dead | heartbeat | HeartbreatDead() | boolean
journal-rotate-lock | server IDs | JnlRotateLock() | boolean
journal-rotate | server IDs | JnlRotate() | boolean
pull-archive | “pull” | PullArchive() | boolean
push-commit | depot paths | PushCommit() | boolean
push-content | depot paths | PushContent() | boolean
push-submit | depot paths | PushSubmit() | boolean
service-check | "auth" | ServiceCheck() | boolean
shelve-commit | depot paths | ShelveCommit() | boolean
shelve-delete | depot paths | ShelveDelete() | boolean
shelve-submit | depot paths | ShelveSubmit() | boolean

## PressurePause callback

To prioritize certain commands, consider using the `PressurePause` Extension hook callback. `PressurePause` can call the `SetPauseState()` function to tell the server to keep pausing the command, unpause the command, or let the server determine whether to pause or unpause the command. Only one `PressurePause` Extension is allowed.

See also these Trigger script variables:

`%sessionsPaused%` -- Number of paused client commands.

`%pauseRateCPU%` -- Percentage of commands blocked for CPU.

`%pauseRateMem%` -- Percentage of commands blocked for memory.

`%pressureMem%` -- low/medium/high memory pressure.

`%pressureCPU%` -- high CPU pressure.

Your search for returned results