🌱Ian's Digital Garden

distinguishing the hourglass model, the narrow waist concept, two-stage pipelines, and Perlis Epigram #9 (DRAFT)


Splitting programs up is a bread-and-butter programming technique. It's gotten tons of advanced study.

This note is about one specific type of split: the single-split. Forget compositionality in general. Let's take a look at systems that focus down to just one point. The bottleneck. The choke-point. The megavertex. The NEMA connector. The Isthmus of Panama.

Black-and-white illustration of data flowing through a rough hourglass shape

(Image cropped from this paper by Tung-Liang Chang)


First let's get our feet planted.

  • Compilers
    • Often broken into a frontend and backend, connected by a small IR
    • For instance ⚛️GHC Core
  • The Internet
    • The Internet Protocol separates the transport layer from the link layer. TCP and UDP aren't allowed to know about Ethernet or Wi-Fi.
    • DAG of protocol dependencies that all go through IPv4
      • (Image from this paper by Saamer Akhshabi and Constantine Dovrolis)
  • This website
    • 💾Obsidian makes a folder of markdown and a static site generator uses it to create the website. I can swap out either without having to touch the other.
  • Lisp and Unix
    • Everything whangs on lists and bytestreams, respectively.

There are powerful principles for constructing programs at work here, applicable all the way from small scripts to gargantuan systems.


  • Is the split about dependencies, data flow, or both?
    • For the Internet the split is about dependencies. An application isn't allowed to know certain things about ethernet. But it might be listening for and sending IP packets at multiple places within the program.
    • For the static site example it's about both. Not only can Obsidian not know about the static site generator, it also must communicate with it at only one point and only one-way.
    • We didn't give an example, but you could imagine a static site that's split by data flow but not dependencies. It's one tangled code base, but partway through the processing must compress to a single data structure.
  • Symmetry and cardinality of the split
    • In Lisp millions of different functions all speak lists.
    • In the compiler/Internet/static site examples the world is split into two parts, each with a different responsibility relative to the splitting interface (layered architectures, one side "below" the split and the other "above").
  • Is the split within a single program?


What existing vocabulary lets us talk about these situations?

  • Frontend and backend
  • Perlis Epigram #9
  • Uniform Metaphor
    • Also applies to Lisp (stated explicitly in the source) and Unix-style systems.
    • 🖊️
      Uniform Metaphor

      Uniform Metaphor: A language should be designed around a powerful metaphor that can be uniformly applied in all areas.

      Examples of success in this area include LISP, which is built on the model of linked structures; APL, which is built on the model of arrays; and Smalltalk, which is built on the model of communicating objects. In each case, large applications are viewed in the same way as the fundamental units from which the system is built.
  • Narrow waist design / hourglass model / hourglass architecture
    • Definitely applies to the Internet example... because that's where it came from.
    • ⚛️
      Hourglass Model or Narrow Waist Design


      The hourglass model and narrow waist design are the same thing. The "narrow waist" refers to the neck of an hourglass.


      According to this video the original source is 👤Jon Postel splitting up the design of TCP and IP.

      It quotes Postel in IEN # 2 from 1977:

      We are screwing up in our design of internet protocols by violating the principle of layering. Specifically we are trying to use TCP to do two things: serve as a host level end to end protocol, and to serve as an internet packaging and routing protocol. These two things should be provided in a layered and modular way. I suggest that a new distinct internetwork protocol is needed, and that TCP be used strictly as a host level end to end protocol.

      At 3:47 in the video the speaker describes Postel drawing an hourglass and using the term "narrow waist" (emphasis mine):

      The starting point for the Internet was John saying, "The structure of our world is this: there's only one piece-- that thing in the middle-- that has to be everywhere. Everything else is sitting on individual hosts or individual wires. The thing that has to be everywhere you want it to be absolutely bulletproof, you want it to be really simple, and you want it to be a foundation that you can build on above and below. And the foundation's not going to ever change, because if it changes everything that rests on it is going to have to change and that's going to really stifle the innovation". So John drew an hourglass and said, "Look this is the way the world should be shaped. We get a narrow waist in the center which has to be everywhere. Above it we can put our transport protocols more the better lots of experimentation. Below it we can put lots of different interfaces the more the better lots of experimentation. In the middle we're going to do this thing that's going to be as simple as we can possibly make it and we're never going to let it change."

      So the original hourglass metaphor seems to be for systems that (1) have layered architectures, (2) follow a complex-simple-complex layering, and (3) hope not to have to change the simple layer much.


      I heard about the Van Jacobson video above while reading the article The Internet Was Designed With a Narrow Waist.

  • Pipeline
    • This applies to the compiler and static site examples, whose data flow narrows to a single node.
    • Within a single expression this is function composition.
    • For programs whose data flow bottlenecks internally it's a two-stage pipeline.
    • For the static site example with separate executables it's a two-program pipeline.


Let's review our original examples. What follows is just my subjective view, I'd appreciate suggestions.

The Internet has a layered architecture following the hourglass model.

The compiler and the static site examples do as well. Additionally they could be described as multi-stage pipelines.

The Lisp and Unix examples are applications of 🖊️Perlis Epigram #9 and can be described as following the 🖊️Uniform Metaphor principle. Unix OSes could also be described as following the hourglass model with bytestreams as the simple layer that applications speak to access OS behavior.

However I wouldn't say that the hourglass model applies to the Unix ecosystem as a whole. Yes, there are lots of types such as JSON, XML etc. that are also bytestreams. There are lots of operations (such as ag, cat, less, etc) on those bytestreams. But no layering is present since both new types and new bytestream operations are visible to applications. Thus I wouldn't call this an hourglass model since the system isn't split into two by a fixed interface.