New to Kestra?
Use blueprints to kickstart your first workflows.
Orchestrate a scheduled Postgres aggregate refresh with Kestra, then fan out pipeline-completion events to multiple NATS subjects so downstream teams react independently.
Stop making every downstream team poll the warehouse or query Kestra to find out a nightly pipeline finished. This blueprint refreshes a daily sales aggregate in Postgres on a schedule, then publishes three purpose-built completion events onto three independent NATS subjects, one for fulfillment, one for analytics, and one for audit, each carrying only the fields that team actually needs. Every subscriber reacts to the same pipeline run without coupling to the database schema or to each other.
refresh_daily_sales (io.kestra.plugin.jdbc.postgresql.Query) upserts today's row into reporting.daily_sales, aggregating order count and revenue from public.orders for the current date.read_aggregate (io.kestra.plugin.jdbc.postgresql.Query) reads that row back with fetchType: FETCH_ONE, exposing total_orders and total_revenue as outputs.read_aggregate.row.*.notify_fulfillment (io.kestra.plugin.nats.core.Produce) publishes a small JSON payload with just the order count onto pipeline.completed.fulfillment.notify_analytics (io.kestra.plugin.nats.core.Produce) publishes a payload with just the revenue total onto pipeline.completed.analytics.notify_audit (io.kestra.plugin.nats.core.Produce) publishes the full aggregate plus the Kestra execution id onto pipeline.completed.audit, giving compliance a complete, traceable record.nightly Schedule trigger runs the whole sequence once a day; the errors block posts a Slack alert if the refresh or any publish step fails, so a broken fan-out is never silent.Postgres and NATS connection details are each set once through pluginDefaults, so the three Produce tasks only need to declare their subject and payload.
pipeline.completed.audit that ties every completion event back to a specific Kestra execution id.Produce task, with zero changes to the existing subscribers.NATS delivers messages reliably once you publish them, but it has no scheduler, no SQL execution, and no concept of "refresh this aggregate, then tell three different subjects about it, and alert someone if any step fails." Kestra supplies all of that: the Schedule trigger drives the refresh, the JDBC tasks compute the aggregate the fan-out actually reports on, three Produce tasks publish tailored events as one auditable execution, and the errors block guarantees a failure anywhere in the chain still reaches a human. The whole notification contract for three teams lives in one version-controlled YAML file instead of being scattered across cron jobs and ad hoc publish scripts.
public.orders table and a reporting.daily_sales table keyed on report_date.url.pipeline.completed.fulfillment, pipeline.completed.analytics, and pipeline.completed.audit.POSTGRES_URL: JDBC URL, for example jdbc:postgresql://warehouse-host:5432/orders.POSTGRES_USERNAME / POSTGRES_PASSWORD: database credentials.NATS_URL: NATS server URL, for example nats://nats.internal:4222.NATS_USERNAME / NATS_PASSWORD: credentials for the NATS server.SLACK_WEBHOOK_URL: Slack incoming webhook URL.public.orders and reporting.daily_sales tables exist with the expected columns.nats sub "pipeline.completed.>").disabled: false on the nightly trigger, or run the flow manually to see all three events published.Produce task for a new downstream team without touching the existing three, since each subscriber only depends on its own subject.pipeline.completed.* subjects with a templated subject per region or business unit for multi-tenant fan-out.io.kestra.plugin.nats.kv.Put) alongside the fan-out so late subscribers can read the last completion state instead of only reacting to the live event.