> For the complete documentation index, see llms.txt.
Skip to main content

Check out Port for yourself ➜ 

Live events

Live events allow an integration to process source changes as they happen, usually through webhooks or a source-specific watch API. They update mapped catalog entities between scheduled resyncs, which reduces the delay before changes appear in Port.

Live events complement full and incremental syncs, but they do not replace full resync reconciliation. Support and setup vary by integration. If an integration does not support live events, Port keeps its data up to date through scheduled or manually triggered resyncs and, where available, incremental sync.

For self-hosted deployments that require better reliability, event durability, or horizontal scaling of live event processing, you can optionally set up Port's dedicated live events infrastructure.

Live events at scale

SaaS customers

If you are using Port's hosted integrations, no action is required. The infrastructure described here is managed entirely by Port on the SaaS side.

Port's live events infrastructure allows integrations to receive and process real-time webhook events from third-party services. For self-hosted deployments, you can configure a scalable infrastructure using Redis Streams and a dedicated ingestion component (ocean-gateway) to improve reliability, durability, and horizontal scalability.

This section covers the components and configuration, deployment steps, and consumer scaling options for this infrastructure. Each integration's documentation remains the authoritative source for integration-specific setup (webhook registration, event types, and filters).

Who is this for?

This infrastructure is targeted at self-hosted (on-prem) customers who:

  • Run high volumes of live events and need better reliability and event ingestion guarantees.
  • Experience event loss on pod restarts or failure scenarios.
  • Want to scale live event consumers horizontally.

How it works

Incoming webhook traffic is routed through your Ingress to ocean-gateway, which writes each event to a per-integration Redis Stream. Consumer pods read from that stream independently of ingestion, so events are never lost on a pod restart and consumers can be scaled horizontally.

Live events infrastructure architecture showing webhook traffic routed through Ingress to ocean-gateway, which writes events to Redis Streams for consumer pods to process

Components and configuration

This infrastructure is deployed via the ocean-gateway Helm chart, which can optionally bundle Redis or use a Redis instance you bring yourself. Once deployed, two values must be set for the whole flow to work: the live events base URL and your Ingress routing.

Ocean-gateway

The ocean-gateway service is a required component of the live events infrastructure. It handles all incoming webhook HTTP traffic and writes events to the appropriate Redis Stream, with no processing logic of its own.

  • It is available as an open-source service in the ocean-gateway repository.
  • It is included in the Ocean Helm chart for self-hosted deployments and must be deployed alongside your integration pods.
  • Because it only ingests events into Redis Streams, it continues to accept and persist webhook traffic even when your live event consumer pods are unavailable, events wait in the stream and are processed once a consumer is back up.

Redis

  • Minimum version: Redis 7.0 or later.
  • Redis Streams support is required. It is available from Redis 5.0, but version 7.0 or later is required for full compatibility.

Live events are stored in Redis Streams. The ocean-gateway service is stateless - only Redis holds events after ingestion. Redis must use persistent storage so stream data survives a Redis pod crash or restart.

  • If you use the bundled Redis (deployed via the ocean-gateway Helm chart), persistence is enabled by default via a PVC. Do not disable it unless you accept event loss on Redis restarts.
  • If you bring your own Redis, you are responsible for ensuring durability - for example, a managed Redis service with persistence, or your own Redis deployment with a volume and RDB/AOF enabled.

Live events base URL

Each integration must have a unique, stable base URL, set via the liveEvents.baseUrl Helm value, which the integration pod exposes internally as the OCEAN__BASE_URL environment variable. This value is used as the Redis Stream key, so it must be unique across all integrations sharing the same Redis instance.

The URL must follow this exact format:

https://live-events.your-domain.com/live-events/<unique-id>
Avoid URL collisions

Two integrations with the same OCEAN__BASE_URL on the same Redis instance will collide and corrupt each other's event stream. Use a different <unique-id> per integration, and avoid trailing slashes or variations between environments.

Ingress

Your Ingress must route incoming webhook traffic to ocean-gateway, not directly to the integration pod. If you manage your Ingress outside of the Helm chart, configure the routing rule manually to point to the ocean-gateway service.

Split routing for webhook handshakes: some integrations perform a handshake during webhook setup using HTTP methods other than POST (such as GET or OPTIONS) to verify the endpoint before sending events. Since ocean-gateway handles only POST requests, handshake requests must be routed directly to the integration pod.

Integrations that require this split routing include Azure DevOps and Okta. See each integration's documentation for the exact configuration.

Deployment steps

Bundled Redis is enabled by default in the ocean-gateway Helm chart. Use this path if you don't already run Redis.

Step 1 - Deploy ocean-gateway

Set a strong password, and optionally your Ingress values. You will reuse this same password in Step 2:

helm upgrade --install ocean-gateway port-labs/ocean-gateway \
--namespace ocean-gateway --create-namespace \
--set redis.auth.password=<strong-password> \
--set ingress.enabled=true \
--set ingress.className=nginx \
--set ingress.host=live-events.your-domain.com

Step 2 - Create a Redis credentials secret for the integration

ocean-gateway auto-wires its own Redis connection, but the integration needs a separate secret with both sets of keys. Use the same <strong-password> you set in Step 1:

kubectl create secret generic live-events-redis-credentials \
--namespace <integration-namespace> \
--from-literal=REDIS_LIVE_EVENTS_URL=ocean-gateway-redis-master.ocean-gateway.svc.cluster.local:6379 \
--from-literal=REDIS_LIVE_EVENTS_PASSWORD=<strong-password> \
--from-literal=REDIS_LIVE_EVENTS_ENABLE_TLS=false \
--from-literal=OCEAN__LIVE_EVENTS__REDIS__URL=redis://ocean-gateway-redis-master.ocean-gateway.svc.cluster.local:6379 \
--from-literal=OCEAN__LIVE_EVENTS__REDIS__PASSWORD=<strong-password> \
--from-literal=OCEAN__LIVE_EVENTS__REDIS__ENABLE_TLS=false
Release name

Replace ocean-gateway with your release name and namespace if they differ.

Configure your Ingress

Route incoming webhook POST traffic to ocean-gateway, not directly to the integration pod:

https://live-events.your-domain.com/live-events/<liveEventsUUID>/integration/<webhookSuffix>
Handshake routing

Some integrations (Azure DevOps, Okta) verify endpoints with GET or OPTIONS. ocean-gateway handles POST requests only, so route handshake requests directly to the integration pod. See Ingress.

Configure the integration for live events

Set the following in the integration's Helm values:

liveEvents:
baseUrl: https://live-events.your-domain.com/live-events/<unique-id>
isRedisStreamConsumerEnabled: true
redis:
credentialsSecretName: live-events-redis-credentials

Or with --set flags:

helm upgrade --install my-integration port-labs/port-ocean \
--namespace port-ocean --create-namespace \
--set liveEvents.baseUrl=https://live-events.your-domain.com/live-events/<unique-id> \
--set liveEvents.isRedisStreamConsumerEnabled=true \
--set liveEvents.redis.credentialsSecretName=live-events-redis-credentials
  • baseUrl (sets OCEAN__BASE_URL) - the integration's unique base URL, following the required format. See Live events base URL.

  • isRedisStreamConsumerEnabled - without this, ocean-gateway will keep writing events to Redis, but the integration pod will not read them.

  • redis.credentialsSecretName - the secret created above, so the integration connects to the same Redis instance as ocean-gateway.

    Unique base URL

    liveEvents.baseUrl must be unique per integration on the same Redis instance. See Live events base URL.

Verify

Confirm the deployment is healthy and events are flowing:

  • ocean-gateway pods are ready.

  • The integration consumer has OCEAN__LIVE_EVENTS__IS_REDIS_STREAM_CONSUMER_ENABLED=true.

  • A test webhook returns 202 Accepted.

  • Events appear in Port without a growing Redis backlog.

    kubectl get pods -n ocean-gateway
    kubectl logs -n ocean-gateway deploy/ocean-gateway

Scaling live events consumers (optional)

With this infrastructure, live event consumer pods can be deployed independently from the main integration pod. This is useful when:

  • You need to scale event processing horizontally under high event volumes.
  • You want to isolate live event processing from integration resync logic.

To scale up consumers, set the replica count in your Helm chart values:

liveEvents:
worker:
enabled: true
replicaCount: 3

Each additional replica joins the same Redis consumer group and starts processing events in parallel. No other configuration changes are needed.

Scalable mode

For high-throughput environments, consider also enabling scalable mode for the integration itself to decouple the resync process from live event processing. This option is available in each integration's self-hosted installation section.