Custom events let you create system-wide triggers that any script can fire and multiple processes can respond to. You'll build the event registry entry, write code to fire it, and create handlers that respond when it fires.
The problem with direct script coupling
Without events, scripts that need to trigger other processes have to call them directly — creating notifications in the same script that processes a request, or having a Business Rule directly call web services. This creates tight coupling where changing one piece breaks others. Platform admins and developers inherit systems where a single script does five different things, making troubleshooting and maintenance a nightmare. When something fails, you can't tell which part broke without digging through monolithic scripts.
How ServiceNow events decouple processes
Events work in three layers: the registry entry defines what the event is called and what data it carries, the firing script uses gs.eventQueue() to put the event in the queue, and handler scripts or notifications respond when ServiceNow processes the event. The key insight is that events are asynchronous — the script that fires the event continues immediately without waiting for handlers to finish. This means you can add new handlers later without changing the original firing script. Start with a simple event that carries basic record data, then add multiple handlers as your use case grows.
Production-quality event architectures
Once basic events work, the improvements that matter are: designing event names as a hierarchy (incident.assigned, incident.resolved) so you can build generic handlers, passing structured data instead of just record references so handlers don't need database lookups, and creating event scripts that can handle failures gracefully. Well-designed events become the backbone for complex integrations — one business process fires events at key moments, and multiple downstream systems respond independently.
Before you start
- •admin role or event_management role
Sourdough: ServiceNow Monitoring and Analytics
A Chrome extension for ServiceNow Admins and Developers with essential tools, analytics, graphs and monitoring features.
Free to install. Pro $5/month after a 14-day no-card trial.
Pro requires the ServiceNow admin role. Upgrade inside the extension.
Step by step
Create the event registry entry
Navigate to System Policy > Events > Registry and click New. Set the Event name to something hierarchical like 'custom.user.onboarding' — use dots to create logical groupings. Fill in Description with what triggers this event and what data it carries. The Fired by field should describe which scripts or processes fire this event. Leave all checkboxes unchecked unless you need the event to wake up sleeping instances.
Use lowercase with dots as separators — this becomes the exact string you'll pass to gs.eventQueue().
Test firing the event
Open Scripts - Background and write a test script: 'gs.eventQueue("custom.user.onboarding", current, "param1_value", "param2_value");'. The second parameter should be a GlideRecord if you have one, or null. The third and fourth parameters are strings you can pass to handlers. Run the script and check System Logs > Events to confirm your event was queued and processed.
Create an event script action
Navigate to System Definition > Script Actions and click New. Set the Name to something descriptive like 'Handle user onboarding event'. Check the Event firing checkbox and set Event name to match your registry entry exactly. In the Script field, write your handler logic — use 'event.parm1' and 'event.parm2' to access the parameters you passed, and 'current' to access the record if you passed one.
Add the firing code to your business logic
Replace your test script with the actual location where you want to fire the event — typically inside a Business Rule, Script Include, or Flow. Use the same gs.eventQueue() syntax but pass meaningful parameters. For example: 'gs.eventQueue("custom.user.onboarding", current, current.department.getDisplayValue(), current.manager.sys_id.toString());'. This lets handlers access department name and manager ID without additional queries.
Create additional handlers
Navigate back to System Definition > Script Actions and create additional handlers for the same event name. Each Script Action that matches the event name will run independently. You can also create Email Notifications that trigger on your custom event by setting the When to fire field to 'Event is fired' and specifying your event name. This lets you send emails, update other records, or call web services all from the same event trigger.
Verify asynchronous execution
Add logging to both your firing script and your event handlers using gs.info() with different messages. Fire the event and check System Logs > System Log to see the execution order. The firing script's log entries will appear first, followed by the handler log entries. This confirms the event fired asynchronously — your original script didn't wait for the handlers to complete.
Best practices
Name events hierarchically with dots (incident.assigned, incident.resolved) so you can build handlers that respond to entire categories using wildcards or string matching.
Pass structured data as parameters instead of making handlers query the database — if handlers need department name and manager ID, pass those as parm1 and parm2 rather than just the user record.
Don't fire events inside loops — if you need to process multiple records, collect them and fire a single event with a list, or use scheduled jobs for bulk processing.
Create a naming convention and document it — teams that inherit your events need to understand what triggers them and what data they carry without reading the source code.
Test event handlers in isolation by firing events manually in Scripts - Background before integrating them into business processes.
Test Your Knowledge
Quick 3-question quiz — see how your ServiceNow skills stack up.
A list view on a table with millions of records is slow. Best fix?
Select an answer to continue