Skip to main content

Notify when a deployment fully shifts traffic

🎯 Goal: Set up an entity hook that fires only when a deployment reaches 100% traffic, so your post-deploy logic runs exactly once per rollout.

Introduction​

Deployment updates fire often during a rollout: progress percentages, health checks, traffic switch increments, and a final status change. Most of the time you don't want to react to all of them. You want one signal that says "this deployment is now the live one."

With entity hook filters, you can subscribe to deployment:write events and ask nullplatform to call you back only when the body of the update matches a specific condition: when traffic has fully shifted to the new revision.

When you'd use this hook​

This pattern is useful any time the action you want to take has to happen after users are actually being served by the new revision, not during the rollout and not on every intermediate progress update. A few concrete examples:

  • Run a post-deploy test suite. Kick off smoke tests, synthetic monitoring, or end-to-end checks the moment 100% of traffic is on the new revision, so you measure the version your users are hitting.
  • Close out the Jira ticket attached to the deployment. Move the issue to Done, post a comment with the deployment URL, or update a custom "Released in" field, automatically, once the rollout is complete.
  • Trigger customer-facing announcements. Drop a release note in a status page, post to a #changelog Slack channel, or email a customer segment that the feature they were waiting on is now live everywhere.

💡 The common thread: each of these is a one-shot action that should fire exactly once per deployment, when the new version is fully live. Without a filter, you'd have to subscribe to every deployment:write event and write your own deduplication and "is this the final state?" logic, which is exactly what the filter saves you from.

What you'll set up​

By the end of this guide, you'll have:

  • An after-hook on deployment:write that filters by strategy_data.switched_traffic = 100
  • A notification channel that forwards the matching events to your handler
  • A working filter expression that also covers fast-finalize scenarios

1. Create the hook with a traffic filter​

The following command creates an entity hook that fires after a deployment update, but only when the request body contains strategy_data.switched_traffic equal to 100. Every other intermediate update is ignored.

np entity-hook action create \
--body '{
"nrn": "<account nrn or namespace nrn>",
"entity": "deployment",
"action": "deployment:write",
"dimensions": {},
"when": "after",
"type": "hook",
"on": "update",
"filters": {
"strategy_data.switched_traffic": 100
}
}'

A few details worth calling out:

  • when: "after": the hook runs after nullplatform has already applied the update, which is the right place to react to a "settled" state.
  • filters.strategy_data.switched_traffic: uses dot notation to reach into the nested strategy_data object of the request body. The same engine that powers notification filters is used here, so all the MongoDB-style operators ($eq, $gte, $or, ...) are available.
  • No filters set at all: this would cause the hook to fire on every single deployment update during the rollout, which is almost certainly not what you want.
Watch out for fast finalizations

Some deployment strategies finalize a deployment without going through a 100% traffic shift. For example, if the rollout is aborted and rolled back, or if a strategy completes by promoting the revision in a single step. In those cases, strategy_data.switched_traffic may never be exactly 100, and the hook above will silently skip the event.

If you need to react to every "this deployment is now done" signal regardless of how it finished, use the broader filter in step 2 instead.

2. Cover both traffic-100 and finalized statuses​

To catch both the traffic-shift case and the fast-finalize case, create a second hook that combines the conditions with $or:

np entity-hook action create \
--body '{
"nrn": "<account nrn or namespace nrn>",
"entity": "deployment",
"action": "deployment:write",
"dimensions": {},
"when": "after",
"type": "hook",
"on": "update",
"filters": {
"$or": [
{ "strategy_data.switched_traffic": 100 },
{ "status": "finalized" }
]
}
}'

Now the hook fires when either condition holds. The trade-off: a deployment that goes through a normal rollout will trigger this hook twice: once when traffic hits 100 and once when the status transitions to finalized. Make sure your handler is idempotent (or de-duplicate by deployment.id on your side) before relying on this filter in production.

3. Forward the event to a handler​

Once the hook is in place, you need a notification channel so nullplatform knows where to deliver the event. Anything that accepts the entity source works: an HTTP endpoint, a Slack channel, or a nullplatform agent.

Here's a minimal HTTP example:

np notification channel create \
--body '{
"nrn": "<account nrn or namespace nrn>",
"source": ["entity"],
"type": "http",
"configuration": {
"url": "https://yourdomain.com/deployment-finalized"
}
}'

Your endpoint will receive a payload like:

POST https://yourdomain.com/deployment-finalized
{
"id": "1180cd02-1c36-4274-8e7a-4483b87e8f2e",
"source": "entity",
"event": "deployment:write",
"created_at": "2025-02-13T14:20:43.088Z",
"notification": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"entity": "deployment",
"entity_id": "5",
"nrn": "organization=1:account=2:namespace=3:application=4:scope=5",
"callback_url": "https://api.nullplatform.com/entity_hook/550e8400-e29b-41d4-a716-446655440000",
"type": "hook",
"when": "after",
"on": "update"
}
}

For an after-hook, nullplatform expects an acknowledgement. See Implementing hook processing for the full callback format.

Where to go next​