The Catalyst::Engine::PSGI module (which I guess is being used a lot now) has this stuff inside its run method:
$c = $class->prepare(env => $env);
$status = $c->finalize;
...and much further down...
return [ $c->res->status, $headers, $body ];
This causes the _run_after_request hooks to be triggered before the response is returned.
I am not sure how to solve this issue. First off, I find it very optimistic to expect that an after 'finalize' method wrapper will be safely executed after the response has been sent. The Catalyst documentation doesn't explicitly mention that at the time finalize is called, the response has already been sent.
So fixing this, should be done by inserting another hook in Catalysts request/response loop, right after finalize.
On the other hand, there are more hacky ways, such as ensuring that all responses become streaming and then attach a guard that executes when the returned sub is destroyed. (Yuval Kogman would probably do that :). Another way is just changing Catalyst::Engine::PSGI, but I think the fix would be temporary since you can't rely on all processing being finished in an after 'finalize' wrapper.
Let me know what you think, and I'll write the fix myself.
Oh, I forgot to mention that this may also be solved by stacking a Plack::Middleware handler on top of the Catalyst PSGI app.