An experienced engineer at Mercury, a fintech serving 300,000 businesses, shares hard-won lessons from running 2 million lines of Haskell in production. Key themes include treating purity as a boundary rather than a property, encoding operational invariants in types to preserve institutional knowledge, using Temporal for durable execution to replace fragile cron-based state machines, designing domain models independent of transport concerns (e.g., not leaking HTTP status codes into business logic), and using records-of-functions for observability and testability. The post also covers the tradeoffs of heavy type encoding, the importance of pragmatism over idealism in Haskell teams, and honest assessments of ecosystem gaps like limited library instrumentation and HTTP/2 support.
Table of contents
How We Think About ReliabilityPurity Is a Boundary, Not a PropertyMake the Right Thing EasyDurable ExecutionDesign for Your Domain, Not Your TransportThe Type Encoding TradeoffDesigning for IntrospectionWhat We Don't Put in the TypesWhy bother with Haskell at all?Sort: