 I have this cool t-shirt on. I do hot yoga for the first time in four years, so I still need to hold on. The simplest and most powerful idea I've picked up in software development is that design isn't about putting things together. It's about pulling things apart. The 12-factor function pulls apart meaning and magic. It's a set of 12 constraints to isolate meaningful functions. For example, faced with the rampaging dragon, a knight might write this function to decide which village to protect next. Someone whose dream is to open a bowling alley might write this function, and this function personalizes your newsfeed. So what's the big deal about these functions? Well, in a few lines of code, we improved our morning routine, got one step closer to achieving our dreams, and saved the lives of countless villagers. 12-factor functions aren't supposed to be fancy. They're supposed to be meaningful and portable. While there's no one-to-one correlation, the 12-factor function has the same goal and the same approach as the 12-factor app. Move faster by separating the core of your business from the rest of the stack. A 12-factor app is a SaaS application freed from infrastructure concerns. It delivers business value in a way that can be mixed and matched with a variety of infrastructure solutions. But there's something not quite right about the 12-factor app. I can say from experience that the code in them is not actually all business. Now, infrastructure is a fuzzy word. What if we say infrastructure is everything that isn't the rules of your business? Now suddenly, it looks like we drew the lines wrong. The 12-factor function goes to the logical extreme. It says these functions should be 100% business rules. That way, our business value is more portable and the rest of the stack is more generic. I'm using the 12-factor app to tie the 12-factor function into the shared consciousness of the programming community. The 12-factor app is not, however, where I started. I was also not motivated by the great need of developers for more design rules. I would like to take a moment to talk about how I did arrive the 12-factor function and how Ruby helped. We'll drop the words business and infrastructure because they're lame, and to take their place, I'll introduce the words meaning and magic. This is me as a newborn. The 12-factor function is really about approaching my work in a way I hope my younger self and maybe even my own kids will approve of. I was a non-technical baby. I just wanted to understand people. I was born with a keen sense of the absurdity of life, and as I got older, I studied a variety of subjects and worked a variety of jobs looking for clues about how people with all our absurd passions fit into the big, cold universe. Eventually, I arrived at programming. When I started programming, I was lucky to land in the Ruby community. I saw that the Ruby community works hard to humanize software, so I thought I could learn something. I was taught that good code reads like a novel. I liked this idea. I still like this idea, but I started running into a lot of esoteric computer-y stuff that I didn't know how to humanize. I started looking at my code and thinking, wait a second, this doesn't read like a novel. This is about as readable as a QR code. This is some code I actually wrote. It's powerful, and I'm proud of it, but it doesn't exactly read like a novel. So what does this esoteric computer-y stuff have to do with people? What does cache invalidation have to do with people? My conclusion is nothing. However, not all the code I write is about cache invalidation, and not all of it reads like a QR code. Some of it actually has a shred of humanity. Meanwhile, the other parts move information across networks and data stores in extremely powerful, but hard to explain ways. The meaningful parts I feel confident I could explain to my kids. The other parts I would have to gloss over by telling them it's computer magic. So sometimes we're looking for meaning, and sometimes we're moving information. These two activities are very different. Software development gets its power by combining our understanding of people with our understanding of computers, but because they are so different, we progress independently in our pursuits as meaning creators and as magicians. The trouble, as I see it, happens when we tangle up the meaning and the magic so that they hold each other back. If instead of tangling them up, I decouple meaning and magic, first of all, I'll have an easier time justifying my existence to my kids, and second of all, I can move faster along each of these important axes. So that brings us back to the 12-factor function. Instead of talking about business and infrastructure, though, we'll talk about meaning and magic. I chose the word meaning partly because it's so problematic in software, and I want this word choice to bother you two hours from now. The 12-factor function says that if you isolate your meaningful code in functions that meet these criteria, then you'll be able to change the meaning of your software with minimal impact on the magic that moves information, and you'll be able to change the magic with minimal impact on the meaningful bits. The last eight constraints are refinements, so we won't talk about them today. The first four are the core. The 12-factor function must produce meaning, take arguments, not reference deployment strategy, and not reference persistence strategy. Let's take an example to highlight these core criteria. Suppose we have a dataset with 100 facts for every person on Earth. How interesting would you find this information? If I printed this out for you, how much of it would you read? Now, suppose we pass this information to a function that ranks compatibility across all the fields. Imagine I find the one person out of all 7.5 billion people on Earth that is the most compatible with you. How interesting would you find this information? I predict this would be a very successful dating app. This is what we in the meaning creation industry call embarrassingly meaningful. Now let's reimplement this dating app a slightly different way. We'll start off with the same dataset, but this time we'll specify that we're storing it in a Postgres database. Then we'll select a row, any row, using SQL. We'll send the data over an Nginx proxy, we'll stick it on a Kafka queue, and then we'll query it with GraphQL. What would this give us? This is what we in the meaning creation industry call a blind date. So the first criteria of a 12-factor function is that users should find the outputs more valuable than the inputs. In the first example, with the filtering function, this criteria would be satisfied. In the second example, with all the fancy computer science, this criteria would not be satisfied. As part of producing meaning, our function should take arguments. Otherwise, we're just making declarations. Our function also shouldn't care where it is when we invoke it, or how the information gets to it. That's all computer magic. Let's talk more about this deployment strategy thing. Deployment strategies are about where we consume information. I mean, physically where. Even if we don't know the zip code that our process is running in, our process is run in different places, and they pass information over the network. The information's super highway. Networks move information. They don't add meaning, so they belong with the magic. Let's consider some scenarios. What if my matchmaking function ran in a browser? Would the output mean something different than if it ran on a server? What about on a mainframe, or in a container, or in a function as a service, or reverse-emulated Nintendo 64? Would any of these produce different meaning? No. The relationship between information and meaning is the same, no matter where the transformation takes place. I want to free my function from caring where it fits into the network. That way, I can rearrange my processes without touching my meaningful function. And I can change my meaningful function without thinking about the network. In both cases, my changes have smaller footprints with less complexity, so I move quicker, deliver more value, and spend less of my emotional energy feeling guilty about compromises. So our function shouldn't care how we deploy it. It also shouldn't care how we persist the inputs and outputs. Persistent strategies are about when we consume information. Databases, like networks, don't add meaning. They just move information through time. This is a new solution to an old problem. We used to have oral traditions to help us preserve information until we needed it. Then we figured out how to write our information down, which was more transportable and durable than a song. Songs, books, and databases don't change the meaning of what they hold. Well, songs probably do. But books and databases just move information through time. Okay, let's consider more scenarios. What if I were to apply my function before saving its arguments? Would the output mean something different than if I were to apply the function after saving its arguments? What about before queuing or after queuing or before caching or after caching? Would any of these produce different meaning? No. The relationship between information and meaning is the same no matter when the transformation takes place. I want to free my function from caring when the information it depends on enters the system. That way I can experiment with how I persist information without touching my meaningful function. And I can change my meaningful function without thinking about time. In both cases, my changes have smaller footprints with less complexity. So I move quicker, deliver more value, and spend less of my emotional energy feeling guilty about compromises. So persistence strategy is about time, and deployment strategy is about space. Together they give us the magic that moves information through space and time. Once we have that information, we pass it to a function that produces meaning without caring what epic journey brought the information to its doorstep. By decoupling meaning and magic, I can mix and match my meaningful functions with different information gathering shells. Now, meaningful functions may be a tiny part of the code that gets executed at runtime. If you're careful, however, they could be a large part of the code that you write. In the ideal world, all developers would spend 40 hours a week writing nothing but meaningful functions. If we focus on that goal and work together, someday, maybe, big maybe, we'll get there. So there you go, that's the 12 factor function. If you'd like to hear about the other eight constraints or see a more robust example, you can find it here. Thank you.