diff --git a/docs/tutorials/cqrs-with-marten.md b/docs/tutorials/cqrs-with-marten.md
index fb05d729..d5586368 100644
--- a/docs/tutorials/cqrs-with-marten.md
+++ b/docs/tutorials/cqrs-with-marten.md
@@ -337,7 +337,7 @@ As a little tip, I've added this bit of marker code to the very bottom of our `P
// application in a test harness project. Only a convenience
public partial class Program{}
```
-snippet source | anchor
+snippet source | anchor
Having that above, I'll switch to the test harness project and create a shared fixture to bootstrap
diff --git a/docs/tutorials/railway-programming.md b/docs/tutorials/railway-programming.md
index 42573ed0..bc700488 100644
--- a/docs/tutorials/railway-programming.md
+++ b/docs/tutorials/railway-programming.md
@@ -1 +1,150 @@
-# Railway Programming with Wolverine
\ No newline at end of file
+# Railway Programming with Wolverine (Kind Of)
+
+::: tip
+I'm sure a grizzled, experienced developer in your life has already told you this
+many times, but throwing and catching `Exceptions` in .NET code is pretty expensive in
+terms of performance.
+:::
+
+[Railway Programming](https://fsharpforfunandprofit.com/rop/) is an idea that came out of the F#
+community as a way to develop for "sad path" exception cases without having to resort to
+throwing .NET `Exceptions` as a way of doing flow control by chaining together functions in
+such a way that it's relatively easy to abort workflows is preliminary steps are invalid.
+
+As with just about anything in software development, Railway Programming can be abused or
+just not be terribly ideal in certain areas. Also see [Against Railway-Oriented Programming](https://fsharpforfunandprofit.com/posts/against-railway-oriented-programming/)
+from its originator just about where it's not a great fit.
+
+Most .NET implementations of Railway Programming that this author has seen involve using
+some kind of custom `Result` type that denotes in a standard way if the processing should continue
+or stop. [Andrew Lock](https://andrewlock.net/about/) wrote a series about doing this in his series
+[Working with the result pattern](https://andrewlock.net/working-with-the-result-pattern-part-1-replacing-exceptions-as-control-flow/).
+
+::: warning
+Some teams have tried to do Railway Programming by using a mediator library where each
+message handler returns some kind of custom `Result` value, then try to chain complex workflows by calling
+a separate message handler for each step. The Wolverine team **very strongly recommends against this approach** as it
+creates a lot of code ceremony and flat out noise code while detracting from both your ability to reason about the code
+in your system. That approach can very easily create severe performance problems by being "chatty" in its interactions with backing
+databases and generally making it hard for teams to even see the relationship between system inputs and what database calls are being made.
+:::
+
+Wolverine has some direct support for a quasi-Railway Programming approach by moving validation
+or data loading steps prior to the main message handler or HTTP endpoint logic. Let's jump into
+a quick sample that works with either message handlers or HTTP endpoints using the built in [HandlerContinuation](/guide/handlers/middleware.html#conditionally-stopping-the-message-handling) enum:
+
+```csharp
+public static class ShipOrderHandler
+{
+ // This would be called first
+ public static async Task<(HandlerContinuation, Order?, Customer?)> LoadAsync(ShipOrder command, IDocumentSession session)
+ {
+ var order = await session.LoadAsync(command.OrderId);
+ if (order == null)
+ {
+ return (HandlerContinuation.Stop, null, null);
+ }
+
+ var customer = await session.LoadAsync(command.CustomerId);
+
+ return (HandlerContinuation.Continue, order, customer);
+ }
+
+ // The main method becomes the "happy path", which also helps simplify it
+ public static IEnumerable