- Create a Context. If no TraceId is provided, generates a new one. If no Baggage is provided, creates an empty one. @param null|TraceId $traceId Optional TraceId to use @param null|Baggage $baggage Optional Baggage to use
+ Create a root Context (no active span). A span created in this context becomes a new trace root. Attach an active span with Context::withActiveSpan() to make subsequent spans its children. @param null|Baggage $baggage Optional Baggage to use
+ Create a GitDetector. @param null|string $workingDirectory Directory to run git in (default: current working directory) @param string $gitBinary Path to the git binary (default: \"git\", resolved from $PATH)
+
+ Create an asynchronous curl transport for OTLP endpoints. @param string $endpoint OTLP endpoint URL (e.g., \'http://localhost:4318\') @param JsonSerializer|ProtobufSerializer $serializer Serializer for encoding telemetry data (JSON or Protobuf) @param AsyncCurlTransportOptions $options Transport configuration options @param ?Transport $failover Optional failover transport receiving prior batches when primary fails @param ErrorHandler $error_handler Handler for failures reaped on send()/tick()/shutdown() (no failover)
+
- Create an async curl transport for OTLP endpoints. Creates a CurlTransport that uses curl_multi for non-blocking I/O. Requests are queued and executed asynchronously. OTLP/HTTP allows JSON or Protobuf encoding; defaults to JSON. Requires: ext-curl PHP extension @param string $endpoint OTLP endpoint URL (e.g., \'http://localhost:4318\') @param JsonSerializer|ProtobufSerializer $serializer Serializer for encoding telemetry data (JSON or Protobuf) @param CurlTransportOptions $options Transport configuration options @param ?Transport $failover Optional failover transport receiving prior batches when primary fails
+ Create a synchronous curl transport for OTLP endpoints. Creates a CurlTransport that drives each request to completion and reports the outcome immediately (returns on success, throws on failure). OTLP/HTTP allows JSON or Protobuf encoding; defaults to JSON. Keeping export off the application hot path is the job of the batching processor in front of the exporter. Requires: ext-curl PHP extension @param string $endpoint OTLP endpoint URL (e.g., \'http://localhost:4318\') @param JsonSerializer|ProtobufSerializer $serializer Serializer for encoding telemetry data (JSON or Protobuf) @param CurlTransportOptions $options Transport configuration options @param ?Transport $failover Optional failover transport receiving the batch when the primary fails
+ `
+ return div
+ },
+ apply: snippet("\\Flow\\ETL\\DSL\\schema_sort_by_type_and_name(" + "$" + "{" + "1:priorities" + "}" + ", " + "$" + "{" + "2:order" + "}" + ")"),
+ boost: 10
}, {
label: "schema_strict_validator",
type: "function",
diff --git a/web/landing/assets/images/banner.png b/web/landing/assets/images/banner.png
index 32fc4994ac..ba05d7c6de 100644
Binary files a/web/landing/assets/images/banner.png and b/web/landing/assets/images/banner.png differ
diff --git a/web/landing/assets/images/blog/.DS_Store b/web/landing/assets/images/blog/.DS_Store
new file mode 100644
index 0000000000..06cfb14c6a
Binary files /dev/null and b/web/landing/assets/images/blog/.DS_Store differ
diff --git a/web/landing/assets/images/blog/flow-php-release-0410/messenger_link.png b/web/landing/assets/images/blog/flow-php-release-0410/messenger_link.png
new file mode 100644
index 0000000000..8a000938e8
Binary files /dev/null and b/web/landing/assets/images/blog/flow-php-release-0410/messenger_link.png differ
diff --git a/web/landing/assets/images/blog/flow-php-release-0410/profiler_01.png b/web/landing/assets/images/blog/flow-php-release-0410/profiler_01.png
new file mode 100644
index 0000000000..58b1d04b1c
Binary files /dev/null and b/web/landing/assets/images/blog/flow-php-release-0410/profiler_01.png differ
diff --git a/web/landing/assets/images/blog/flow-php-release-0410/profiler_02.png b/web/landing/assets/images/blog/flow-php-release-0410/profiler_02.png
new file mode 100644
index 0000000000..599d22a13d
Binary files /dev/null and b/web/landing/assets/images/blog/flow-php-release-0410/profiler_02.png differ
diff --git a/web/landing/assets/images/blog/flow-php-release-0410/profiler_migrations.png b/web/landing/assets/images/blog/flow-php-release-0410/profiler_migrations.png
new file mode 100644
index 0000000000..1aad168a68
Binary files /dev/null and b/web/landing/assets/images/blog/flow-php-release-0410/profiler_migrations.png differ
diff --git a/web/landing/assets/images/blog/flow-php-release-0410/profiler_queries.png b/web/landing/assets/images/blog/flow-php-release-0410/profiler_queries.png
new file mode 100644
index 0000000000..b439f14cb3
Binary files /dev/null and b/web/landing/assets/images/blog/flow-php-release-0410/profiler_queries.png differ
diff --git a/web/landing/assets/images/favicons/apple-touch-icon.png b/web/landing/assets/images/favicons/apple-touch-icon.png
index 5e4c2a1969..d6cba89d23 100644
Binary files a/web/landing/assets/images/favicons/apple-touch-icon.png and b/web/landing/assets/images/favicons/apple-touch-icon.png differ
diff --git a/web/landing/assets/images/favicons/favicon-16x16.png b/web/landing/assets/images/favicons/favicon-16x16.png
index aa799bbe25..4f5cf71001 100644
Binary files a/web/landing/assets/images/favicons/favicon-16x16.png and b/web/landing/assets/images/favicons/favicon-16x16.png differ
diff --git a/web/landing/assets/images/favicons/favicon-32x32.png b/web/landing/assets/images/favicons/favicon-32x32.png
index 107ca465b3..6febd3abe7 100644
Binary files a/web/landing/assets/images/favicons/favicon-32x32.png and b/web/landing/assets/images/favicons/favicon-32x32.png differ
diff --git a/web/landing/assets/images/sponsors/1Password.png b/web/landing/assets/images/sponsors/1Password.png
index 23e99f51bb..02796575dc 100644
Binary files a/web/landing/assets/images/sponsors/1Password.png and b/web/landing/assets/images/sponsors/1Password.png differ
diff --git a/web/landing/assets/images/sponsors/cloudflare.png b/web/landing/assets/images/sponsors/cloudflare.png
index 4d27bb3ce1..d0711b1903 100644
Binary files a/web/landing/assets/images/sponsors/cloudflare.png and b/web/landing/assets/images/sponsors/cloudflare.png differ
diff --git a/web/landing/assets/images/sponsors/datadog.png b/web/landing/assets/images/sponsors/datadog.png
index ffafa460a6..53f5458912 100644
Binary files a/web/landing/assets/images/sponsors/datadog.png and b/web/landing/assets/images/sponsors/datadog.png differ
diff --git a/web/landing/assets/images/sponsors/tailscale.png b/web/landing/assets/images/sponsors/tailscale.png
index 634db00d99..cca54fd14d 100644
Binary files a/web/landing/assets/images/sponsors/tailscale.png and b/web/landing/assets/images/sponsors/tailscale.png differ
diff --git a/web/landing/assets/styles/app.css b/web/landing/assets/styles/app.css
index b3dc7a2f09..d17bc1c0b8 100644
--- a/web/landing/assets/styles/app.css
+++ b/web/landing/assets/styles/app.css
@@ -117,9 +117,9 @@ code {
font-size: 0.9em;
}
-/* Blog post prose. Wraps full-width with comfortable reading measure. */
+/* Blog post prose. Wraps full-width to match the site container. */
#blog-post {
- @apply pb-5 px-4 sm:px-6 lg:px-8 mx-auto max-w-3xl text-slate-700 dark:text-white/85;
+ @apply pb-5 px-4 sm:px-6 lg:px-8 mx-auto max-w-screen-2xl text-slate-700 dark:text-white/85;
}
#blog-post a {
@@ -190,6 +190,18 @@ code {
@apply border-b border-slate-200 px-3 py-2 dark:border-white/10;
}
+#blog-post img {
+ @apply max-w-full h-auto rounded-lg my-6 mx-auto;
+}
+
+#blog-post figure {
+ @apply my-8;
+}
+
+#blog-post figcaption {
+ @apply text-sm text-slate-500 text-center mt-2 dark:text-white/55;
+}
+
#example-description h1 {
@apply font-bold text-2xl;
diff --git a/web/landing/src/Flow/Website/Blog/Posts.php b/web/landing/src/Flow/Website/Blog/Posts.php
index 0ad9776303..a9428f1f50 100644
--- a/web/landing/src/Flow/Website/Blog/Posts.php
+++ b/web/landing/src/Flow/Website/Blog/Posts.php
@@ -39,6 +39,12 @@ final class Posts
'date' => '2025-03-16',
'slug' => 'flow-php-release-cycle',
],
+ [
+ 'title' => 'Flow PHP - Release 0.41.0',
+ 'description' => 'Summary of things changed in Flow PHP 0.41.0 release',
+ 'date' => '2026-06-29',
+ 'slug' => 'flow-php-release-0410',
+ ],
];
/**
diff --git a/web/landing/templates/blog/posts/2026-06-29/flow-php-release-0410/exporter_enabling.yaml b/web/landing/templates/blog/posts/2026-06-29/flow-php-release-0410/exporter_enabling.yaml
new file mode 100644
index 0000000000..4f849c0c2a
--- /dev/null
+++ b/web/landing/templates/blog/posts/2026-06-29/flow-php-release-0410/exporter_enabling.yaml
@@ -0,0 +1,9 @@
+flow_telemetry:
+ exporters:
+ otlp_exporter:
+ enabled: '%env(bool:OTEL_ENABLED)%' # off → discard exports; profiler still captures every signal
+ otlp:
+ transport:
+ type: curl
+ endpoint: '%env(OTEL_ENDPOINT)%'
+ encoding: protobuf
\ No newline at end of file
diff --git a/web/landing/templates/blog/posts/2026-06-29/flow-php-release-0410/messenger_linking.yaml b/web/landing/templates/blog/posts/2026-06-29/flow-php-release-0410/messenger_linking.yaml
new file mode 100644
index 0000000000..186f5f52bd
--- /dev/null
+++ b/web/landing/templates/blog/posts/2026-06-29/flow-php-release-0410/messenger_linking.yaml
@@ -0,0 +1,7 @@
+flow_telemetry:
+ instrumentation:
+ messenger:
+ enabled: true
+ context_propagation: true # Propagate context across message boundaries
+ propagation_style: link # link|continue - How the consumer span relates to the producer span
+ link_to_worker: true # Link each message trace back to the messenger:consume worker span
\ No newline at end of file
diff --git a/web/landing/templates/blog/posts/2026-06-29/flow-php-release-0410/post.html.twig b/web/landing/templates/blog/posts/2026-06-29/flow-php-release-0410/post.html.twig
new file mode 100644
index 0000000000..a2c8963553
--- /dev/null
+++ b/web/landing/templates/blog/posts/2026-06-29/flow-php-release-0410/post.html.twig
@@ -0,0 +1,102 @@
+{% extends 'blog/post.html.twig' %}
+{% block article %}
+
+
Flow PHP - Release 0.41.0
+
+
+ This is a first blog post about Flow Release, and 0.41.0 is bringing a lot of cool new features, mostly
+ around Telemetry and Symfony Integration.
+
+
+ The plan is to write a blog post for each release, or at least try to.
+
+
+
Symfony Telemetry Bundle
+
+
+ This is where most of our efforts were focused on, so lets start from the most exciting one.
+
+
Telemetry integration with Profiler
+
+
+
+ Telemetry panel in the Symfony profiler
+
+
+
+ This way during local development, we don't need to setup a full scale APM to quickly check if given part of
+ the system is correctly collecting telemetry signals.
+
+
+ Profiler integration is configurable on the bundle level, you can read more about it in documentation.
+
+
Telemetry Worker Mode Support
+
+ Modern PHP systems are often deployed in the Worker mode, through runtimes like FrankenPHP or Swoole.
+ In order to support that, we introduced a ResettableContextStorage and a mechanism that can automatically detect if system is running in a worker mode.
+
+
+ runtime_mode can also be configured at symfony configuration level.
+
+ Symfony Telemetry Bundle can now link traces that published message on the queue with message handling process (trace).
+
+
+
+ Symfony Messenger traces linking
+
+
+ As we can see on the screenshot above, trace representing processing CreateOrderMessage
+ is now linked into two other Traces.
+
+
+ The first one is a Worker trace (Flow Telemetry separates workers from handlers) and the second one is a
+ link to a Controller that published that CreateOrderMessage on the queue.
+
+
+ That behavior is also configurable at Symfony Bundle level.
+
+ Integrating Telemetry into existing systems can be really challenging task. It might be a good idea to start
+ in development environment or staging first, and only when everything is calibrated and tuned, enable it also
+ at production.
+
+
+ Now it can be achieved by a dedicated enabled option added to each export
+
+ This opens a new set of features for Flow, making scalable indexing documents from various sources easier than ever.
+ Please look at the example of indexing a CSV document:
+