<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

 <title>Evan Meagher</title>
 <link href="https://evanm.website/atom.xml" rel="self"/>
 <link href="https://evanm.website/"/>
 <updated>2024-10-28T23:15:21+00:00</updated>
 <id>https://evanm.website/</id>
 <author>
   <name>Evan Meagher</name>
   <email>evan.meagher@gmail.com</email>
 </author>

 
 <entry>
   <title>More trail safety tips</title>
   <link href="https://evanm.website/2023/02/more-trail-safety-tips/"/>
   <updated>2023-02-21T00:00:00+00:00</updated>
   <id>https://evanm.website/2023/02/more-trail-safety-tips</id>
   <content type="html">&lt;p&gt;As a follow-up to &lt;a href=&quot;/2023/01/trail-running-first-aid-kit/&quot;&gt;my last post recommending that trail runners carry first aid kids&lt;/a&gt;, here are a few more tips for staying safe when running or hiking on trails.&lt;/p&gt;

&lt;h2 id=&quot;1-bring-water&quot;&gt;1. Bring water&lt;/h2&gt;

&lt;p&gt;You should always carry water if you’re planning to be out for more than an hour or if it’s particularly hot out. Heat stroke is &lt;a href=&quot;https://www.outsideonline.com/outdoor-adventure/environment/heat-related-illness-trail-running-death-philip-kreycik/&quot;&gt;scary&lt;/a&gt; and can sneak up on you.&lt;/p&gt;

&lt;h2 id=&quot;2-bring-your-phone&quot;&gt;2. Bring your phone&lt;/h2&gt;

&lt;p&gt;Your phone is a table stakes piece of safety equipment. With the obvious caveat that its usefulness deteriorates if you’re going outside of cell service.&lt;/p&gt;

&lt;p&gt;A phone helps you know where you are and allows you to call for help.&lt;/p&gt;

&lt;p&gt;With a good mapping app, you can track your progress along your planned route and avoid getting lost. Google/Apple Maps have decent coverage of urban trails, but you may want to graduate to a more trail-specific app like Gaia GPS or AllTrails if you’re going off the beaten path. I use Gaia GPS and love it.&lt;/p&gt;

&lt;p&gt;Most importantly, if you get into trouble, you need to be able to call for help. For instance, when I fell and gashed my knee against a retaining wall a few months ago, I was able to text my wife and ask her to pick me up at the nearest trailhead. This saved me from having to hobble all the way back to our house with an open wound&lt;sup&gt;&lt;a id=&quot;fn1ref&quot; href=&quot;#fn1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;In addition to these basic safety features, a phone can help you&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;identify plants and animals&lt;/li&gt;
  &lt;li&gt;write notes on ideas inspired by your time outdoors&lt;/li&gt;
  &lt;li&gt;play music/podcasts&lt;sup&gt;&lt;a id=&quot;fn2ref&quot; href=&quot;#fn2&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Maybe we’ll get to a world where a watch can cover all of these bases (Apple Watch Ultra?). But for now, don’t leave your phone in your car when you head out at a trailhead.&lt;/p&gt;

&lt;h2 id=&quot;3-bring-a-whistle&quot;&gt;3. Bring a whistle&lt;/h2&gt;

&lt;p&gt;On the same theme of being able to call for help, carrying a whistle is an easy way to help people find you if you get lost. They’re compact and can be heard from far away. So if you stumble down a hillside or find yourself way off the trail, you can make a bunch of noise with the whistle to alert other trail users in the area that you need help.&lt;/p&gt;

&lt;p&gt;Bonus points if you learn &lt;a href=&quot;https://www.advnture.com/features/hiking-whistles&quot;&gt;the basic distress signals&lt;/a&gt;. For the SOS signal in particular, here’s a handy visual mnemonic for remembering whether the short or long triplet comes first:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/more-trail-safety-tips/sos-morse-code.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;As for what whistle to get, I have one of &lt;a href=&quot;https://www.amazon.com/gp/product/B007S3OJTU/&quot;&gt;these&lt;/a&gt; on my keychain. It’s really slim, so doesn’t &lt;a href=&quot;https://www.youtube.com/watch?v=Dz2IrS6AlzA&quot;&gt;bulk up my keys&lt;/a&gt;. Alternatively, you could get a more traditional coach’s whistle like &lt;a href=&quot;https://www.amazon.com/gp/product/B003T16UUG/&quot;&gt;this&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;4-bring-your-id-and-insurance-card&quot;&gt;4. Bring your ID and insurance card&lt;/h2&gt;

&lt;p&gt;This one’s a little grim, but if you get seriously injured and can’t identify yourself, having an ID on your person helps emergency services personnel know who you are. Similarly, having an insurance card can help streamline your way through the healthcare system.&lt;/p&gt;

&lt;p&gt;You might also throw in a laminated card listing your emergency contacts. I don’t currently do this, but probably should add it to my kit.&lt;/p&gt;

&lt;p&gt;I slip these in a zippered pocket of my running shorts whenever I head out, which has the side benefit of letting me leave the rest of my wallet at home when driving to a trailhead.&lt;/p&gt;

&lt;p&gt;You can always throw in a credit card if you’re planning to hit a cafe or convenience store on your route (or else rely on Apple/Google Pay, since #1 above convinced you to bring your phone!).&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;There’s often a fine line between preparedness and paranoia, but basic safety precautions like these are painless and help prevent the worst outcomes if you run into trouble in the wilderness.&lt;/p&gt;

&lt;p&gt;Stay safe out there!&lt;/p&gt;

&lt;hr /&gt;

&lt;section class=&quot;footnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn1&quot;&gt;In that particular case, I would&apos;ve survived, but it would have sucked and increased the risk of a much longer recovery time. &lt;a href=&quot;#fn1ref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;li id=&quot;fn2&quot;&gt;Using headphones! Don&apos;t be the person blasting music nobody wants to hear in the wilderness.&lt;a href=&quot;#fn2ref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
  &lt;/ol&gt;
&lt;/section&gt;

</content>
 </entry>
 
 <entry>
   <title>Trail runners should pack first aid kits</title>
   <link href="https://evanm.website/2023/01/trail-running-first-aid-kit/"/>
   <updated>2023-01-02T00:00:00+00:00</updated>
   <id>https://evanm.website/2023/01/trail-running-first-aid-kit</id>
   <content type="html">&lt;p&gt;A couple weeks ago, I was &lt;a href=&quot;https://www.strava.com/activities/8275733291&quot;&gt;running&lt;/a&gt; on a trail near my house when I slipped and fell, gashing my knee against the corner of a crib wall&lt;sup&gt;&lt;a id=&quot;fn1ref&quot; href=&quot;#fn1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;It was thankfully just a flesh wound, but quite painful in the moment and enough to put fitness activities on hold for a while. The experience spurred me to put together a compact first aid kit to bring with me on trail runs, something I’ve been meaning to do for a while.&lt;/p&gt;

&lt;p&gt;This post explains why first aid kits are a worthwhile piece of gear for trail runners and describes what I’ve included in my kit.&lt;/p&gt;

&lt;h2 id=&quot;why-pack-a-first-aid-kit&quot;&gt;Why pack a first aid kit?&lt;/h2&gt;

&lt;p&gt;2022 was an exciting year for trail running as a sport. Sponsorship and prize money is flowing, people are hungry to spectate big races like UTMB, and more amateurs like me are hitting trails in their communities.&lt;/p&gt;

&lt;p&gt;One of the great things about running around in nature is that it lets you &lt;a href=&quot;https://en.wikipedia.org/wiki/Nature_therapy&quot;&gt;disconnect from the stresses of civilization&lt;/a&gt;. But this also means you’re going to be far from any kind of help if you get injured. Emergency services will take a while to get to you, doubly so if the trail is technical or not well mapped.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.outsideonline.com/outdoor-adventure/environment/heat-related-illness-trail-running-death-philip-kreycik/&quot;&gt;This article&lt;/a&gt; gives a particularly grim depiction of the risks you take when exerting yourself alone in remote areas. After reading it last summer, I did a little research on outfitting a minimal first aid kit that wouldn’t be annoying to pack when running. Go figure, I had to wait for my next injury out on the trail to complete the project.&lt;/p&gt;

&lt;h2 id=&quot;what-i-pack-in-mine&quot;&gt;What I pack in mine&lt;/h2&gt;

&lt;p&gt;There’s a bare minimum level of emergency preparedness that one should take when trail running. Aside from always bringing your phone&lt;sup&gt;&lt;a id=&quot;fn2ref&quot; href=&quot;#fn2&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;, it’s a good idea to carry a very basic set of first aid materials.&lt;/p&gt;

&lt;p&gt;A good goal is to help ensure that an injured person (you, a friend, or a fallen stranger you come across) can get patched up enough to make it to a trailhead for evac by car. Like any other piece of running gear, you want to keep things compact and light.&lt;/p&gt;

&lt;p&gt;I bought &lt;a href=&quot;https://www.amazon.com/dp/B07NZ1KM73&quot;&gt;the smallest first aid pouch I could find&lt;/a&gt;. You could of course use any old pouch or a ziplock bag, but I like this one because it’s red and clearly labeled.&lt;/p&gt;

&lt;p&gt;Whatever you choose should fit easily into whatever running vest or belt you use when journeying into remote areas. I use a &lt;a href=&quot;https://nakedsportsinnovations.com/pages/the-band&quot;&gt;Naked running band&lt;/a&gt; most of the time and the little red first aid kit fits nicely into any of its three pockets.&lt;/p&gt;

&lt;p&gt;Inside the kit, I keep a handful of items mostly focused on &lt;a href=&quot;https://www.irunfar.com/trail-first-aid-wound-management&quot;&gt;basic wound treatment&lt;/a&gt;:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Antiseptic wipes&lt;sup&gt;&lt;a id=&quot;fn3ref&quot; href=&quot;#fn3&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
  &lt;li&gt;Band-Aids&lt;/li&gt;
  &lt;li&gt;3”x3” gauze pads&lt;/li&gt;
  &lt;li&gt;A small roll of gauze for wrapping bandages&lt;/li&gt;
  &lt;li&gt;Antibiotic ointment&lt;/li&gt;
  &lt;li&gt;Ibuprofen&lt;/li&gt;
  &lt;li&gt;A &lt;a href=&quot;https://www.amazon.com/gp/product/B00KI1I7BU/&quot;&gt;pair of tweezers&lt;/a&gt;, in case I have to remove a tick from myself or my dog&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;img src=&quot;/images/trail-running-first-aid-kit/kit.jpg&quot; alt=&quot;Contents of my kit&quot; /&gt;&lt;/p&gt;

&lt;p&gt;A couple of the items photographed here were cannibalized from my home first aid kit. Be sure to restock any larger kit you take stuff from so you’re not out of something you need in an emergency.&lt;/p&gt;

&lt;h2 id=&quot;other-items-you-might-include&quot;&gt;Other items you might include&lt;/h2&gt;

&lt;p&gt;What you pack comes down to the types of emergency scenarios you want to be prepared for. Scrapes and cuts tend to be the most common form of injury from falling on a trail, hence the focus on wound care. But you might choose to include other items depending on your body or geography.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;If you’re prone to rolling ankles, athletic tape can be used to wrap up and immobilize a sore ankle to help you walk to the nearest trailhead.&lt;/li&gt;
  &lt;li&gt;Some Tecnu and a small rag would be a great addition for dealing with poison oak.&lt;/li&gt;
  &lt;li&gt;Ticks are a constant menace in my area, but you might want to pack items specific to other kinds of &lt;a href=&quot;https://www.trailrunnermag.com/training/trail-tips-training/wildlife-safety-for-runners-bear-snake-mountain-lions/&quot;&gt;wildlife&lt;/a&gt;. For instance, for bears, the general guidance is to make a ton of noise. A small airhorn can help with this—the Ginger Runner recommends &lt;a href=&quot;https://www.amazon.com/Shoreline-Marine-Eco-Air-Horn/dp/B01MY4YTKG&quot;&gt;this one&lt;/a&gt; in &lt;a href=&quot;https://www.youtube.com/watch?v=M0Qgk6Qbs9Y&amp;amp;t=21m11s&quot;&gt;his recent 2022 gear of the year video&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Stay safe out there!&lt;/p&gt;

&lt;hr /&gt;

&lt;section class=&quot;footnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn1&quot;&gt;A crib wall is a type of retaining structure that holds a trailbed in place along a hillside. &lt;a href=&quot;https://oaklandtrails.org/wp-content/uploads/2017/10/IMG_20171020_133436.jpg&quot;&gt;Here&apos;s&lt;/a&gt; an example (one that I helped build, in fact). &lt;a href=&quot;#fn1ref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;fn2&quot;&gt;It shocks me how common it is for folks to run without a phone. I know I wrote above how running it a great way to disconnect, but your phone should absolutely be seen as a table stakes piece of emergency equipment for communicating if you need help. &lt;a href=&quot;#fn2ref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;fn3&quot;&gt;Mild preference for benzalkonium chloride over alcohol, since they’re supposed to be better for cleaning wounds rather than the skin around wounds. &lt;a href=&quot;#fn3ref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
  &lt;/ol&gt;
&lt;/section&gt;
</content>
 </entry>
 
 <entry>
   <title>Momentum is magic</title>
   <link href="https://evanm.website/2022/02/momentum/"/>
   <updated>2022-02-07T00:00:00+00:00</updated>
   <id>https://evanm.website/2022/02/momentum</id>
   <content type="html">&lt;p&gt;A concept I’ve frequently found myself referring to lately is &lt;em&gt;momentum&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;In physics, momentum is a quantity that captures the tendency for a moving object to remain in motion. Once something gets moving, it takes energy to slow it down, and the forward motion often  becomes the new default state.&lt;/p&gt;

&lt;p&gt;This is a great metaphor for project work.&lt;/p&gt;

&lt;p&gt;At the start of a new project, it’s easy to procrastinate or become distracted by &lt;a href=&quot;https://www.intercom.com/blog/first-rule-prioritization-no-snacking/&quot;&gt;snacks&lt;/a&gt;. A proven way to overcome this inertia is to get a few quick wins that point you in the desired direction. The quick wins snowball into a tangible sense of momentum that drives a team forward towards the broader goal.&lt;/p&gt;

&lt;h2 id=&quot;what-can-momentum-look-like-in-practice&quot;&gt;What can momentum look like in practice?&lt;/h2&gt;

&lt;ol&gt;
  &lt;li&gt;A new team forms around some big problem. Say, customers have been complaining about slow page loads or the company has decided to prioritize a hairy migration to a new technology. The eventual goal feels daunting, but the team prioritizes a handful of low-hanging fruit tasks that feel like &lt;a href=&quot;https://medium.com/@jamesacowling/stepping-stones-not-milestones-e6be0073563f&quot;&gt;stepping stones&lt;/a&gt; towards the Big Outcome. After only a few days on these tasks, the team has collectively built a mental model of the problem and a clear path forward emerges.&lt;/li&gt;
  &lt;li&gt;In the realm of company-formation, the lean startup methodology is essentially a framework for generating momentum. By tightening the feedback loop between product development and customer feedback, a team is able to build confidence in a solution to a problem faced by some market.&lt;/li&gt;
  &lt;li&gt;I know that blogging is supposed to be good for my career. But I’m only able to get over the hump of motivation to write a thoughtful longish-form post once or twice per year. The post you’re reading is an attempt to leverage momentum by writing shorter posts when inspiration strikes. Stay tuned for whether it works!&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;takeaway&quot;&gt;Takeaway&lt;/h2&gt;

&lt;p&gt;A project’s success is determined by the team’s ability to generate and sustain momentum. A good way to generate early momentum in a project is to prioritize quick wins and explorations that tighten the feedback loop.&lt;/p&gt;

&lt;h2 id=&quot;further-reading&quot;&gt;Further reading&lt;/h2&gt;

&lt;p&gt;A few other good things out there on momentum and related concepts:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;https://leeorengel.medium.com/the-middle-slump-the-power-of-weekly-project-goals-3c23ad95c440&quot;&gt;The middle slump: the power of weekly project goals&lt;/a&gt;, by Leeor Engel&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://medium.com/@jamesacowling/stepping-stones-not-milestones-e6be0073563f&quot;&gt;Stepping Stones not Milestones&lt;/a&gt;, by James Cowling&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://taylorpearson.me/interestingtimes/become-like-water-my-friend/&quot;&gt;Become Like Water My Friend&lt;/a&gt;, by Taylor Pearson&lt;/li&gt;
  &lt;li&gt;Venkatesh Rao’s book &lt;a href=&quot;https://www.ribbonfarm.com/tempo/&quot;&gt;&lt;em&gt;Tempo&lt;/em&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;em&gt;Thanks to &lt;a href=&quot;https://www.lexrhoads.art&quot;&gt;Alexa Rhoads&lt;/a&gt; and &lt;a href=&quot;https://www.linkedin.com/in/kush-gupta/&quot;&gt;Kush
Gupta&lt;/a&gt; for reading and
providing feedback on drafts of this essay.&lt;/em&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>How to avoid overengineering</title>
   <link href="https://evanm.website/2020/10/how-to-avoid-overengineering/"/>
   <updated>2020-10-01T00:00:00+00:00</updated>
   <id>https://evanm.website/2020/10/how-to-avoid-overengineering</id>
   <content type="html">&lt;p&gt;This article considers the conditions that lead teams to produce overengineered software and describes how you can avoid falling prey to such conditions.&lt;/p&gt;

&lt;h2 id=&quot;what-do-we-mean-by-overengineering&quot;&gt;What do we mean by “overengineering”?&lt;/h2&gt;

&lt;p&gt;When a software developer says that a piece of software is &lt;em&gt;overengineered&lt;/em&gt;, they are saying that they think it has too many moving parts, too much abstraction, or an excessive emphasis on performance. The number of concepts required to understand the thing feels unreasonable.&lt;/p&gt;

&lt;p&gt;It’s a fundamentally subjective call, but you know it when you see it. Like a Ferrari at a go kart race, an overengineered system is out of scale with its operating environment and intended usage.&lt;/p&gt;

&lt;p&gt;But how does it happen? Are there certain conditions that lead teams to produce systems that observers would perceive as overengineered?&lt;/p&gt;

&lt;p&gt;To determine this, let’s consider two stereotypical software
engineering phenomena: cargo culting and a related pattern that I’ve
started to call “the Xoogler effect”.&lt;/p&gt;

&lt;p&gt;From there, we can characterize certain cognitive biases that drive a team towards overengineering.&lt;/p&gt;

&lt;h2 id=&quot;cargo-culting&quot;&gt;​​Cargo culting&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;/images/overengineering/cloudnativelandscape.jpg&quot; alt=&quot;The Trillion Dollar Homepage&quot; /&gt;&lt;span class=&quot;figure_caption&quot;&gt;Fig. 1. &lt;a href=&quot;https://landscape.cncf.io&quot;&gt;The Trillion Dollar Homepage&lt;/a&gt;.&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;A &lt;a href=&quot;https://en.wikipedia.org/wiki/Cargo_cult&quot;&gt;cargo cult&lt;/a&gt; is a cultural phenomenon in which technologically-advanced artifacts become objects of obsessive ritual to a group of people outside of the artifact-producing society. While the term has fallen out of favor within the field of anthropology (in acknowledgement of its reductive and colonialist overtones), it’s fairly common in software circles.&lt;/p&gt;

&lt;p&gt;To a software engineer, “cargo culting” is used pejoratively to refer to the adoption of a technology or practice based solely on its origin or popularity. Loosely, the thinking goes that if a tool, language, or convention was developed at or inspired by ideas from a large, successful company, then that tool must have contributed to the company’s success. Thus, in adopting it, you increase your odds of also succeeding.&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;“Era-defining companies like Intel and Google used OKRs, so we should too.”&lt;/li&gt;
  &lt;li&gt;“The SRE book talks about how Google relies on service level objectives, so using them will help our services become more reliable.”&lt;/li&gt;
  &lt;li&gt;“Most successful companies end up needing advanced load balancing and request-proxying systems to scale their microservices architectures. Our 10-person startup should adopt these systems in order to help us scale.”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Like incorporating in Delaware or only hiring graduates of name-brand universities, a particular practice correlating with notable instances of company growth doesn’t imply causation. Just because a &lt;a href=&quot;https://en.wikipedia.org/wiki/Authority_bias&quot;&gt;popular or successful&lt;/a&gt; company uses a technology doesn’t mean that it’s appropriate or worthwhile for your situation.&lt;/p&gt;

&lt;h2 id=&quot;the-xoogler-effect&quot;&gt;The Xoogler effect&lt;/h2&gt;

&lt;p&gt;When people leave engineering jobs at big, successful tech companies, they take their former employer’s engineering culture with them. This tends to be highly valuable, for both the technical acumen of the new company and the incoming engineer’s compensation package.&lt;/p&gt;

&lt;p&gt;But this tendency can be taken too far. The incoming employee, believing that they have a direct line to the state of the art, may go on to recreate systems in their former employer’s image to an unreasonable degree.&lt;/p&gt;

&lt;p&gt;Not to pick on Googlers, but something about that company’s culture really brings this out. There are many notable examples of Xooglers replicating Google-internal systems and practices in the outside world, either as independent startups or efforts within existing companies. I don’t find this terribly surprising, given the tone that’s set within Google—you spend your time there constantly being told that you’re among the best software engineers to walk the face of the Earth, using technologies unmatched in their power, quality, and scalability. It makes sense that former employees feel compelled to emulate things that worked at Google&lt;sup&gt;&lt;a id=&quot;fn1ref&quot; href=&quot;#fn1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;But this generalizes to other large and/or successful companies. Many people leave the productivity bubble of a “FAANG and friends” company and end up building tools and systems that they miss. To name but a few, this is how we got Thrift, Envoy, and &lt;a href=&quot;https://bazel.build&quot;&gt;three&lt;/a&gt; &lt;a href=&quot;https://www.pantsbuild.org/&quot;&gt;different&lt;/a&gt; &lt;a href=&quot;https://buck.build&quot;&gt;tools&lt;/a&gt; based on Google’s build system.&lt;/p&gt;

&lt;h2 id=&quot;cognitive-biases&quot;&gt;Cognitive biases&lt;/h2&gt;

&lt;p&gt;I think these two phenomena can be linked to a handful of widely-known cognitive biases. Cargo culting is a clear manifestation of &lt;a href=&quot;https://en.wikipedia.org/wiki/Authority_bias&quot;&gt;authority bias&lt;/a&gt;. And the Xoogler effect seems related to &lt;a href=&quot;https://en.wikipedia.org/wiki/Law_of_the_instrument&quot;&gt;the law of the instrument&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It’s rational to want to stay within your &lt;a href=&quot;https://fs.blog/2013/12/circle-of-competence/&quot;&gt;circle of competence&lt;/a&gt;, but it can be counterproductive in excess. When you’ve been inculcated in the expert use of hammers, every problem looks like a nail. Your thinking in new environments is &lt;a href=&quot;https://en.wikipedia.org/wiki/Anchoring_(cognitive_bias)&quot;&gt;anchored&lt;/a&gt; by prior experience in old environments, which can impede learning and the development of new skills.&lt;/p&gt;

&lt;p&gt;And it turns out that these two patterns can feed on each other. Cargo culting is &lt;em&gt;catalyzed by&lt;/em&gt; the Xoogler effect in cases when a former big company employee’s experience is uncritically venerated by new colleagues.&lt;/p&gt;

&lt;h2 id=&quot;how-to-resist-the-urge-to-overengineer&quot;&gt;How to resist the urge to overengineer&lt;/h2&gt;

&lt;p&gt;Resisting the temptation to overengineer requires one to be honest with themselves about the context in which they’re operating.&lt;/p&gt;

&lt;p&gt;You should always design systems to address problems that are in front of you instead of falling for solutions to problems faced by big companies in the past. You shouldn’t base your company’s infrastructure on GitHub stars. And as wistful as you may be for your last company’s tools, they may not be as applicable to your current situation as you think.&lt;/p&gt;

&lt;h3 id=&quot;assessing-cargo-without-becoming-a-cultist&quot;&gt;Assessing cargo without becoming a cultist&lt;/h3&gt;

&lt;p&gt;When evaluating a popular tool, language, or convention, it’s worthwhile to take the time to understand the underlying forces that motivated its invention&lt;sup&gt;&lt;a id=&quot;fn2ref&quot; href=&quot;#fn2&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;. Before making any decisions, try to contextualize a technology within the environment that formed it. From there, you can pattern match that environment to your own in order to determine if the technology is appropriate.&lt;/p&gt;

&lt;p&gt;As an example, let’s consider everyone’s favorite overengineering punching bag: Kubernetes.&lt;/p&gt;

&lt;p&gt;Kubernetes traces its conceptual lineage to Borg&lt;sup&gt;&lt;a id=&quot;fn3ref&quot; href=&quot;#fn3&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;, the cluster-management system that’s run Google’s production workloads for over a dozen years. The main value that Borg provides to Alphabet is its ability to maximize the capital efficiency of their datacenters. The technology that we now call “container orchestration” allowed them to get more computing oomph out of their fleet by maximizing utilization and making more efficient use of machines they’d already paid for.&lt;/p&gt;

&lt;p&gt;Is maximizing capital efficiency of your datacenter or cloud environment a concern for your company? If you believe Kubernetes offers other benefits&lt;sup&gt;&lt;a id=&quot;fn4ref&quot; href=&quot;#fn4&quot;&gt;4&lt;/a&gt;&lt;/sup&gt;, are you confident that they outweigh the complexity and maintenance overhead?&lt;/p&gt;

&lt;p&gt;I find this thought process helpful when evaluating new tools, patterns, frameworks, or management practices. Conventional wisdom advocates that you fully understand a problem before applying a solution to it. It’s also important to understand the conditions that led to a solution and how those conditions align with those you find yourself in.&lt;/p&gt;

&lt;p&gt;Regardless of the decision you end up making, this process is likely to make you a better engineer. The job is fundamentally about building systems to solve problems at reasonable cost. That cost is measured not only as upfront capital expenditure, but in the ongoing drag associated with maintenance and cognitive load. More often than we realize, engineering is about right-sizing a solution in light of these ongoing costs.&lt;/p&gt;

&lt;h2 id=&quot;further-reading&quot;&gt;Further reading&lt;/h2&gt;

&lt;p&gt;A few links to other reading material on related topics:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://johnsalvatier.org/blog/2017/reality-has-a-surprising-amount-of-detail&quot;&gt;Reality has a surprising amount of detail&lt;/a&gt;, by John Salvatier&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://lethain.com/learn-to-never-be-wrong/&quot;&gt;Learn to never be wrong&lt;/a&gt;, by Will Larson&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://boringtechnology.club&quot;&gt;Choose Boring Technology&lt;/a&gt;, by Dan McKinley&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/2016/03/synthesis-over-invention/&quot;&gt;Synthesis over invention&lt;/a&gt;, by yours truly&lt;/li&gt;
  &lt;li&gt;The concept of “integrative thinking”, as described in Roger Martin’s book, &lt;a href=&quot;https://www.goodreads.com/book/show/2001132.The_Opposable_Mind&quot;&gt;The Opposable Mind&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;em&gt;Thanks to
&lt;a href=&quot;https://www.linkedin.com/in/paupadhyay/&quot;&gt;Parth Upadhyay&lt;/a&gt;,
&lt;a href=&quot;https://thisisehsan.com&quot;&gt;Ehsan Noursalehi&lt;/a&gt;,
&lt;a href=&quot;https://twitter.com/wil&quot;&gt;Wilhelm Bierbaum&lt;/a&gt; for reading
and providing feedback on drafts of this essay.&lt;/em&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;section class=&quot;footnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn1&quot;&gt;Not to be that guy, but for full disclosure, I&apos;ve had two stints at Google/Alphabet in my career, first as a lowly intern in 2010 and more recently leading a software team on an early-stage project at X. &lt;a href=&quot;#fn1ref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;fn2&quot;&gt;This research can often be done by reading blog posts or conference papers related to the technologies in question (major plug for &lt;a href=&quot;https://blog.acolyer.org&quot;&gt;The Morning Paper&lt;/a&gt;&apos;s digestible summaries of papers). Recorded conference talks can be good sources, too. If you are networking-inclined, nothing beats being able to hear from experienced people directly. &lt;a href=&quot;#fn2ref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;fn3&quot;&gt;Or really, &lt;a href=&quot;https://research.google/pubs/pub41684/&quot;&gt;Omega&lt;/a&gt;. Long story. &lt;a href=&quot;#fn3ref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;fn4&quot;&gt;Container orchestration tools are marketed as solutions for developer productivity and software scalability, which has always felt like revisionist history to me. In my understanding, these were not the primary concerns this technology was invented to address. &lt;a href=&quot;#fn4ref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
  &lt;/ol&gt;
&lt;/section&gt;
</content>
 </entry>
 
 <entry>
   <title>Things I Learned From Five Years in Climate Tech</title>
   <link href="https://evanm.website/2020/02/five-years-in-energy/"/>
   <updated>2020-02-24T00:00:00+00:00</updated>
   <id>https://evanm.website/2020/02/five-years-in-energy</id>
   <content type="html">&lt;p&gt;&lt;img src=&quot;/images/energy-startup-lessons/glacier.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This post also &lt;a href=&quot;https://thenextweb.com/syndication/2020/03/20/6-things-i-learned-from-working-in-climate-tech-startups/&quot;&gt;appeared on The Next Web&lt;/a&gt; in March 2020.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Over the past five years, I’ve worked at two startups in what is now being called the climate tech sector&lt;sup&gt;&lt;a id=&quot;fn1ref&quot; href=&quot;#fn1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;. Given the recent surge in interest in this space, I thought it would be worthwhile to record a handful of lessons that I’ve learned from this experience. These lessons span business strategy and the realities of the electric utility industry.&lt;/p&gt;

&lt;h2 id=&quot;timeline-what-has-this-guy-actually-done&quot;&gt;Timeline: What has this guy actually done?&lt;/h2&gt;

&lt;p&gt;I left Twitter in early 2015 with the goal of finding software opportunities in grid modernization&lt;sup&gt;&lt;a id=&quot;fn2ref&quot; href=&quot;#fn2&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;Soon thereafter, I met a couple guys who were leaving &lt;abbr title=&quot;Lawrence Berkeley National Laboratory&quot;&gt;LBNL&lt;/abbr&gt; to start a company around &lt;a href=&quot;https://pdfs.semanticscholar.org/931c/9a2e7a5843ed077e8564455b551aff74a655.pdf&quot;&gt;a novel sensing technique&lt;/a&gt; for monitoring home energy use. I joined them as the first employee of Whisker Labs, where we set about making it cheaper and easier to mine residential energy data. After a handful of successful pilots and an &lt;a href=&quot;https://venturebeat.com/2016/12/05/earth-networks-acquires-whisker-labs-and-launches-diy-home-energy-monitor/&quot;&gt;acquisition&lt;/a&gt;, I parted ways with Whisker Labs in 2018.&lt;/p&gt;

&lt;p&gt;I then spent some time developing an idea to address painpoints I’d observed while working with electric utilities at Whisker Labs. I ended up joining &lt;a href=&quot;https://blog.x.company/why-the-electric-grid-needs-a-moonshot-6dbac9b8b2c2&quot;&gt;an early-stage team at X&lt;/a&gt; that shared my thinking on this specific problem space. I can’t say much of anything about this project, due to the secretive nature of X.&lt;/p&gt;

&lt;p&gt;The following unordered and subjective list reflects my thinking about startups in the energy space, particularly those that aim to sell software to utilities.&lt;/p&gt;

&lt;h2 id=&quot;1-consumers-dont-care-about-energy&quot;&gt;1. Consumers don’t care about energy&lt;/h2&gt;

&lt;p&gt;The ideal energy system is one that fades into the background. The overwhelming majority of people don’t ever want to think about how electricity is delivered to their homes or how much of it they’re using. No one actually wants to look at time series plots of energy usage. They just want the lights to turn on when they flip a switch or yell at Alexa.&lt;/p&gt;

&lt;p&gt;Early adopter types might enjoy seeing in real time how much power their solar panels are generating or their car is drawing, but this is not functionality that will drive user engagement or revenue at scale.&lt;/p&gt;

&lt;h2 id=&quot;2-exits-are-different-than-those-for-traditional-tech-startups&quot;&gt;2. Exits are different than those for traditional tech startups&lt;/h2&gt;

&lt;p&gt;To be blunt—you’re probably not going to sell your climate tech startup to Facebook. In the event you &lt;em&gt;do&lt;/em&gt; get acquired, a statistically likely buyer is an oil major like Exxon Mobil, an industrial giant like Siemens, or a European utility like E.ON, Enel, or ENGIE. These companies aren’t going to pay $10 MM per employee or cater to your taste in programming languages or productivity software.&lt;/p&gt;

&lt;p&gt;This isn’t to say that energy startups can’t have exits that make money for founders and investors. But the scale of these exits and the character of acquiring companies is typically not what you see for software startups in other venture-fueled verticals.&lt;/p&gt;

&lt;h2 id=&quot;3-you-live-or-die-by-the-trust-you-build-in-the-industry&quot;&gt;3. You live or die by the trust you build in the industry&lt;/h2&gt;

&lt;p&gt;Energy is the ultimate example of an industry where “build it and they will come” doesn’t work. For utilities, downtime is often measured in fatalities and switching costs are massive. There is huge institutional inertia impeding the adoption of new technology.&lt;/p&gt;

&lt;p&gt;Overcoming this inertia takes a long time and requires that your team include deep subject matter experts who can speak the language of the industry. As in any other enterprise setting, you need to build real relationships with stakeholders up and down your target customer’s org chart.&lt;/p&gt;

&lt;p&gt;And realize that the people who write checks are typically not the people who will use your software. As a consequence, the quality or state-of-the-artness of your technology often won’t be a primary contributor to your success.&lt;/p&gt;

&lt;h2 id=&quot;4-energy-economics-are-a-poor-match-for-venture-capital&quot;&gt;4. Energy economics are a poor match for venture capital&lt;/h2&gt;

&lt;p&gt;Fundamentally, energy is a commodity good. This translates to razor-thin margins for companies whose primary product is electricity or natural gas. If your business involves selling to these companies, then you inherit their commodity-driven nature, making it very difficult to achieve returns that are attractive to investors used to SaaS companies with 80% margins.&lt;/p&gt;

&lt;p&gt;The way many successful companies avoid this problem is by changing the nature of the product they offer. By framing your business around something other than energy/savings (e.g. comfort, convenience, automation, luxury), you can escape the razer-thin margin game. Your overarching mission can still be to save energy or reduce emissions, but as a by-product of a valuable service that customers will pay real money for. In consumer settings, this approach can also help work around the fact that most consumers don’t care about energy (discussed above).&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Instead of batteries, &lt;a href=&quot;https://www.tesla.com/&quot;&gt;sell cars&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;Instead of home energy efficiency solutions, sell &lt;a href=&quot;https://nest.com/&quot;&gt;smart thermostats&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;Instead of commercial energy efficiency solutions, sell &lt;a href=&quot;https://www.comfyapp.com/&quot;&gt;employee comfort&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;5-beware-the-utility-sales-cycle&quot;&gt;5. Beware the utility sales cycle&lt;/h2&gt;

&lt;p&gt;The glacial pace of the utility sales cycle has a big impact on cash management and fundraising for startups. Companies aiming to sell to utilities need to be extra mindful of runway and plan far in advance the traction metrics they can realistically raise money on.&lt;/p&gt;

&lt;p&gt;Utilities are some of the most-regulated and slowest-moving companies in existence. They plan budgets in multi-year increments and introduce new technologies over the course of decades. Staying alive as a utility vendor or service provider requires minimizing your company’s burn rate and scraping together enough early pilot projects to show traction to the next round’s investors.&lt;/p&gt;

&lt;p&gt;For instance, say you start a company with money from friends and family to build a product that will help utilities decarbonize the residential sector. In order to raise money in 9–12 months, institutional investors will expect to see one or two signed pilot agreements and demonstrated progress towards the milestones of these pilots.&lt;/p&gt;

&lt;p&gt;So you send emails, get on the phone, and rack up airline miles to sell the stuffing out of your idea. You convince a decision-maker at a utility across the country that your product is the perfect fit for a demonstration project they’ve been planning for months. This person introduces you to an executive with “Innovation” in their title and helps you develop a case for why your product is exactly what they’re looking for.&lt;/p&gt;

&lt;p&gt;Three months later, you’ve made it through an &lt;abbr title=&quot;Request For Proposals&quot;&gt;RFP&lt;/abbr&gt; process and landed a $5 MM pilot. The pilot is split into three phases over the course of the next five years, with most of the money coming in the last phase. $500k lands in your bank account for phase zero, which only extends your runway three months once you factor in the people you’ll need to hire. Seven months has passed since your friends-and-family round and you’re losing sleep over the number of parenthesized numbers in your financial spreadsheets.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;An aside on funding—grants (for instance, from &lt;a href=&quot;https://www.sbir.gov/&quot;&gt;the Small Business Innovation Research program&lt;/a&gt; or the &lt;a href=&quot;https://www.grants.gov/learn-grants/grant-making-agencies/department-of-energy.html&quot;&gt;Department of Energy&lt;/a&gt;) can be an alternative source of early stage funding that is better suited to many energy projects than traditional VC. They provide patient capital and, in many cases, don’t take an equity stake. Grants can help get an R&amp;amp;D project off the ground without having to jump on the VC treadmill right out of the gate.&lt;/p&gt;

&lt;p&gt;But grants do have downsides. You lock yourself into arbitrary demonstration milestones that tend to quickly diverge from where market opportunities lie. Customer development should always come first, and you run the risk of getting sidetracked with the care and feeding of grant milestones.&lt;/p&gt;

&lt;h2 id=&quot;6-policy-is-more-important-than-technology&quot;&gt;6. Policy is more important than technology&lt;/h2&gt;

&lt;p&gt;As far as bending the warming curve towards 1.5° C is concerned, I think policy and regulatory reform is currently a larger source of leverage than technology. In particular, carbon pricing (&lt;a href=&quot;https://www.washingtonpost.com/climate-environment/the-fastest-way-to-cut-carbon-emissions-is-a-fee-and-a-rebate-top-leaders-say/2020/02/13/b63b766c-4cfc-11ea-bf44-f5043eb3918a_story.html&quot;&gt;if done right&lt;/a&gt;) is the single most effective tool we have to reduce global emissions.&lt;/p&gt;

&lt;p&gt;Don’t get me wrong—technology innovation is obviously a primary means to addressing climate change. But I feel more and more that we’re approaching the point at which technology has gone about as far as it can within the confines of a 20th century policy regime. Buying EVs and solar panels make us feel good, but only represents marginal progress while oil subsidies artificially prop up the internal combustion engine and campaign finance laws give incumbent fossil fuel companies undue influence to hamstring the deployment of clean technologies.&lt;/p&gt;

&lt;p&gt;Even within an antagonistic policy framework, solar, wind, and batteries are proving to be cost-competitive with fossil fuels in many geographies. Imagine how far they’ll go once the rules actually incentivize them at scale.&lt;/p&gt;

&lt;p&gt;I don’t believe that we’ll get where we need to go without a global price on carbon. This is why &lt;a href=&quot;/2019/03/my-climate-lobby-hobby/&quot;&gt;I volunteer with the Citizens’ Climate Lobby&lt;/a&gt; to build political will for a national carbon fee and dividend policy in the US. It seems insurmountable given the current political climate, but you’d be surprised how much progress we’ve made.&lt;/p&gt;

&lt;h2 id=&quot;closing-words-of-encouragement&quot;&gt;Closing words of encouragement&lt;/h2&gt;

&lt;p&gt;As I’m sure this essay has made clear, five years of building technologies for sale to utilities has left me rather burnt out by the slow pace and legacy nature of the energy industry. That being said, I remain excited by the incredible work being done throughout the energy/climate startup ecosystem. I don’t mean to dissuade anyone from taking the plunge, but founding teams need to know what they’re signing up for.&lt;/p&gt;

&lt;p&gt;And investors need to know what they’re funding. Energy is not the realm of hyper-growth SaaS apps that can scale to 10 million users in the blink of an eye. A utility might only have 20 people in their organization that will meaningfully use a specialized product. And it could take three years of sales and integration legwork to get a product paid for and incorporated into day-to-day work.&lt;/p&gt;

&lt;p&gt;So take these lessons with a grain of salt. If you’re setting out on a startup journey in the energy sector, your mileage will undoubtedly vary. I’m rooting for you.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;em&gt;Thanks to
&lt;a href=&quot;https://www.linkedin.com/in/apoorv-bhargava/&quot;&gt;Apoorv Bhargava&lt;/a&gt;,
&lt;a href=&quot;https://www.linkedin.com/in/nickolasclarke/&quot;&gt;Nick Clarke&lt;/a&gt;,
&lt;a href=&quot;https://www.linkedin.com/in/alexarhoads/&quot;&gt;Alexa Rhoads&lt;/a&gt;, and
&lt;a href=&quot;https://www.linkedin.com/in/oschetrit/&quot;&gt;Oren Schetrit&lt;/a&gt; for reading
and providing feedback on drafts of this essay.&lt;/em&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;section class=&quot;footnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn1&quot;&gt;Née energy tech, green tech, clean tech. &lt;a href=&quot;#fn1ref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;fn2&quot;&gt;By grid modernization, I’m referring to technology often associated with the buzzword “smart grid”. It involves augmenting the electric grid with information technologies in order to make operations safer, cheaper, and more flexible. Modernizing the grid is table stakes if we want to decarbonize the economy, as it&apos;s fundamentally not designed for a world of intermittent renewables and massive energy demand spikes from EVs. &lt;a href=&quot;#fn2ref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
  &lt;/ol&gt;
&lt;/section&gt;
</content>
 </entry>
 
 <entry>
   <title>My Climate Lobby Hobby</title>
   <link href="https://evanm.website/2019/03/my-climate-lobby-hobby/"/>
   <updated>2019-03-29T00:00:00+00:00</updated>
   <id>https://evanm.website/2019/03/my-climate-lobby-hobby</id>
   <content type="html">&lt;p&gt;In a departure from this blog’s typical tech-related content, I’d like
to write about some work I’ve done outside of the confines of my day
job(s).&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/my-climate-lobby-hobby/CCL-Logo-H2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;For the past few years, I’ve volunteered as a member of an
organization called the &lt;a href=&quot;https://citizensclimatelobby.org/&quot;&gt;Citizens’ Climate
Lobby&lt;/a&gt;. CCL is a non-partisan,
non-profit advocacy group whose mission is to build political will for
solutions to climate change. Specifically, the group is laser-focussed
on lobbying Congress to enact a policy called &lt;a href=&quot;https://en.wikipedia.org/wiki/Fee_and_dividend&quot;&gt;Carbon Fee and
Dividend&lt;/a&gt;. This policy
would make it more expensive for companies to extract and import
fossil fuels, and thus help steer the economy towards better, cleaner
sources of energy.&lt;/p&gt;

&lt;p&gt;The hook of the policy (in contrast to others like
California’s cap-and-trade system) is that the revenue generated by
the carbon tax would be distributed evenly to the populace, as monthly
dividend checks to all US citizens&lt;sup&gt;&lt;a id=&quot;fn1ref&quot; href=&quot;#fn1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;To cut to the chase, I’m excitedly writing this post because my
congresswoman, Rep. Barbara Lee, this week co-sponsored the bill we’ve
been lobbying for, &lt;a href=&quot;https://www.congress.gov/bill/116th-congress/house-bill/763&quot;&gt;the Energy Innovation and Carbon Dividend
Act&lt;/a&gt;. This
is the culmination of many meetings and calls with congressional
staff, letters to the editor, town hall appearances, fliers handed out
at farmers’ markets, and alliance-building with other environmental
groups. This achievement for our local CCL chapter here in Alameda
County is one among many that are happening all over the country
(&lt;em&gt;including&lt;/em&gt; red districts) as we build a base of bipartisan support
for this carbon pricing policy.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/my-climate-lobby-hobby/feb2019_lee_lobby_meeting.jpg&quot; alt=&quot;&quot; /&gt;&lt;span class=&quot;figure_caption&quot;&gt;Fig. 1. Photo of our team at a recent lobbying
 meeting at Rep. Lee’s office in Oakland.&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;That’s my story. I’m really proud of this accomplishment for our
chapter and I wanted to share it. Getting involved with CCL has been a
desperately-needed breath of fresh air amid the toxic political
climate and news cycle we’re all living in. And it’s been a great way
to meet inspiring people and learn the ground game of activism.&lt;/p&gt;

&lt;p&gt;There are glimmers of hope for representative democracy in America,
and it looks a lot like the Citizens’ Climate Lobby.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;em&gt;Thanks to &lt;a href=&quot;https://www.drtedobbard.com/&quot;&gt;Dr. Ted Obbard&lt;/a&gt;, chapter
co-lead of &lt;a href=&quot;http://cclalameda.org&quot;&gt;CCL Alameda&lt;/a&gt;, for reading and
providing feedback on drafts of this essay.&lt;/em&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol&gt;
&lt;li id=&quot;fn1&quot;&gt; There are &lt;a href=&quot;https://citizensclimatelobby.org/remi-report/&quot;&gt;a bunch&lt;/a&gt; of
features that make the policy great, regardless of which side of the
aisle you’re on. It’s effective because it would drastically and
rapidly reduce carbon emissions. It’s good for the economy, given that
it doesn’t increase the size of the government. It’s forecasted to
create millions of jobs and it give companies predictable targets for
fuel prices. And by putting money directly into people’s pockets every
month, it’s an equitable solution that &lt;a href=&quot;https://citizensclimatelobby.org/household-impact-study/&quot;&gt;disproportionally&lt;/a&gt;
helps out households in the lower end of the income spectrum. &lt;a href=&quot;#fn1ref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content>
 </entry>
 
 <entry>
   <title>Defining resiliency in energy and software</title>
   <link href="https://evanm.website/2017/10/resiliency-in-energy-and-software/"/>
   <updated>2017-10-19T00:00:00+00:00</updated>
   <id>https://evanm.website/2017/10/resiliency-in-energy-and-software</id>
   <content type="html">&lt;p&gt;&lt;img src=&quot;/images/resiliency/ali_frazier.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The word “resiliency” is all the rage right now.&lt;/p&gt;

&lt;p&gt;The notion of resiliency is uniquely applicable in a &lt;em&gt;systems&lt;/em&gt;
context. Specifically, it is a desirable feature of any system that is
made up of many moving parts that operate in a distributed,
coordinated fashion.&lt;/p&gt;

&lt;p&gt;In such systems, failure is an inevitability that must be planned
for. Whether you’re talking about an electricity grid or a network of
software services, the study and construction of distributed systems
necessarily entail having to worry about component failure. Planning
for failure and designing &lt;a href=&quot;/2017/02/systems-thinkpiece&quot;&gt;systems&lt;/a&gt; to be
able to mitigate its impact is at the core of resiliency.&lt;/p&gt;

&lt;p&gt;To study the implications of this mindset, let’s take a look at how
resiliency is defined in the electricity generation, transmission, and
distribution industry.&lt;/p&gt;

&lt;h2 id=&quot;setting-the-stage&quot;&gt;Setting the stage&lt;/h2&gt;

&lt;p&gt;Within the US energy sector, a debate is raging
among
&lt;a href=&quot;https://www.greentechmedia.com/articles/read/microgrids-hurricanes-resiliency&quot;&gt;industry analysts&lt;/a&gt;,
&lt;a href=&quot;https://arstechnica.com/science/2017/08/energy-departments-contentious-baseload-study-is-out/&quot;&gt;regulators&lt;/a&gt;,
and vendors on the degree to which renewable energy resources
could
&lt;a href=&quot;https://www.greentechmedia.com/articles/read/rick-perry-congress-doe-coal-nuclear-cost-freedom&quot;&gt;wreak&lt;/a&gt; &lt;a href=&quot;http://thehill.com/policy/energy-environment/355673-conservative-think-tank-plan-to-help-coal-nuclear-power-arbitrary&quot;&gt;havoc&lt;/a&gt; on
our electricity grid. On the one hand, proponents of the status quo of
subsidized fossil fuels and centralized power generation are sowing
fear that intermittent solar and wind generation will cause brownouts
and systemic failures. Countering this narrative is a growing pile of
research and field evidence that indicate that the distributed nature
of renewables—and particularly the one-two punch
of
&lt;a href=&quot;http://www.utilitydive.com/news/is-the-future-finally-here-for-utility-scale-solar-plus-storage/449496/&quot;&gt;solar-plus-storage&lt;/a&gt;—will
make the grid &lt;em&gt;more&lt;/em&gt; resilient to systemic failures.&lt;/p&gt;

&lt;p&gt;These terms (reliability, resiliency) are
also &lt;a href=&quot;https://landing.google.com/sre/&quot;&gt;all the rage&lt;/a&gt; in the software
industry. In fact, if you blur your eyes a little and think abstractly
about the systems involved, recent trends in software architecture
look strikingly similar to those in the renewable and distributed
energy resource space.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/resiliency/centralized_vs_distributed_energy_and_data.png&quot; alt=&quot;&quot; /&gt;&lt;span class=&quot;figure_caption&quot;&gt;Fig. 1. Centralized vs distributed
 architectures of power and data generation, transmission, storage,
 and consumption.&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;The last couple of decades saw similar arcs in the trajectories of
SaaS-/IoT-era software stacks and renewable energy resources. In place
of relying on big, centralized resources, we’re seeing more use of
distributed resources. Analogous to the onslaught of microservices and
smart devices, the future of the energy grid lies in energy harvested
from solar panels
or &lt;a href=&quot;https://en.wikipedia.org/wiki/Demand_response&quot;&gt;demand response&lt;/a&gt;
providers, and stored
in
&lt;a href=&quot;http://news.mit.edu/2016/battery-molten-metals-0112&quot;&gt;batteries&lt;/a&gt;,
&lt;a href=&quot;https://www.tesla.com/model3&quot;&gt;cars&lt;/a&gt;, or
even
&lt;a href=&quot;https://www.greentechmedia.com/articles/read/the-water-heater-as-grid-battery-version-2-0&quot;&gt;water heaters&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;defining-reliability-and-resiliency&quot;&gt;Defining reliability and resiliency&lt;/h2&gt;

&lt;p&gt;In my experience in the software industry, “resiliency” is one of
those whizbang words that’s fun to throw around, but remains generally
ill-defined. Often, reliability and resiliency are used by executives
to describe effort spent paying down technical debt.&lt;/p&gt;

&lt;table class=&quot;table-bordered&quot;&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th class=&quot;col-sm-4&quot;&gt;What is said&lt;/th&gt;
      &lt;th class=&quot;col-sm-8&quot;&gt;What is meant&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td class=&quot;col-sm-4&quot;&gt;&quot;We&apos;re going to focus on reliability this quarter.&quot;&lt;/td&gt;
      &lt;td class=&quot;col-sm-8&quot;&gt;&quot;I&apos;m getting flak from customers/investors about our app not working, so I want you to fix bugs, reduce latencies, and increase success rates, potentially at the cost of timely feature development.&quot;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;By comparison, these terms are very precisely &lt;a href=&quot;https://ics-cert.us-cert.gov/sites/default/files/ICSJWG-Archive/QNL_MAR_16/reliability%20and%20resilience%20pdf.pdf&quot;&gt;defined&lt;/a&gt; and &lt;a href=&quot;http://prod.sandia.gov/techlib/access-control.cgi/2017/171493.pdf&quot;&gt;measured&lt;/a&gt; in the electric power industry.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;For the electric sector, reliability can be defined as the
  ability of the power system to deliver electricity in the quantity
  and with the quality demanded by users. (…) Reliability means that
  lights are always on in a consistent manner.&lt;/p&gt; &lt;cite&gt;Aaron
  Clark-Ginsberg, &lt;a href=&quot;https://ics-cert.us-cert.gov/sites/default/files/ICSJWG-Archive/QNL_MAR_16/reliability%20and%20resilience%20pdf.pdf&quot;&gt;&lt;em&gt;What’s
  the Difference between Reliability and Resilience&lt;/em&gt;&lt;/a&gt;&lt;/cite&gt;
&lt;/blockquote&gt;

&lt;p&gt;In this light, reliability is binary along the time dimension—your
thing either works under a given set of conditions or it
doesn’t. These conditions are typically defined in a service-level
agreement (SLA), which a service is charged with adhering to over
time.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/resiliency/stripe_status.png&quot; alt=&quot;&quot; /&gt;&lt;span class=&quot;figure_caption&quot;&gt;Fig. 2. Screenshot
 from &lt;a href=&quot;https://status.stripe.com/&quot;&gt;Stripe’s system status dashboard&lt;/a&gt;,
 which is used to signal whether or not their systems are functioning
 properly.&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;Resilience is more complicated.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Resilience, stemming from the root &lt;em&gt;resilio&lt;/em&gt;, meaning to leap or
spring back, is concerned with the ability of a system to recover
and, in some cases, transform from adversity.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Clark-Ginsberg’s report goes on to say that “resilience operates from
a systems perspective, understanding incidents as a complex process
occurring at the intersection of natural and human forces across
multiple scales, evolving and changing over time.”&lt;/p&gt;

&lt;p&gt;Reliability and resiliency, while related, are fundamentally different
attributes. Resilience involves the gray area of partial failure, as
in the case of a rolling brownout or a broken widget on an
otherwise functional web page. It implies thinking of a service as a
system of constituent components, with too many moving parts to be
reasonably characterized using a simple “does it work or not” rubric.&lt;/p&gt;

&lt;h2 id=&quot;we-arent-so-different-you-and-i&quot;&gt;We aren’t so different, you and I&lt;/h2&gt;

&lt;p&gt;With respect to the nature of renewable energy and software systems,
it’s not a coincidence that both can be characterized as distributed
systems or that both lend themselves towards discussions of
resiliency.&lt;/p&gt;

&lt;p&gt;In both cases, intermittent and composable resources require thinking
about a service as a distributed system. Part of distributed systems
theory and practice is the notion that failure is inevitable, and thus
the topic of being resilient to failure is paramount.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;em&gt;Thanks to &lt;a href=&quot;https://www.linkedin.com/in/oschetrit&quot;&gt;Oren Schetrit&lt;/a&gt;
and &lt;a href=&quot;https://twitter.com/bd&quot;&gt;Berk Demir&lt;/a&gt; for reading and providing
feedback on drafts of this essay.&lt;/em&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Lessons Learned Putting a Thing on the Internet</title>
   <link href="https://evanm.website/2017/05/lessons-learned-putting-a-thing-on-the-internet/"/>
   <updated>2017-05-02T00:00:00+00:00</updated>
   <id>https://evanm.website/2017/05/lessons-learned-putting-a-thing-on-the-internet</id>
   <content type="html">&lt;p&gt;&lt;em&gt;This is a text version of a talk I gave on May 1st, 2017 at
&lt;a href=&quot;https://nvite.com/WhiskerLabs/lower2&quot;&gt;an event&lt;/a&gt; that
&lt;a href=&quot;https://whiskerlabs.com&quot;&gt;my company&lt;/a&gt; hosted focusing on our
experience bringing a connected device to market.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;My talk focused on the software side of the company, presenting three
lessons that we’ve taken to heart after two years in the trenches
building a data-intensive hardware product. Slides available
&lt;a href=&quot;https://speakerdeck.com/evanm/lessons-learned-writing-software-at-whisker-labs&quot;&gt;here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;At Whisker Labs, our goal is to unlock value from the electrical
networks within homes.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/thing-lessons/panel-photo.jpg&quot; alt=&quot;&quot; /&gt;&lt;span class=&quot;figure_caption&quot;&gt;Fig. 1. Whisker Labs prototype device
 installed on a circuit breaker panel.&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;I bet you don’t often think about your home’s electrical system. We
just turn stuff on and off as we go about our day. And yet, this
&lt;a href=&quot;/2017/02/systems-thinkpiece/&quot;&gt;system&lt;/a&gt; is implicit in practically
everything that goes on in a home. It’s always there, and almost
everything you do in your home has an effect on it. By putting a
finger on this pulse, we’re able to provide a lot of value to
homeowners and our partner organizations that they wouldn’t otherwise
have access to.&lt;/p&gt;

&lt;p&gt;The technology involved has two parts. We make a hardware product
which monitors the home’s electrical network. And we run a SaaS
platform which ingests, processes, and delivers insights from the
data.&lt;/p&gt;

&lt;h2 id=&quot;lesson-1-mind-your-protocols-and-queues&quot;&gt;Lesson 1: Mind your protocols and queues&lt;/h2&gt;

&lt;p&gt;Software bridges the gap between these two parts of our business. This
software spans multiple computational footprints, from embedded
devices up to the machines in our cloud.&lt;/p&gt;

&lt;p&gt;A good way to contextualize these tiers of software is to consider the
&lt;em&gt;time scales&lt;/em&gt; at which they operate.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/thing-lessons/time-scales.png&quot; alt=&quot;&quot; /&gt;&lt;span class=&quot;figure_caption&quot;&gt;Fig. 2. Breakdown of the time scales at
 eachstage of the data ingestion pipeline.&lt;/span&gt;&lt;/p&gt;

&lt;h3 id=&quot;time-scales&quot;&gt;Time scales&lt;/h3&gt;

&lt;p&gt;Closest to the metal (literally), we have our sensors. These are
custom PCBs that run interrupt-driven tasks on a low-power MCU. The
sole purpose of the code running on these devices is to pull data out
of magnetic field sensing elements at a rate of about 2,000 Hz, which
translates to about 500 microseconds per polling operation.&lt;/p&gt;

&lt;p&gt;These raw sensor data are put into a ring buffer with capacity
equivalent to ⅒ of a second’s worth of data. Ten times per second,
the sensors populate their output buffers with new data. It is then
necessary for the sensors to be polled at a rate of at least 10 Hz, or
else data will be lost.&lt;/p&gt;

&lt;p&gt;In order to avoid hammering our backend, the agent which polls the
sensors buffers data in order to space out transmissions to our
API. By default, the transmission rate is 1 Hz, but can be modulated
either to decrease end-to-end latency for important data or to
implement exponential backoff in response to a backpressure signal
from the API.&lt;/p&gt;

&lt;p&gt;At this point, data has made its way into our backend. But the data
itself consists of unitless signal measurements. Turning these raw
data into meaningful measurements of current, voltage, and power
requires a bunch of math and a learning process which, over time,
calibrates its output according to characteristics of the magnetic
field environment of the customer’s circuit breaker panel.&lt;/p&gt;

&lt;p&gt;At the end of all this, we have output values in terms of scientific
units that can be either displayed to customers or fed into further
analysis workloads. The time scale at this “application layer” for our
data tends to be on the order of seconds, or in the case of historical
analyses, days, months, or years.&lt;/p&gt;

&lt;p&gt;One consequence of this gradation of time scales is our reliance on
queues, or more specifically, ring buffers. I often joke that our
system is ring buffers all the way down, because it basically is when
you think about it. The way each stage makes the jump to a higher time
scale is to queue data until a threshold duration’s worth has been
buffered, and then flush the buffered data to the next
stage. Unbounded queueing being a recipe for memory leaks, we use ring
buffers to fix our buffering capacity at each stage.&lt;/p&gt;

&lt;p&gt;What I’m describing isn’t novel; It’s basically network
programming 101. I’ll refer back to this in a later section.&lt;/p&gt;

&lt;h3 id=&quot;protocols&quot;&gt;Protocols&lt;/h3&gt;

&lt;p&gt;Another consequence that we’ve taken to heart is the fundamental
importance of &lt;em&gt;protocols&lt;/em&gt;, or the formats in which data are encoded
and the policies enforced around interacting with it.&lt;/p&gt;

&lt;p&gt;In the web universe, JSON is still the linga franca. Within
datacenters, it’s increasingly common to pass data between services in
more efficient formats, like Protocol Buffers or Thrift. In the
scientific community, HDF is the standard, being better suited for
numerical and tabular datasets.&lt;/p&gt;

&lt;p&gt;One thing that I’m glad we did up front was to put thought into what
data formats we want to support for exchanging data between the
components outlined above. Each transition represents a different set
of constraints in terms of memory, computation, and
time. Additionally, we foresaw the need for our stream-processing
pipeline to support types of data other than those produced by our
sensors. For instance, we feed system metrics from our sensors and hub
through the same APIs as energy data, letting the backend multiplex
different data streams to the appropriate downstream services.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/thing-lessons/em-matrix.png&quot; alt=&quot;&quot; /&gt;&lt;span class=&quot;figure_caption&quot;&gt;Fig. 3. Example of energy time series data at
 a ~1-second interval.&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;What we came up with is an extensible data model based on &lt;em&gt;typed
matrices&lt;/em&gt;. For any given type of data stream (“energy data”, “system
metrics”, “thermostat data”), we can define a series of channels which
each have a datatype and a unit. For example, we represent “energy
data” as a matrix whose columns convey values like voltage in volts,
current in amperes, and power in watts. “System metrics” streams
convey the usual suspects (CPU/memory/network utilization) with added
emphasis on measurements relevant to embedded systems, like
temperature and line frequency.&lt;/p&gt;

&lt;p&gt;In the memory and bandwidth-constrained environments of our devices,
we use a custom binary protocol which enacts the matrix representation
of our data model. This protocol is itself extensible too, allowing us
to annotate payloads with metadata or implement new compression
schemes in a backwards compatible way.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;As an aside, this is the context in which we developed the adaptive
averaging compression algorithm which
&lt;a href=&quot;/2016/03/pseudo-periodic-time-series-and-how-to-encode-them/&quot;&gt;I wrote about last year&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Being mindful of the protocols we use continues to pay dividends. By
tailoring our data formats towards extensibility and our specific
constraints, we’ve been able to drastically reduce data sizes, reduce
the rate at which we produce
&lt;a href=&quot;/2013/06/survey-on-technical-debt-management/&quot;&gt;technical debt&lt;/a&gt;, and
streamline the process of integrating with external data providers.&lt;/p&gt;

&lt;h2 id=&quot;lesson-2-err-on-the-side-of-conservatism&quot;&gt;Lesson 2: Err on the side of conservatism&lt;/h2&gt;

&lt;p&gt;A second lesson that we’ve learned is that production-grade embedded
development requires a level of conservatism not fashionable in
popular software culture.&lt;/p&gt;

&lt;p&gt;This lesson is derived from the basic premise that we have no control
over devices once they leave the factory. If the device installation
process fails, there’s no crash-reporting system you can rely on for
debugging. Once online, a device can disappear at any time should the
homeowner’s power go out or they change their wifi password. Or the
device’s network connection may slow to a trickle a few times per day
because their breaker panel is on the opposite side of a wall as a
microwave.&lt;/p&gt;

&lt;p&gt;This throws a wrench in our ability as fleet operators to ensure
timely data collection
or &lt;a href=&quot;/2017/10/resiliency-in-energy-and-software&quot;&gt;reliable&lt;/a&gt; upgrades to
the devices’ software. When you put a thing in someone’s home, you
lose the ability to make any assumptions about its availability and
serviceability.&lt;/p&gt;

&lt;p&gt;The low-hanging fruit mitigation strategy is to enforce rigorous
testing throughout the development process and thorough QA before
devices leave the factory. This decreases the likelihood of
self-inflicted wounds from bugs into our own software. But many risk
factors are outside of our control. What if a critical open source
library stops being maintained? What if a vendor on which you rely
goes out of business?&lt;/p&gt;

&lt;p&gt;Being a small team with tight shipping schedules, we may not be able
to afford the sudden disappearance of a giant on whose shoulders we’ve
stood. In contrast to a similar situation in the web development
sphere, like migrating a user auth flow from Parse to Amazon Cognito,
you can’t exactly swap out your device’s runtime with 100% confidence.&lt;/p&gt;

&lt;p&gt;To de-risk our embedded software, we’ve erred on the side of
conservatism when choosing to tie our ship to any outside entity. For
instance, we’ve resisted the nascent trend towards running
bleeding-edge containerization tools on our devices. On the one hand,
being able to hermetically isolate processes would be a boon for
security. But we’re not comfortable betting our devices’ decade-long
operating requirements on open source projects that garner 100 commits
per week.&lt;/p&gt;

&lt;h2 id=&quot;lesson-3-everything-old-is-new-again&quot;&gt;Lesson 3: Everything old is new again&lt;/h2&gt;

&lt;p&gt;I am of the opinion that “IoT” is more marketing term than an
indication of a fundamental shift in technology.&lt;/p&gt;

&lt;p&gt;Looking out on the consumer landscape, we’re inundated in a sea of
smart devices. Every appliance manufacturer under the sun is trying to
sell us more expensive versions of their products that have screens or
can send us text messages.&lt;/p&gt;

&lt;p&gt;On the research end, if you read the literature on the Internet of
Things, you’re vaulted into a near future in which our world is
transformed by ubiquitous, networked sensors. No human desire or
action is left unchanged. We are about to live in a Charles Stross
novel.&lt;/p&gt;

&lt;p&gt;After working with this stuff for a few years, I’ve started to wonder
how the IoT trend will leave its mark on the software industry
itself. I’m hopeful that as more developers work on or around
connected devices, we’re collectively getting a chance to relearn how
computers actually work.&lt;/p&gt;

&lt;p&gt;In years past, the advance of Moore’s Law led to incrementally
higher-level innovation in how software was developed and run. First
we got structured programming and higher-level languages. Then
operating systems and virtual memory. Then virtual &lt;em&gt;machines&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;As the Internet grew in the 90s we saw the rise of Java as a
client-side platform. And then when that didn’t work out, JavaScript
ascended. Now the browser is the lowest-level abstraction that many
developers have to think about.&lt;/p&gt;

&lt;p&gt;Provided the IoT sector finds its footing, this ever-present march
towards higher-level abstractions will inevitably paper over many of
the concerns of the underlying hardware and network topology. But I
think we’re safe in assuming that for the next handful of years, the
trend towards ubiquitous computing will rely on low-power hardware
platforms that communicate under variable networking conditions.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/thing-lessons/hamilton.jpg&quot; alt=&quot;&quot; /&gt;&lt;span class=&quot;figure_caption&quot;&gt;Fig. 4. Photo of Margaret Hamilton working on
 an IoT product.&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;In a small way, these adverse characteristics harken back to the good
ol’ days of programming at places like MIT’s AI Lab in the 60s or Bell
Labs in the 70s. Working with resource-limited environments requires a
fundamental understanding of how computers work. In all, this makes
the space an enriching one to work in.&lt;/p&gt;

&lt;p&gt;Vinyl records are resurgent and more people are having to care how
many bytes their programs occupy in memory. Everything old is new
again.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Throughout the lessons discussed above (the importance of protocols
and buffering strategies, conservatism with respect to dependencies,
and the value of the tried and true ways of doing things), an
overarching theme emerges—there isn’t a “default path” one can take
when building software for a connected device.&lt;/p&gt;

&lt;p&gt;For many companies, there’s a well-trod path of battle-tested
solutions to most problems that arise. Need a webapp? Use Rails or
React. Website slow? Use Memcached or Redis. Deploys slow? Use Docker,
I guess.&lt;/p&gt;

&lt;p&gt;In the IoT world, you’re in less-charted territory. Your problems are
more apt to be something fundamental, like how your device is using
the network or how the time scales of operation align between devices
or how your device is translating physical stimuli into a stream of
numbers.&lt;/p&gt;

&lt;p&gt;I, for one, relish these kinds of problems that require you to sink
your teeth in. And I hope we as an industry use them as an opportunity
to grow.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;em&gt;Thanks to &lt;a href=&quot;https://www.instagram.com/baerkif/&quot;&gt;Fikreab Mulugeta&lt;/a&gt; for
reading and providing feedback on drafts of this essay.&lt;/em&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Aiming for sustainability</title>
   <link href="https://evanm.website/2017/03/aiming-for-sustainability/"/>
   <updated>2017-03-21T00:00:00+00:00</updated>
   <id>https://evanm.website/2017/03/aiming-for-sustainability</id>
   <content type="html">&lt;p&gt;&lt;a href=&quot;/2017/02/systems-thinkpiece/&quot;&gt;My last post&lt;/a&gt; dealt with the subject of
“systems thinking”, claiming that its fashionableness in the tech
industry doesn’t jive with the amount of collateral damage being
racked up by prominent companies.&lt;/p&gt;

&lt;p&gt;I wanted to follow up with a post that doesn’t spend 600 words tearing
down other people’s work. To that end, I’d like to pose the question
of what a company would look like if it were to truly espouse systems
thinking.&lt;/p&gt;

&lt;p&gt;To characterize a possible outline of such a company, I think that it
comes down to developing a sustainable business model before being
coerced by market forces to make the business work by any means
necessary.&lt;/p&gt;

&lt;h2 id=&quot;sustainability&quot;&gt;Sustainability&lt;/h2&gt;

&lt;p&gt;The word “sustainability” ceased to convey meaning years ago. It’s
become more of a Boy Scout merit badge than an objective against which
key results can be measured.&lt;/p&gt;

&lt;p&gt;But to take a step back and define our terms, for a process to be
sustainable, it must be capable of continuous operation without the
aid of external forces. In the realm of business, the process to be
sustained is &lt;em&gt;growth&lt;/em&gt;, presumably of revenue. A firm can’t simply
remain in operation to be considered successful—it must keep pace with
(or beat) the greater economy.&lt;/p&gt;

&lt;p&gt;This fact of business life provides the primary point of pressure on
management—growth must be sustained, if not accelerated, or else it’s
your head.&lt;/p&gt;

&lt;p&gt;A company must overcome this pressure in order to have the luxury of
even &lt;em&gt;considering&lt;/em&gt; its adverse impacts on society. A management team
kept up at night by fear of investor insurrection is not one that’s
apt to fret about automation’s impact on the working class.&lt;/p&gt;

&lt;p&gt;A company that fails to overcome this pressure is akin to a truck
rolling downhill with its brakes cut. As more people pin their hopes
and dreams to the company, management starts to lose political capital
and control of their own destiny. As things get dicier, it starts
looking preferable to steer the truck towards the crowded intersection
in order to stay on the road instead of maintaining course at the
brick wall ahead of you.&lt;/p&gt;

&lt;p&gt;A business earns the luxury of considering social impact by enacting a
successful business model. A sustainable bottom line is the price of
entry.&lt;/p&gt;

&lt;h2 id=&quot;luck&quot;&gt;Luck&lt;/h2&gt;

&lt;p&gt;That sounds all well and great, but one does not simply “enact a
successful business model”. This is a very difficult thing that most
management teams fail to do.&lt;/p&gt;

&lt;p&gt;Two contrived examples of how this may occur:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;As a consequence of identifying a problem that your team is
uniquely capable of solving, you achieve bottom line growth before
investors lose patience.&lt;/li&gt;
  &lt;li&gt;You raise money from folks that trust you deeply, and this trust
allows you to invest early capital in experimentation in pursuit of
a sustainable business model.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Both of these scenarios involve quite a bit of luck. But this luck is
&lt;em&gt;earned&lt;/em&gt;, either by the team’s execution on a suitable problem or by
building and leveraging trusted relationships.&lt;/p&gt;

&lt;h2 id=&quot;alignment&quot;&gt;Alignment&lt;/h2&gt;

&lt;p&gt;To me, the crux of this process is wrapped up in the motivations of a
founding team. A team motivated by the fashionableness of starting a
company as a get-rich-quick scheme is not one that’s likely to be
mindful of negative externalities.&lt;/p&gt;

&lt;p&gt;I contend that you’re better off executing on a problem that you find
truly meaningful and likely to have a positive impact on
society. These characteristics do not supersede the requirement of
making money, but can be thought of as filters on the paths down which
a company may traverse.&lt;/p&gt;

&lt;p&gt;Starting a company is hard work. Minimizing a company’s exploitative
fallout on society requires patience, some amount of privilege, and
fundamental alignment among the founding team.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;em&gt;Thanks to &lt;a href=&quot;https://www.linkedin.com/in/oschetrit&quot;&gt;Oren Schetrit&lt;/a&gt; for
reading and providing feedback on drafts of this essay.&lt;/em&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Systems Thinkpiece</title>
   <link href="https://evanm.website/2017/02/systems-thinkpiece/"/>
   <updated>2017-02-13T00:00:00+00:00</updated>
   <id>https://evanm.website/2017/02/systems-thinkpiece</id>
   <content type="html">&lt;p&gt;&lt;img src=&quot;/images/systems-thinkpiece/strangelove-war-room.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Luminaries in the technology industry love to trumpet
&lt;a href=&quot;https://en.wikipedia.org/wiki/Systems_thinking&quot;&gt;systems thinking&lt;/a&gt;. A
“systems thinker” is one who possesses the ability to reason
holistically about the relationships between independent components of
a system. This notion is recursive in the sense that each component
may itself be a system composed of interconnected parts.&lt;/p&gt;

&lt;p&gt;In practice, companies tout systems thinking as a means towards the
nebulous ideal of “innovation”. We like to hire “systems thinkers”
because our companies are complex, special organizations that need to
be properly cared for and fed by smart people. But really, I think
that &lt;em&gt;true&lt;/em&gt; systems thinking manifests elsewhere in a corporate
setting. An enlightened company thinks of ways to minimize their
adverse impact on customers’ lives and society as a whole. Such a
company may disrupt their &lt;em&gt;competition&lt;/em&gt;, but leave society intact, if
not improved.&lt;/p&gt;

&lt;p&gt;Two examples, admittedly focusing on the negative because it’s easier
to call attention to:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The fast food industry is bad at systems thinking. Their success is
inversely correlated with the physical health of their customers.&lt;/li&gt;
  &lt;li&gt;The financial industry has a centuries-long track record of being
bad at systems thinking. Time and time again, recessions are caused
by the over-exploitation of markets and people. In terms of systems,
expressions of laissez faire capitalism show a contemptible
disregard for the consequences of exploitative actions on powerless
people.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;tech&quot;&gt;Tech&lt;/h2&gt;

&lt;p&gt;How does the technology industry fair when viewed through this lens?
To frame the current moment in history, I think technologists’
collective vision of the future has come into stark contrast with
reality. Look at basically any peppy video advertisement from a
startup and you’ll see a world inhabited solely by affluent,
tech-savvy people. The primary motivators when these people make
purchasing decisions are the degree to which a product or service can
make them feel “connected” and maximally productive.&lt;/p&gt;

&lt;p&gt;This vision, one in which Maslow’s hierarchy itself has been
disrupted, isn’t a vision that represents the bulk of humanity. In its
dominant guise driven by venture capitalists, I don’t think Silicon
Valley is as good at thinking about systems as it thinks it is.&lt;/p&gt;

&lt;p&gt;Specifically, the current iteration of the tech industry fails to take
into account and plan for the societal impact of its offerings. We
want a driverless future, but it’s not our job to think about how
we’ll maintain the livelihood and dignity of taxi-, truck-, and
bus-drivers. We want an open and universal communications network, but
refuse to acknowledge our consequent role in defending the truth and
policing hate speech. We want to institute a sharing/gig economy, but
give zero thought into how this would impact the health care system or
how people find time to raise children amid a workweek full of
discontinuous tasks carried out for rich people.&lt;/p&gt;

&lt;h2 id=&quot;closing&quot;&gt;Closing&lt;/h2&gt;

&lt;p&gt;When the financial industry’s unchecked expansion into predatory
lending cratered the global economy, we were up in arms, calling for
heads to roll. Now, by giving a megaphone populists, social media has
helped put an authoritarian administration in the White House and the
specter of white supremacy back into the mainstream. What is to be
done when the leadership at Facebook and Twitter fail to even
acknowledge their platforms’ inadvertent role in these developments?*&lt;/p&gt;

&lt;p&gt;We can’t build an equitable future when the powers that drive the
narrative (namely, prominent executives and VCs) fail to recognize
technology’s adverse effects. When will Silicon Valley have its
Oppenheimer moment?&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;em&gt;Thanks to &lt;a href=&quot;https://twitter.com/marcprecipice&quot;&gt;Marc Hedlund&lt;/a&gt; for
reading and providing feedback on drafts of this essay.&lt;/em&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;* I realize that this is reductive. Also, the massive outpouring of
activism since the election would be impossible without social media,
so the megaphone goes both ways.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Introducing JSON Toggle</title>
   <link href="https://evanm.website/2017/02/introducing-json-toggle/"/>
   <updated>2017-02-07T00:00:00+00:00</updated>
   <id>https://evanm.website/2017/02/introducing-json-toggle</id>
   <content type="html">&lt;p&gt;&lt;img src=&quot;/images/json-toggle/rail-bw.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;This post proposes &lt;em&gt;JSON Toggle&lt;/em&gt;, a JSON document structure for
specifying feature toggles. This format is being used at
&lt;a href=&quot;https://www.whiskerlabs.com&quot;&gt;Whisker Labs&lt;/a&gt; with
&lt;a href=&quot;https://github.com/whiskerlabs/toggle&quot;&gt;a Java 8 library&lt;/a&gt; which we’re
open-sourcing as a proof-of-concept for JSON Toggle.&lt;/p&gt;

&lt;h2 id=&quot;background&quot;&gt;Background&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;http://martinfowler.com/articles/feature-toggles.html&quot;&gt;Feature Toggles&lt;/a&gt;
(or feature flags) are a programming mechanism used to dynamically
configure running programs. A team utilizing feature toggles can
modify a software system’s behavior without having to redeploy code or
restart processes with new configuration. When used judiciously,
feature toggles can dramatically increase a team’s rate of
experimentation and delivery.&lt;/p&gt;

&lt;p&gt;The state of a collection of feature toggles is typically read at
runtime from some side channel such as a database or a config
file. This state can be updated out-of-band with tooling (e.g. a
dashboard) and automatically distributed to running applications. At
Twitter (where I used to work), the company-wide feature flag system
provides the software equivalent of a railroad switching station,
giving teams dynamic control over which codepaths were enabled for
which users. This level of flexibility unlocks the ability to roll out
new features and perform
&lt;a href=&quot;https://medium.com/turbine-labs/every-release-is-a-production-test-b31d80f2bc74#.gp6im5ad7&quot;&gt;large refactors&lt;/a&gt;
with a minimum of pulled-out hair.&lt;/p&gt;

&lt;h2 id=&quot;a-protocol-for-defining-feature-toggles&quot;&gt;A protocol for defining feature toggles&lt;/h2&gt;

&lt;p&gt;Since
&lt;a href=&quot;https://code.flickr.net/2009/12/02/flipping-out/&quot;&gt;their emergence in the late aughts&lt;/a&gt;,
feature toggles have become a common pattern
&lt;a href=&quot;https://blog.travis-ci.com/2014-03-04-use-feature-flags-to-ship-changes-with-confidence/&quot;&gt;at&lt;/a&gt;
&lt;a href=&quot;https://gmail.googleblog.com/2011/12/developing-gmails-new-look.html&quot;&gt;internet&lt;/a&gt;
&lt;a href=&quot;http://techblog.netflix.com/2013/11/preparing-netflix-api-for-deployment.html&quot;&gt;companies&lt;/a&gt;
and have made their way into the
&lt;a href=&quot;https://msdn.microsoft.com/en-us/magazine/dn683796&quot;&gt;enterprise&lt;/a&gt;. Despite
this, there has never been a successful effort to standardize the
means by which toggles are configured. By and large, the state of the
art has each organization building an implementation from scratch and
maintaining a bespoke distributed CRUD app to manage them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It’s shocking to me that there isn’t an equivalent of
&lt;a href=&quot;https://github.com/b/statsd_spec&quot;&gt;the statsd protocol&lt;/a&gt; for feature
toggles.&lt;/strong&gt; Regardless of the storage and distribution mechanism used,
a protocol would at least allow us to converge on a standard for
specifying toggle configuration.&lt;/p&gt;

&lt;p&gt;With this in mind, I’d like to propose &lt;strong&gt;JSON Toggle&lt;/strong&gt;, a feature
toggle specification format that we’re starting to use at Whisker
Labs.&lt;/p&gt;

&lt;p&gt;JSON Toggle defines a JSON document structure for parameterizing a set
of feature toggles. Such documents, called “toggle specifications”,
may be used to enact weighted probabilities that determine whether or
not a feature is enabled for a given request.&lt;/p&gt;

&lt;p&gt;JSON Toggle is language-agnostic in the sense that ingestion libraries
may be implemented in any programming language.&lt;/p&gt;

&lt;h2 id=&quot;an-example-toggle-spec&quot;&gt;An example toggle spec&lt;/h2&gt;

&lt;p&gt;In the following example toggle specification, three toggles are
defined:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;/feature/ab_test&quot;&lt;/code&gt; which acts as a simple coin-flip with 50%
probability.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;/feature/dogfood_widget&quot;&lt;/code&gt; which can be used to guard a feature
that is 100% accessible to employees but inaccessible to all other
users.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;/feature/incremental_rollout&quot;&lt;/code&gt; which grants access to all
employees, but only 1% of non-employee users.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The spec looks like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-json&quot; data-lang=&quot;json&quot;&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;key&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;/feature/ab_test&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;value&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5000&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;key&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;/feature/dogfood_widget&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;filter&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;cohort&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;target&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;employee&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;value&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10000&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;value&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;key&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;/feature/incremental_rollout&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;filter&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;cohort&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;target&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;employee&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;value&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10000&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;value&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Or equivalently in YAML:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-yaml&quot; data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;nn&quot;&gt;---&lt;/span&gt;
&lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;/feature/ab_test&quot;&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;5000&lt;/span&gt;
&lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;/feature/dogfood_widget&quot;&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;cohort&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;employee&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;10000&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;/feature/incremental_rollout&quot;&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;cohort&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;employee&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;10000&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;100&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;For each specified toggle, an integer value from zero to 10,000
represents a probability (out of 10,000). These values can be thought
of as weights for predicates (boolean-valued functions) that are used
in application code to guard whether or not a feature is enabled for a
given request.&lt;/p&gt;

&lt;p&gt;Toggles can additionally specify &lt;em&gt;filters&lt;/em&gt; which apply different
probability values to certain types of requests. For example, a filter
could be used to target a cohort of users, such as “employees” or
“beta testers”.&lt;/p&gt;

&lt;h3 id=&quot;toggle-specification-specification&quot;&gt;Toggle Specification specification&lt;/h3&gt;

&lt;p&gt;An individual toggle definition is broken into three components:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;A required &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;key&lt;/code&gt; string which uniquely identifies the toggle within
the toggle spec.&lt;/li&gt;
  &lt;li&gt;An optional &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;filter&lt;/code&gt; property, defining a list of &lt;em&gt;filters&lt;/em&gt; which
define “special case” branches of the toggle.
    &lt;ul&gt;
      &lt;li&gt;For instance, a &lt;em&gt;cohort filter&lt;/em&gt; is used to match a toggle
  invocation with a cohort. A cohort target could identify a subset
  of a userbase (e.g “employees”), an IP range of incoming requests
  (e.g. 67.174.128.0/24), or any other subdivision relevant to an
  application.&lt;/li&gt;
      &lt;li&gt;Filters should be evaluated in the order that they appear in the
  toggle specification.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;A &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;value&lt;/code&gt; property, which sets the “base” value for cases when no
filter applies to a request. Values are specified in
&lt;a href=&quot;https://en.wikipedia.org/wiki/Basis_point&quot;&gt;basis points&lt;/a&gt; and define
toggle probabilities out of 10,000. Thus a toggle value of 5,000
will result in a toggle probability of 50%.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;a-java-8-library-for-working-with-json-toggle&quot;&gt;A Java 8 library for working with JSON Toggle&lt;/h2&gt;

&lt;p&gt;In addition to this protocol, I’d like to share an early version of a
JSON Toggle ingestion library that we’re using at Whisker Labs for our
Java services. &lt;a href=&quot;https://github.com/whiskerlabs/toggle&quot;&gt;toggle&lt;/a&gt; is a
Java 8 library which implements the functionality described above
using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;java.util.function&lt;/code&gt; primitives.  It supports toggle
specifications stored in Amazon DynamoDB tables or JSON/YAML files,
and offers a caching decorator powered by
&lt;a href=&quot;https://github.com/ben-manes/caffeine&quot;&gt;Caffeine&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;With this library, we can do things like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;c1&quot;&gt;// Construct a caching `ToggleMap` backed by a DynamoDB table.&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;Table&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dynamoDbTable&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dynamoDbClient&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getTable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;production-toggles&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;nc&quot;&gt;ToggleMap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Integer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;toggleMap&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CachingToggleMap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;gt;(&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;DynamoDbToggleMap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Integer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dynamoDbTable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt;
  &lt;span class=&quot;s&quot;&gt;&quot;maximumSize=1000,expireAfterWrite=1m&quot;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Create a toggle backed by the &quot;/feature/new_hotness&quot; definition.&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;Toggle&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Integer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fancyNewFeature&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;toggleMap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;/feature/new_hotness&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Use the toggle to guard some new functionality, based on a user ID.&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fancyNewFeature&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;userId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// New hotness.&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// Old and busted.&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;em&gt;Nomenclature unabashedly cribbed from
&lt;a href=&quot;https://twitter.github.io/finagle/guide/Configuration.html#feature-toggles&quot;&gt;Finagle&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h2 id=&quot;now-what&quot;&gt;Now what?&lt;/h2&gt;

&lt;p&gt;If JSON Toggle is to become a thing, we’ll need to write ingestion
libraries in other programming languages and various tools to make it
easy to manage with toggle specifications.&lt;/p&gt;

&lt;p&gt;If you think this approach could be useful or that it’s a stupid idea,
I’d love to hear from you. In lieu of an official channel like a
mailing list, for the time being, please reach out
&lt;a href=&quot;mailto:evan.meagher@gmail.com&quot;&gt;via email&lt;/a&gt; or by filing an issue on
the &lt;a href=&quot;https://github.com/whiskerlabs/toggle&quot;&gt;toggle project on GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;em&gt;Thanks to &lt;a href=&quot;https://twitter.com/rishair&quot;&gt;Rishi Ishairzay&lt;/a&gt; for reading
and providing feedback on drafts of this essay.&lt;/em&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Synthesis over invention</title>
   <link href="https://evanm.website/2016/03/synthesis-over-invention/"/>
   <updated>2016-03-31T00:00:00+00:00</updated>
   <id>https://evanm.website/2016/03/synthesis-over-invention</id>
   <content type="html">&lt;p&gt;&lt;img src=&quot;/images/synthesis/gottingen_library.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I recently finished a great book called
&lt;a href=&quot;https://www.goodreads.com/book/show/1217018.Hilbert&quot;&gt;&lt;em&gt;Hilbert&lt;/em&gt;&lt;/a&gt; [1],
an eponymous biography of the mathematician David Hilbert. It’s a fun
read and conveys an important message for anyone who strives to be
creative in a technical field. In contrast to the stereotype of the
inventive genius who advances a field by creating fundamentally new
concepts, many of
&lt;a href=&quot;https://en.wikipedia.org/wiki/List_of_things_named_after_David_Hilbert&quot;&gt;the innovations to which Hilbert’s name is attributed&lt;/a&gt;
are instead examples of &lt;em&gt;synthesis&lt;/em&gt;, or the process of combining
different existing theories into a single system.&lt;/p&gt;

&lt;p&gt;This is a critical distinction which I don’t feel is emphasized enough
in the contemporary software development and computer science
community.&lt;/p&gt;

&lt;h2 id=&quot;nerd-nostalgia&quot;&gt;Nerd nostalgia&lt;/h2&gt;

&lt;p&gt;Beyond capturing the life of an intellectually preeminent man, author
Constance Reid does a fabulous job of snapshotting the energy and
unprecedented output of the mathematical society centered around
&lt;a href=&quot;https://en.wikipedia.org/wiki/University_of_G%C3%B6ttingen&quot;&gt;Göttingen&lt;/a&gt;,
Germany at the turn of the twentieth century.&lt;/p&gt;

&lt;p&gt;If you were to trace the lineage of virtually any subfield of modern
mathemathics or physics, Göttingen would stand out as an inexorable
nexus of theory and innovation. Any subset of
&lt;a href=&quot;https://en.wikipedia.org/wiki/List_of_Georg-August_University_of_G%C3%B6ttingen_people&quot;&gt;the list&lt;/a&gt;
of folks who passed through would be an intellectual hall of fame:
Gauss, Riemann, Dirichlet, Born, Oppenheimer, Teller, Dirac, Planck,
Einstein, Noether, Klein, Schopenhauer, Fermi, von Neumann,
Heisenberg.&lt;/p&gt;

&lt;p&gt;Up there with the Manhattan Project and
&lt;a href=&quot;http://www.sexmagazine.us/articles/laurie-spiegel/1&quot;&gt;Bell Labs in the 70s&lt;/a&gt;,
Göttingen is one of the storied valhallas of nerd nostalgia. Every few
decades since the industrial revolution (and before, but with far
lesser frequency), some cloistered organization attracts a critical
mass of productive brain power and is canonized in history books as a
hotbed of R&amp;amp;D. The Georg August University of Göttingen was one such
place from its heyday in the mid-19th century up until the German
braindrain of the 1930s. Add to this the era of geopolitical
turbulence overlapping Hilbert’s lifetime, and you’re left with a
fascinating slice of history.&lt;/p&gt;

&lt;h2 id=&quot;a-synthetic-character&quot;&gt;A synthetic character&lt;/h2&gt;

&lt;p&gt;In the wake of this book, I’m left ruminating over certain
characterizations of Hilbert’s work and the historical setting in
which he lived. One particularly compelling specialty that Hilbert
possessed was an ability to synthesize disparate concepts into
cohesive theories that at once fundamentally broke ground and unified
different fields.&lt;/p&gt;

&lt;p&gt;Hilbert’s student and fellow mathematician, Otto Blumenthal:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&amp;#8220;For the analysis of a great mathematical
talent, one has to differentiate between the ability to create new
concepts and the gift of sensing the depth of connections and
simplifying fundamentals. Hilbert&apos;s greatness consists of his
overpowering, deep-penetrating insight. All of his works contain
examples from far-flung fields, the inner relatedness of which and the
connection with the problem at hand only he had been able to discern;
from all these the synthesis &amp;mdash; and his work of art &amp;mdash; was
ultimately created.&amp;#8221;&lt;/p&gt;
&lt;cite&gt;C. Reid, &lt;em&gt;Hilbert&lt;/em&gt;, 1st ed. New York: Copernicus, 1996,
ch. 24, pp. 208.&lt;/cite&gt;
&lt;/blockquote&gt;

&lt;p&gt;To paraphrase, Hilbert is best known not for inventing lots of
fundamentally new science, but for finding and leveraging
commonalities between the many good things that his contemporaries
came up with. Rather than endlessly adding to an intractable pile of
mathematical novelty, Hilbert excelled at &lt;em&gt;synthesis&lt;/em&gt;, or the process
of combining different theories into a single cohesive system.&lt;/p&gt;

&lt;p&gt;In an ambitious age of unbounded possibility and imagination, what
better strategy than to seek &lt;em&gt;depth of connections and simplifying
fundamentals&lt;/em&gt;.&lt;/p&gt;

&lt;h2 id=&quot;wherein-software-eats-my-book-report&quot;&gt;Wherein software eats my book report&lt;/h2&gt;

&lt;p&gt;This notion has important and obvious lessons for software
developers. The existential balance between novelty and synthesis in
theoretical mathematics is equivalent to maintaining a balanced diet
of abstraction in a computational system.&lt;/p&gt;

&lt;p&gt;For example, I would go so far as to say that there is a trend in
certain niche programming language communities to culturally
appropriate as much from the fields of modern mathematics as
possible. This has several adverse consequences, most immediate of
which is the imposition of an immense educational burden on
newcomers. Longer term, when projects are built around arcane
abstractions that few people truly understand, they are inevitably
used “improperly” because consumers don’t know any better.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://twitter.com/evanm/status/714521881387204608&quot;&gt;I think&lt;/a&gt; that
the degree to which a project exposes overly-conceptual abstraction is
directly related to the rate at which technical debt accumulates in
consuming code. Such cases do all of us a disservice and lead to the
eventual marginalization of the abstraction-laden technology.&lt;/p&gt;

&lt;p&gt;To me, it’s interesting to think about where the pendulum of creation
vs synthesis currently lies in the world of software development. We
are awash in heady topics that we collectively feel remiss for not
understanding well enough. From elliptic curve cryptography to block
chains to consensus protocols to region-based memory management to
whatever the hell a monad actually is, there are an increasing number
of gaps in our domain expertise and few unifying systems through which
to understand them.&lt;/p&gt;

&lt;p&gt;I get the feeling that lately we as an industry put too much emphasis
on novelty and not enough on unification. We are easily titilated by
the newest programming language or the latest gizmo that can fork a
process on a far away computer and less interested in ideas that
fundamentally simplify how we reason about and work with computers.&lt;/p&gt;

&lt;h2 id=&quot;towards-synthesis&quot;&gt;Towards synthesis&lt;/h2&gt;

&lt;p&gt;I’m humbled by Hilbert’s definitive ability to consolidate and
simplify. Read by a software developer, the book is a call to action
pitting the goal of synthesis against our tendency to run as fast as
we can in a million directions at once.&lt;/p&gt;

&lt;p&gt;By emulating David Hilbert and studying disparate fields with an eye
towards unification, we can produce powerful tools without requiring
that our users read 40 whitepapers before understanding anything.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;em&gt;Thanks to &lt;a href=&quot;https://twitter.com/rishair&quot;&gt;Rishi Ishairzay&lt;/a&gt;,
&lt;a href=&quot;https://twitter.com/noradio&quot;&gt;Marcel Molina&lt;/a&gt;, and
&lt;a href=&quot;https://twitter.com/a_a&quot;&gt;Arya Asemanfar&lt;/a&gt; for reading and providing
feedback on drafts of this essay.&lt;/em&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;section class=&quot;footnotes&quot;&gt;
  &lt;h2&gt;References&lt;/h2&gt;
  &lt;ol&gt;
    &lt;li&gt;C. Reid, &lt;em&gt;Hilbert&lt;/em&gt;, 1st ed. New York: Copernicus, 1996.&lt;/li&gt;
  &lt;/ol&gt;
&lt;/section&gt;
</content>
 </entry>
 
 <entry>
   <title>Adaptive compression of periodic signals</title>
   <link href="https://evanm.website/2016/03/pseudo-periodic-time-series-and-how-to-encode-them/"/>
   <updated>2016-03-02T00:00:00+00:00</updated>
   <id>https://evanm.website/2016/03/pseudo-periodic-time-series-and-how-to-encode-them</id>
   <content type="html">&lt;p&gt;&lt;img src=&quot;/images/pseudo-periodicity/hokusai.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;What do all compression algorithms have in common?&lt;/p&gt;

&lt;p&gt;They usually involve some fancy math, but when it comes down to it,
their defining tactic is to exploit properties of their input in order
to encode the data in fewer bits. Thus a given compression algorithm
is typically best applied to a specific type of data. Inversely, given
a type of data, the process of selecting an appropriate compression
algorithm requires one to precisely identify an exploitable
characteristic of the data.&lt;/p&gt;

&lt;p&gt;In this article, I’ll introduce a data-compression problem that we
faced at &lt;a href=&quot;https://www.whiskerlabs.com&quot;&gt;Whisker Labs&lt;/a&gt;, chart a course
through several fields of research, and describe a technique that my
colleagues and I developed to address the problem.&lt;/p&gt;

&lt;h2 id=&quot;an-introductory-example&quot;&gt;An introductory example&lt;/h2&gt;

&lt;p&gt;Let’s start with a example. Imagine that you’re tasked with building a
device which must measure the electrical current going through a 60 Hz
&lt;a href=&quot;https://learn.sparkfun.com/tutorials/alternating-current-ac-vs-direct-current-dc/alternating-current-ac&quot;&gt;AC circuit&lt;/a&gt;. The
device uses a sensing element to measure current, produces a time
series of readings, and then transmits these data to a server for
offline processing.&lt;/p&gt;

&lt;p&gt;Because alternating current is defined as a sinusoidal function of
time, instantaneous measurements are meaningless in isolation. That is
to say, since the value of current oscillates periodically, no
individual sample will provide a meaningful representation of the
dataset as a whole. At best it provides you with a snapshot of the
signal’s amplitude at some arbitrary time. To arrive at useful current
measurements, you have to capture the full current waveform and then
typically compute a
&lt;a href=&quot;https://en.wikipedia.org/wiki/Root_mean_square&quot;&gt;quadratic mean&lt;/a&gt; to
arrive at a numerical result in Amperes.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/pseudo-periodicity/single-period-sine-wave.png&quot; alt=&quot;&quot; /&gt;&lt;span class=&quot;figure_caption&quot;&gt;Fig. 1. A single period of a simple sin
 wave, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;y(t) = sin(2πt)&lt;/code&gt;.&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;In order to produce data that characterizes the 60 Hz current
waveform, the sensor
&lt;a href=&quot;https://en.wikipedia.org/wiki/Nyquist%E2%80%93Shannon_sampling_theorem&quot;&gt;has to&lt;/a&gt;
sample the circuit at least 120 times per second. In practice, much
higher sample rates are required because electrical current can
fluctuate on time scales much shorter than one second. Given a sample
rate of 1 kHz, if each datapoint is a 16-bit integer, our sensor
entails bandwidth of at least 16,000 bits/second or just under 2
kilobytes/second. This may not sound like a lot in the modern era of
Big Data™ until one considers the constrained networking environment
in which such sensing devices typically operate. For example, an
electric utility may deploy these devices on
&lt;a href=&quot;https://en.wikipedia.org/wiki/ZigBee&quot;&gt;ZigBee&lt;/a&gt; networks, which have
maximum data rates necessarily measured in kbps. Or the utility may
splurge for access to a cellular data network, in which case our
sensor’s requirement of almost 40 gigabytes of data per month becomes
exorbitantly expensive at any meaningful deployment scale.&lt;/p&gt;

&lt;p&gt;So we’ve got ourselves an objective based on a constraint: to reduce
the bandwidth utilization of our hypothetical sensor.&lt;/p&gt;

&lt;h2 id=&quot;characterizing-the-data&quot;&gt;Characterizing the data&lt;/h2&gt;

&lt;p&gt;By definition, data compression involves taking advantage of certain
properties of a dataset in order to represent it with fewer bits of
information. A simple example is the application of
&lt;a href=&quot;https://en.wikipedia.org/wiki/Run-length_encoding&quot;&gt;run-length encoding&lt;/a&gt;
(RLE) to a set of small positive integers, which can result in the
elimination of the integers’ leading zeros (in two’s complement).&lt;/p&gt;

&lt;p&gt;To apply this strategy to our sensor’s output, we first need to
identify patterns in the data and then figure out how we can exploit
those patterns. The most ripe characteristic of our dataset has
already been mentioned – the fact that AC circuits produce sinusoidal
data. For a constant current, the sampled data would form a simple
&lt;a href=&quot;https://en.wikipedia.org/wiki/Sine_wave&quot;&gt;sinusoid&lt;/a&gt; (the most basic
example thereof is illustrated in Fig. 1). Such a signal could be
encoded in only two quantities: the waveform’s amplitude and phase
angle. Note that the frequency parameters of the wave equation are
fixed for a 60 Hz circuit.&lt;/p&gt;

&lt;p&gt;But of course our example is not that simple. As in electric
utilities’ use cases, we need to be able to monitor realistic
circuits, such as those of a home, commercial building, or data
center. These types of circuits entail variable electrical loads,
which produce data that are still fundamentally sinusoidal, but are
much more messy (see Figure 2).&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/pseudo-periodicity/realistic-example-data.png&quot; alt=&quot;&quot; /&gt;&lt;span class=&quot;figure_caption&quot;&gt;Fig. 2. An example current waveform produced
 by a residential electrical load during a state transition. Y axis
 units are omitted because the sensor output is technically
 unitless. The amplitude is proportional to current, but must go
 through a calibration operation to produce measurements in
 amps.&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;It turns out that there’s an existing body of research related to
signals like these. Whereas vanilla composite waveforms (e.g. Figure
1) are &lt;em&gt;periodic&lt;/em&gt; in the sense that they repeat over and over forever,
a signal can be termed &lt;em&gt;pseudo-periodic&lt;/em&gt; if it can be subdivided into
discrete segments of periodicity [2]. An example pointed out in [2] of
a pseudo-periodic time series is a heart-beat:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;A data set often will exhibit great regularity without exactly
repeating. For example, heartbeats always have the characteristic
&amp;#8220;lub-dub&amp;#8221; pattern which occurs again and again, yet each
recurrence differs slightly from each other. Some beats are faster,
some slower, some are stronger and some weaker. Sometimes a beat may
be &amp;#8220;skipped&amp;#8221;. Nonetheless, the overriding regularity of
the heartbeat is its most striking feature.&lt;/p&gt;
  &lt;cite&gt;William A. Sethares, &lt;a href=&quot;http://sethares.engr.wisc.edu/paperspdf/pnorm.pdf&quot;&gt;&lt;em&gt;Repitition
  and Pseudo-periodicity&lt;/em&gt;&lt;/a&gt;&lt;/cite&gt;
&lt;/blockquote&gt;

&lt;p&gt;Interestingly, this property also applies to the audio waveforms of
music, leading to applications in compression and rhythm analysis
[3]. For the purposes of this article, time series of electrical
current measurements also match this definition. This is apparent by
visual inspection of Figure 2, wherein the signal can be divided it
into three distinct regions:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Time range&lt;/th&gt;
      &lt;th&gt;Characteristics&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;0 - ~220 ms&lt;/td&gt;
      &lt;td&gt;Low-amplitude, periodic&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;~220 - ~440 ms&lt;/td&gt;
      &lt;td&gt;Transient, non-periodic&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;~440+ ms&lt;/td&gt;
      &lt;td&gt;High-amplitude, periodic&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Analogously to how one’s heart-rate fluctuates throughout the day
during periods of excitement or lethargy, the electrical current going
through a circuit fluctuates as connected devices turn on and off. For
our hypothetical sensor, this manifests as a mostly-repeating sequence
of data, interjected by brief periods of perturbation as the signal
shifts to a new pattern.&lt;/p&gt;

&lt;h2 id=&quot;leveraging-pseudo-periodicity&quot;&gt;Leveraging pseudo-periodicity&lt;/h2&gt;

&lt;p&gt;So we have fancy terminology to describe our data, so what?&lt;/p&gt;

&lt;p&gt;Let’s take a step back and consider how a fully periodic time series
could be encoded compactly. By definition, the data repeats itself
over and over for the duration of the dataset. A variant of run-length
encoding could be used, where instead of eliminating sequences of
repeated zeros or ones, entire bit &lt;em&gt;sequences&lt;/em&gt; would be on the
chopping block. Put another way, a periodic dataset presents a similar
opportunity to that presented by the collection of positive integers
mentioned above, but differs in the cardinality of the repeated
pattern.&lt;/p&gt;

&lt;p&gt;This principle applies in kind to pseudo-periodic data, provided we
can identify subsequences that are sufficiently periodic. Given a time
series that can be segmented into locally-periodic regions, we can
encode the periodic parts with a single cycle of the data and an
integer number of cycles over which the cycle repeats. This would be
analogous to deflating a run into a single value and a count in RLE.&lt;/p&gt;

&lt;p&gt;This means that for arbitrarily-long sequences of steady-state current
readings, all we need to convey is a single 60 Hz cycle’s worth of
data and an integer indicating how long the cycle repeats. The
efficacy of this technique scales linearly with the duration over
which it’s applied – deflating a second’s-worth of steady-state data
results in a compression ratio of 60:1, 2 seconds produces 120:1, etc.&lt;/p&gt;

&lt;h2 id=&quot;algorithm-formulation&quot;&gt;Algorithm formulation&lt;/h2&gt;

&lt;p&gt;In order to make use of this compression technique, we need an
automated way to determine that a sequence of data is periodic. This
property is often easy to pick out visually, just as the regions of
periodicity are apparent in Figure 2. If we divide a periodic region
into its constituent cycles and overlay them on top of each other,
it’s clear that the cycles have the same shape:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/pseudo-periodicity/overlaid-cycles.png&quot; alt=&quot;&quot; /&gt;&lt;span class=&quot;figure_caption&quot;&gt;Fig. 3. Forty cycles of electrical current
 samples from a region of periodicity overlaid atop each other. The
 inter-cycle spread is largely due to random noise imposed by
 imperfections in the hardware sensing elements.&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;In order to implement the compression technique described above, an
algorithm is needed to detect periodicity. Such an algorithm could be
deployed to operate on buffered segments of these time series data,
resulting in streaming compression well-suited to sensor output.&lt;/p&gt;

&lt;h3 id=&quot;academic-interlude&quot;&gt;Academic interlude&lt;/h3&gt;

&lt;p&gt;Methods for the detection and characterization of pseudo-periodicity
have been a relatively popular sub-field in academic literature since
the mid-aughts [5, 6]. The publications we surveyed share an
overarching goal of developing an algorithm to determine the precise
mathematical description of a signal’s periodic regions. In contrast
to our need to simply &lt;em&gt;detect&lt;/em&gt; periodicity, the literature was far
more general than was our goal. However, there were of course fruitful
commonalities, including amplitude mismatch [5] between cycles within
a periodic region (which is relevant to any imperfect sensor which
measures things in the real world) and the strategy of computing a
correlation metric by comparing every &lt;em&gt;ith&lt;/em&gt; value in a set of cycles
[6].&lt;/p&gt;

&lt;h3 id=&quot;quantifying-deviance&quot;&gt;Quantifying deviance&lt;/h3&gt;

&lt;p&gt;Rather than diagnosing a signal’s precise parameters and template
function, all we want to do is detect whether or not a time series is
periodic. We could then buffer sensor data for some length of time and
apply our detection function on the buffered windows of data. If the
function returns &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;true&lt;/code&gt;, then we know that the window of data can be
reasonably represented as a single cycle, and thus compressed down by
a significant factor.&lt;/p&gt;

&lt;p&gt;It is worth noting that our compression technique is &lt;em&gt;lossy&lt;/em&gt;. As
illustrated by the spread on the y-axis of the lines plotted in Figure
3, cycles’ amplitudes don’t exactly match even in periodic
regions. Thus we don’t maintain the full raw data when encoding a long
sequence as a single representative cycle. However, in practice we
don’t actually lose &lt;em&gt;useful&lt;/em&gt; information because the amplitude
mismatch can largely be chalked up to minor random noise imposed by
imperfections in the sensors’ physical components. In effect, our
technique has the added benefit of smoothing the sensor data, if
anything.&lt;/p&gt;

&lt;p&gt;Our intuition was to apply a standard
&lt;a href=&quot;https://en.wikipedia.org/wiki/Sum_of_squares&quot;&gt;sum of squares&lt;/a&gt; measure
of variance to a representative sample of sensor data in order to
select a good candidate to serve as the trigger for our algorithm. We
first played with a
&lt;a href=&quot;https://en.wikipedia.org/wiki/Residual_sum_of_squares&quot;&gt;residual sum of squares&lt;/a&gt;
and ended up choosing
&lt;a href=&quot;https://en.wikipedia.org/wiki/Root-mean-square_deviation&quot;&gt;root-mean-square deviation&lt;/a&gt;
because its results are closer in terms of scale to the input
data. That is to say, the RSS grows quadratically as variance
increases, whereas the RMSD will grow linearly.&lt;/p&gt;

&lt;p&gt;With a measure of variance in hand, this leads us into a precise
definition of our algorithm.&lt;/p&gt;

&lt;h3 id=&quot;the-algorithm&quot;&gt;The algorithm&lt;/h3&gt;

&lt;p&gt;At a high level, our streaming algorithm will take as input a chunk of
buffered time series data, determine whether or not it is periodic,
and if so, return a single-cycle representation of the data. Under the
hood, we compute the root-mean-square deviation to assess the
periodicity of the input.&lt;/p&gt;

&lt;p&gt;Given &lt;em&gt;n&lt;/em&gt; seconds’ worth of buffered time series data with a known
cycle frequency, our “adaptive averaging” algorithm
involves three steps:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Averaging&lt;/strong&gt;: Compute a &lt;em&gt;cycle average&lt;/em&gt; by averaging the corresponding samples of
all of the buffered cycles. Put formally, for a set of cycles each
comprising &lt;em&gt;m&lt;/em&gt; data points, from &lt;em&gt;i = 0 to m&lt;/em&gt; compute the average
of the &lt;em&gt;ith&lt;/em&gt; data points of every cycle.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;RMSD&lt;/strong&gt;: Taking the cycle average computed in step 1 as the estimator,
compute its root-mean-square deviation with respect to the raw
cycles themselves.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Threshold-comparison&lt;/strong&gt;: Compare the computed RMSD against a
predefined threshold to produce a boolean value indicating whether
or not the cycle average is sufficiently representative of the
data.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The RMSD can be thought of as an error metric for assessing the
cycles’ closeness to one another. If this error metric exceeds the
threshold, then we cannot reasonably eliminate cycles. If the error
metric is lower than the threshold, then we can consider the cycle
average to be “close enough” to each raw cycle.&lt;/p&gt;

&lt;p&gt;An example is shown in Figure 4. Here we’ve applied the adaptive
averaging algorithm with a one-second window size to a sequence of
data surrounding that shown in Figure 2. The steady-state cases result
in low RMSD values whereas during transient periods of change, the
RMSD spikes considerably.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/pseudo-periodicity/rmsd.png&quot; alt=&quot;&quot; /&gt;&lt;span class=&quot;figure_caption&quot;&gt;Fig. 4. A ten-second snapshot of
 pseudo-periodic time series data and the RMSD values produced by the
 adaptive averaging algorithm with a one-second window size.&lt;/span&gt;&lt;/p&gt;

&lt;h2 id=&quot;example-and-results&quot;&gt;Example and results&lt;/h2&gt;

&lt;p&gt;Bringing this back to our sensor case study, in the steady-state case,
we can compress the time series of current measurements down to a
cycle average and an integer indicating the number of repetitions that
the time series covers. The algorithm is &lt;em&gt;adaptive&lt;/em&gt; in the sense that
it adapts to the degree of periodicity in the data. This manifests in
high compression during steady-state and bursts of lossless data
during intervals of change. So we get low data size when current is
steady, and then when a fridge or an HVAC system kicks on, we get a
brief spike before the current levels off at a new steady-state.&lt;/p&gt;

&lt;p&gt;The compression ratio scales linearly with the duration over which
data is buffered. The following table shows expected steady-state
compression ratios for varying window sizes in terms of the measured
quantity’s period, &lt;em&gt;T&lt;/em&gt;:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Window size, in multiples of &lt;em&gt;T&lt;/em&gt;&lt;/th&gt;
      &lt;th&gt;Compression ratio&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;1&lt;/td&gt;
      &lt;td&gt;1:1&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;10&lt;/td&gt;
      &lt;td&gt;10:1&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;em&gt;n&lt;/em&gt;&lt;/td&gt;
      &lt;td&gt;&lt;em&gt;n&lt;/em&gt;:1&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Thus, if we were to use a one second window size for our sensor
measuring the current of a 60 Hz circuit, we should observe a
compression ratio of 60:1 in steady-state cases. Compared to our
original bandwith of 16,000 bps, our sensor would emit data at an
average rate under 300 bps. This translates to less than one GB/month
of total bandwidth, making the aforementioned ZigBee or cellular
communication use cases much more feasible.&lt;/p&gt;

&lt;h2 id=&quot;other-investigated-areas-of-research&quot;&gt;Other investigated areas of research&lt;/h2&gt;

&lt;p&gt;Along the way towards coming up with the cycle-averaging + RMSD idea,
we investigated a number of areas of research not mentioned thus
far. While not as applicable in the end, they made for very
interesting reading and drove home the point that there’s more than
one way to skin a cat.&lt;/p&gt;

&lt;p&gt;From our stream of raw samples, we could feasibly compute a fast
&lt;a href=&quot;http://betterexplained.com/articles/an-interactive-guide-to-the-fourier-transform/&quot;&gt;Fourier transform&lt;/a&gt;
to decompose the signal into a set of complex numbers or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;(amplitude,
phase)&lt;/code&gt; tuples for each of the harmonics larger than some
threshold. On the server, we could then plug these wave equation
coefficients into &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sin&lt;/code&gt; functions and be done with it. This is a good
option (and one we may eventually implement), but we’ve thus far found
adaptive averaging to be Good Enough for our immediate data size
requirements.&lt;/p&gt;

&lt;p&gt;Facebook’s recent paper on their in-memory time series database called
Gorilla [1] contains an entire section on time series compression,
focusing on delta-of-delta encoding for timestamps and an XOR encoding
scheme for values. These weren’t found to be fruitful for our data,
particularly because the techniques outlined in the paper rely on the
fact that the measurements made by software monitoring systems don’t
often fluctuate on small time scales. Our data is much
higher-frequency and changes constantly. It was Gorilla’s use of
delta-of-delta encoding however that led us down the path of
investigating the idea of comparing &lt;em&gt;ith&lt;/em&gt; data points across adjacent
cycles.&lt;/p&gt;

&lt;p&gt;We went down an indulgent path regarding
&lt;a href=&quot;https://en.wikipedia.org/wiki/Discrete_wavelet_transform&quot;&gt;discrete wavelet transforms&lt;/a&gt;,
a class of functions similar to Fourier transforms that are often used
in image compression. At the core of wavelet theory is the notion of
decomposing a continuous signal into a discrete series of scaled basis
functions. This is compelling, but fell into the same camp as [5] and
[6] in seeking a much more complicated outcome than simply detecting a
specific property of a time series. Wavelets are a rather impenetrable
field of study, but we found [4] to be a reasonable summary.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;As we’ve seen, it behooves the bandwidth-concious to be aware of the
patterns and properties of their data. By exploiting a property of our
specific type of data called pseudo-periodicity, we were able to
reduce the average-case size of our real-world sensor data by an order
of magnitude.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Update:&lt;/strong&gt; The compression technique described in this essay has
since been deployed fleet-wide at Whisker Labs, resulting in a roughly
84% reduction in bandwidth and overall data size.&lt;/em&gt;&lt;/p&gt;

&lt;blockquote class=&quot;twitter-tweet&quot; data-lang=&quot;en&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;&lt;a href=&quot;https://twitter.com/evanm&quot;&gt;@evanm&lt;/a&gt; A fun morning: observing an 84% fleet-wide bandwidth reduction due to our adaptive averaging algorithm &lt;a href=&quot;https://t.co/j26HXUeqYo&quot;&gt;pic.twitter.com/j26HXUeqYo&lt;/a&gt;&lt;/p&gt;&amp;mdash; Evan Meagher (@evanm) &lt;a href=&quot;https://twitter.com/evanm/status/707993539733377024&quot;&gt;March 10, 2016&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async=&quot;&quot; src=&quot;//platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;em&gt;Thanks to
&lt;a href=&quot;http://www.eecs.berkeley.edu/~slanzise/&quot;&gt;Steven Lanzisera&lt;/a&gt;,
&lt;a href=&quot;https://twitter.com/wil&quot;&gt;Wilhelm Bierbaum&lt;/a&gt;, and
&lt;a href=&quot;https://twitter.com/skr&quot;&gt;Johan Oskarsson&lt;/a&gt; for reading and providing
feedback on drafts of this essay.&lt;/em&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;section class=&quot;footnotes&quot;&gt;
  &lt;h2&gt;References&lt;/h2&gt;
  &lt;ol&gt;
    &lt;li&gt;T. Pelkonen, et al, &quot;Gorilla: A Fast, Scalable, In-Memory Time Series Database,&quot; Proceedings of the VLDB Endowment, v.8, n.12, p.1816-1827, August 2015. &lt;a href=&quot;http://www.vldb.org/pvldb/vol8/p1816-teller.pdf&quot;&gt;(link)&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;W. A. Sethares, &quot;Repitition and Pseudo-periodicity,&quot; Tatra Mountains Mathematical Publications, Publication 23, 2001. &lt;a href=&quot;http://sethares.engr.wisc.edu/paperspdf/pnorm.pdf&quot;&gt;(link)&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;W. A. Sethares and T. W. Staley, &quot;Meter and Periodicity in Musical Performance,&quot; Journal of New Music Research, August 2010. &lt;a href=&quot;http://extras.springer.com/2007/978-1-84628-639-1/Papers/jnmr2001.pdf&quot;&gt;(link)&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;C. Valens, &quot;A Really Friendly Guide to Wavelets,&quot; 1999. &lt;a href=&quot;http://agl.cs.unm.edu/~williams/cs530/arfgtw.pdf&quot;&gt;(link)&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;H. Wong and W. A. Sethares, &quot;Estimation of Pseudo-periodic signals,&quot; Dept. of Electrical and Computer Engineering, University of Wisconsin-Madison, May 2004. &lt;a href=&quot;http://sethares.engr.wisc.edu/paperspdf/wong2004.pdf&quot;&gt;(link)&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;M. Small and J. Zhang, &quot;Detecting and describing pseudo-periodic dynamics from time series,&quot; Hong Kong Polytechnic University, August 2007. &lt;a href=&quot;http://small.eie.polyu.edu.hk/pdf/ZhangJieThesis.pdf&quot;&gt;(link)&lt;/a&gt;&lt;/li&gt;
  &lt;/ol&gt;
&lt;/section&gt;
</content>
 </entry>
 
 <entry>
   <title>Design documentation at small companies</title>
   <link href="https://evanm.website/2015/09/design-documentation-at-small-companies/"/>
   <updated>2015-09-24T00:00:00+00:00</updated>
   <id>https://evanm.website/2015/09/design-documentation-at-small-companies</id>
   <content type="html">&lt;p&gt;&lt;img src=&quot;/images/cartographer.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;One component of the engineering culture at Twitter (where I used to
work) that I’m trying to instill at
&lt;a href=&quot;https://whiskerlabs.com&quot;&gt;my new job&lt;/a&gt; is the importance of writing
design documents prior to implementing complicated systems. In this
essay, I will argue in favor of premeditated software design at small
companies and propose what I call “precautionary migration
planning” as a design doc section that caters specifically to
the tradeoffs required by startups.&lt;/p&gt;

&lt;h2 id=&quot;traveling-by-map&quot;&gt;Traveling by map&lt;/h2&gt;

&lt;p&gt;A design document is an outline of a proposed design for a software
system in writing and figures. The level of detail and formality can
vary, but the purpose is to force an engineer to think about and
document what a system should do and how it should be built before
effort is spent on implementation.&lt;/p&gt;

&lt;p&gt;Many large companies enforce design docs for all new projects, going
so far as to prescribe document templates and design review
meetings. While such a formal approach makes sense when projects
require
&lt;a href=&quot;/2014/06/coordinating-technological-change-in-large-software-organizations/&quot;&gt;coordinated effort&lt;/a&gt;
across multiple teams and scores of people, it would be an
inappropriate amount of overhead for an engineering team at a startup.&lt;/p&gt;

&lt;p&gt;But the baby shouldn’t be thrown out with the bathwater. Writing down
and examining your thoughts prior to acting on them is a good way to
avoid mistakes and prevent unwarranted
&lt;a href=&quot;/2013/06/survey-on-technical-debt-management/&quot;&gt;technical debt&lt;/a&gt;. As
such, even at a startup, going through a semi-formal design exercise
injects a healthy amount of peer-review into the process and can
increase the reliability of the systems you end up with. Not to
mention the added benefit of having a good understanding of a
project’s scope and thorough high-level documentation prior to writing
a single line of code. Ideally, when you bring new folks onto the
team, you can simply link them to a set of design docs and save
yourself an hour of whiteboarding.&lt;/p&gt;

&lt;p&gt;A straightforward analogy helps illustrate when a design doc is
appropriate for a new undertaking. A design doc is like a set of
directions and a map. The complexity of a journey determines whether
or not directions are required. For instance, you can walk up the road
to the grocery store without thinking, so you obviously don’t need a
map. Similarly, if all you need to do is add a simple feature or fix a
simple bug, then a rigorous design process is probably unnecessary.&lt;/p&gt;

&lt;p&gt;However, for trips venturing into unfamiliar territory or requiring
multiple vehicles, coordinating travel with a set of directions is a
must. Likewise, if a system at the core of the company’s business has
many moving parts and will affect the lives of numerous people over
its lifetime, then a design doc will probably prove to be worthwhile.&lt;/p&gt;

&lt;h2 id=&quot;external-dependencies&quot;&gt;External dependencies&lt;/h2&gt;

&lt;p&gt;After writing the first couple design documents at Whisker Labs, I’ve
noticed a key difference between what I’m writing now and those I
wrote at Twitter. Critically, the former tend to rely on the
availability of services maintained by unfamilar people at other
companies rather than acquaintances down the hall. For instance, by
making use of Amazon Web Services instead of
&lt;a href=&quot;https://blog.twitter.com/2015/all-about-apache-aurora&quot;&gt;technologies stewarded in-house&lt;/a&gt;,
our services’ uptime is reliant on the diligence of anonymous Amazon
personnel. As the swashbuckling systems cliché goes,
&lt;a href=&quot;http://www.whoownsmyavailability.com/&quot;&gt;you own your availability&lt;/a&gt;,
but you aren’t in control of all of the factors from which it derives.&lt;/p&gt;

&lt;p&gt;Strategies exist for managing the impact of &lt;em&gt;intermittent&lt;/em&gt; outages of
third-party services. RPC interactions can be augmented with features
like retries and failure accrual, or can simply return partial results
as a means to limit the damage caused by temporary downtime. But at a
higher level, years of experience with as-a-service offerings have
shown that there is typically a threshold scale beyond which any given
hosted service ceases to be economical. What we’ve observed is that
almost all companies who bootstrap their software atop
whatever-as-a-service solutions eventually move away from them on
account of cost, reliability, and/or functionality. In the long term,
everybody ends up running their own Graphite and Kafka clusters and
the luckiest of us get our own datacenters.&lt;/p&gt;

&lt;p&gt;Not to mention the trend of services simply disappearing out from
under you, on account of the originating company
&lt;a href=&quot;http://www.economist.com/news/business/21665070-flock-startups-making-cloud-computing-faster-and-more-flexible-most-them-will&quot;&gt;being acquired or otherwise going out of business&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;But for a scrappy, bandwidth-constrained startup team, paying someone
to do the heavy lifting of distributed systems operation is a
no-brainer.  So what does a responsible software engineer do in such
cases when business and productivity concerns demand the usage of
hosted services regardless of their long-term feasibility?&lt;/p&gt;

&lt;h2 id=&quot;precautionary-migration-planning&quot;&gt;Precautionary migration planning&lt;/h2&gt;

&lt;p&gt;The easy (and industry-standard) answer is to throw up your hands and
say “we’ll cross that bridge when we get there.” The pricing and
long-term viability of external services is entirely out of your
control, so why worry about hypothetical futures that you can’t
influence? People still live in Seattle and Portland even though the
mega-quake is coming, right?&lt;/p&gt;

&lt;p&gt;This is a fine answer if you’ve made the conscious decision that your #1
priority as an engineering organization is speed of
execution. Depending on your product or service’s reliability
requirements, the pace of your market, and your bottom line, it very
well may be preferable to put your time to more immediately productive
use than planning for eventualities.&lt;/p&gt;

&lt;p&gt;On the other hand, deciding which failure modes are worth planning for
is part of what makes engineering interesting. The best you can do to
minimize the risk imposed by external dependencies is to come up with
a feasible (but brief) plan for migrating away from them. Consider it a
&lt;a href=&quot;https://en.wikipedia.org/wiki/Precautionary_principle&quot;&gt;precautionary principle&lt;/a&gt;
for SaaS.&lt;/p&gt;

&lt;p&gt;This is why I’m starting to bake such a section into the design docs
that I’m writing. They follow the same principles of situational
awareness and premeditated action that motivates having runbooks for
services, but are more akin to a heart transplant than a simple
runbook item. The sections will:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;List the system’s external dependencies whose long-term feasibility
is deemed at risk (i.e. “&lt;em&gt;&amp;lt;PaaS&amp;gt; will be too expensive by
the time we hit &amp;lt;milestone&amp;gt;&lt;/em&gt;”)&lt;/li&gt;
  &lt;li&gt;List potential replacements for the risky dependency and give a
high-level plan for migrating&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The result of this exercise is a better understanding of a system’s
risk profile and the paths by which the system is likely to evolve
over time.&lt;/p&gt;

&lt;h2 id=&quot;countering-the-logical-conclusion&quot;&gt;Countering the logical conclusion&lt;/h2&gt;

&lt;p&gt;In response to my initial thoughts on this strategy on Twitter, an
esteemed former colleague
&lt;a href=&quot;https://twitter.com/evan/status/646538301181194241&quot;&gt;pointed out&lt;/a&gt; its
logical conclusion, in which the list of “hosted services”
is exhaustive. In literal terms, a program’s “external
dependencies” include the operating system and proprietary
hardware on which it runs, all the way down to the utility company
that supplies the energy powering the computer. In this light,
precautionary migration planning is absurd, given that the engineering
effort involved in reinventing every wheel between your program and
electrons in circuits is well beyond most companies’ capabilities.&lt;/p&gt;

&lt;p&gt;However, I don’t think that this argument refutes the usefulness of
such planning. When done pragmatically, focusing on a reasonable
subset of a system’s dependencies, a team gains the ability to act
quickly when migrations are deemed necessary.&lt;/p&gt;

&lt;p&gt;One way to differentiate external dependencies is by whether or not
they are truly fundamental to a service’s operation. If the power goes
out, a program (or at least a stricken instance thereof) is
unrecoverable regardless of any migration plan. Thus such planning is
only relevant for &lt;em&gt;partial&lt;/em&gt; failure modes, such as the loss of a
hosted database or the end-of-LTS for a specific operating system
version.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Even small ships carry maps. I’ve made a case for the use of design
documents at startups, but a key takeaway is that their use varies
from organization to organization. For some businesses, time spent
planning for hypothetical futures is not time well spent. For others,
it’s a valuable hedge against undesirable outcomes.&lt;/p&gt;

&lt;p&gt;Experience has shown that once an engineering organization reachs a
certain size, a reasonably-rigorous design process is well worth
having in place. A startup team’s habits tend to ossify into company
culture, which is motivation to start thinking about a team’s design
process early. Even if you decide against design documentation in the
early stage of your company, going through the mental exercise of
considering its implications will increase your team’s operational
awareness.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;em&gt;Thanks to &lt;a href=&quot;https://twitter.com/noradio&quot;&gt;Marcel Molina&lt;/a&gt; and
&lt;a href=&quot;https://twitter.com/garru&quot;&gt;Gary Tsang&lt;/a&gt; for reading and providing
feedback on drafts of this essay.&lt;/em&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Introducing Armsible</title>
   <link href="https://evanm.website/2015/07/introducing-armsible/"/>
   <updated>2015-07-13T00:00:00+00:00</updated>
   <id>https://evanm.website/2015/07/introducing-armsible</id>
   <content type="html">&lt;p&gt;&lt;em&gt;&lt;strong&gt;Update:&lt;/strong&gt; Since the publication of this article, Armsible projects
have since been folded into &lt;a href=&quot;https://github.com/whiskerlabs&quot;&gt;Whisker Labs’ GitHub organization&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://s3-us-west-2.amazonaws.com/www.whiskerlabs.com/armsible+logo.png&quot; alt=&quot;ARM + Ansible&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Much ink has been spilled over the “Internet of Things”. A consequence
of this trend is the rise of the
&lt;a href=&quot;https://en.wikipedia.org/wiki/Single-board_computer&quot;&gt;single-board computer&lt;/a&gt;
as a mainstream form factor for application development. With the
popularity of open source&lt;sup&gt;&lt;a id=&quot;fn1ref&quot; href=&quot;#fn1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; platforms like Raspberry Pi,
Arduino, and BeagleBoard, it’s never been easier to build applications
that encompass both hardware and software.&lt;/p&gt;

&lt;p&gt;However, there is less publicly-available material on how to
incorporate single-board computers into larger-scale deployments. A
typical use case involves someone using an ARM computer to monitor or
actuate devices in their home. The deployment workflow is more often
than not akin to a Linux server administered manually through SSH
sessions over the lifetime of the device. In contrast to the level of
automation fetishized in the software operations community, the state
of the art in the open source IoT space is remarkably unsophisticated.&lt;/p&gt;

&lt;p&gt;In spirit, Armsible represents a call-to-action for the use of
industry-standard provisioning tools and techniques in embedded
applications&lt;sup&gt;&lt;a id=&quot;fn2ref&quot; href=&quot;#fn2&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;. Specifically, it is a collection of Ansible
roles and related tools that facilitate the automated deployment of
single-board computers.&lt;/p&gt;

&lt;h2 id=&quot;how-do-i-use-armsible&quot;&gt;How do I use Armsible?&lt;/h2&gt;

&lt;p&gt;As of its unveiling, Armsible boils down to a few Ansible roles and
&lt;a href=&quot;https://github.com/whiskerlabs/armsible/blob/master/local_network_inventory.py&quot;&gt;a dynamic inventory script for targeting hosts on a local network&lt;/a&gt;. The
initial use case is to provision a set of single-board computers on a
LAN.&lt;/p&gt;

&lt;p&gt;Armsible’s focused, albeit limited scope is a consequence of its
intended use in concert with other roles from the Ansible community. A
typical playbook for an embedded project will not be composed entirely
of Armsible roles. Configuration management for standard components
like &lt;a href=&quot;https://github.com/jdauphant/ansible-role-dns&quot;&gt;DNS&lt;/a&gt; is a solved
problem. Armsible fills the gaps between the needs of embedded
applications and the existing suite of roles from the wider community.&lt;/p&gt;

&lt;p&gt;To that end, we’d like Armsible to be the home for the following:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Roles for provisioning specific hardware platforms
(e.g. &lt;a href=&quot;https://github.com/motdotla/ansible-pi&quot;&gt;Raspberry Pi&lt;/a&gt;,
&lt;a href=&quot;https://www.kickstarter.com/projects/beaglecore/beaglecore-100-open-source-iot-device&quot;&gt;BeagleCore&lt;/a&gt;,
Intel Edison)&lt;/li&gt;
  &lt;li&gt;Roles for installing and configuring software components that are
needed by embedded developers but not currently covered by the open
source Ansible community
(e.g. &lt;a href=&quot;https://github.com/whiskerlabs/ansible-watchdog&quot;&gt;the kernel watchdog&lt;/a&gt;,
U-Boot, GPIO configuration)&lt;/li&gt;
  &lt;li&gt;Tooling that enforces best practices for embedded development&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;why-ansible&quot;&gt;Why Ansible?&lt;/h2&gt;

&lt;p&gt;Ansible struck us as the right tool for the job because it is built
around vanilla SSH connections. For embedded devices that run
no-frills distributions of Linux, Ansible is much more applicable out
of the box than other tools that rely on less-ubiquitous transport
protocols and more-complicated topologies.&lt;/p&gt;

&lt;h2 id=&quot;how-is-armsible-organized&quot;&gt;How is Armsible organized?&lt;/h2&gt;

&lt;p&gt;Armsible is structurally inspired by &lt;a href=&quot;http://debops.org/&quot;&gt;DebOps&lt;/a&gt;, a
collection of Ansible playbooks for Debian-based server
deployments. It comprises a number of Ansible roles stored as distinct
repositories within &lt;s&gt;an Armsible GitHub organization&lt;/s&gt; Whisker Labs’
GitHub organization. These roles are published to Ansible Galaxy and
thus installable on the command-line with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ansible-galaxy&lt;/code&gt;. A
&lt;a href=&quot;https://github.com/whiskerlabs/armsible&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bin&lt;/code&gt; project&lt;/a&gt; is provided
to house complementary tools (i.e. dynamic inventory scripts) to be
used in conjunction with Armsible roles.&lt;/p&gt;

&lt;h2 id=&quot;what-plans-exist-for-armsibles-future&quot;&gt;What plans exist for Armsible’s future?&lt;/h2&gt;

&lt;p&gt;The project spawned from the hardware provisioning needs of products
developed at &lt;a href=&quot;https://whiskerlabs.com&quot;&gt;Whisker Labs&lt;/a&gt;. As such, the
project’s initial offerings are a sample of what we’ve developed so
far and are thus limited to the technologies we use.&lt;/p&gt;

&lt;p&gt;Part of the intention behind open-sourcing this work is to foster a
community around IoT hardware provisioning. We encourage anyone
working in this space to take a look at Armsible and help make it more
useful. The best ways to get involved are by filing GitHub issues on
individual projects or joining the conversation in #armsible on
irc.freenode.net.&lt;/p&gt;

&lt;hr /&gt;

&lt;section class=&quot;footnotes&quot;&gt;
  &lt;ol&gt;
  &lt;li id=&quot;fn1&quot;&gt;The technologies in
question are &quot;open source&quot; to varying degrees, but vendors&apos; overall
inclination towards open source is helping push the hardware world in
the right direction. For instance, the Arduino and
BeagleBoard/BeagleBone device families benefit greatly from the
tooling, documentation, and manufacturing ecosystem afforded by open
hardware design. &lt;a href=&quot;#fn1ref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;li id=&quot;fn2&quot;&gt;&quot;Embedded&quot; should really be in air quotes here, given
that we&apos;re talking about machines that run Linux. At the risk of
graybeards not taking me seriously, I&apos;m going to roll with it. &lt;a href=&quot;#fn2ref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content>
 </entry>
 
 <entry>
   <title>Coordinating technological change in large software organizations</title>
   <link href="https://evanm.website/2014/06/coordinating-technological-change-in-large-software-organizations/"/>
   <updated>2014-06-19T00:00:00+00:00</updated>
   <id>https://evanm.website/2014/06/coordinating-technological-change-in-large-software-organizations</id>
   <content type="html">&lt;p&gt;The topic of software scalability seems to bring out the armchair general in everybody. Much of the culture of the software industry is fueled by anecdotal war stories, blog posts, and “this one paper you should read”. We are all knee-deep in an unending stream of literature prescribing ways to achieve maximum computer performance, but the &lt;em&gt;organizational&lt;/em&gt; consequences of hyper-growth get far fewer headlines. I would argue that these consequences have more of an impact on the daily lives of more developers than the scalability of code. The structure of a company can determine what you work on and who you do it with. Without widespread appreciation for the cost of coordinating technology changes across such a dispersed group of people, it’s hard to imagine any single employee not being impacted by wasted time and miscommunication.&lt;/p&gt;

&lt;p&gt;A common tactic for scaling a software engineering organization is to compartmentalize teams around various components that collectively make up the company’s product. The development team may be split into &lt;em&gt;Frontend Engineering&lt;/em&gt; and &lt;em&gt;Backend Engineering&lt;/em&gt;. Each of these may be subdivided into focus areas, terminating in teams that cover specific sets of technologies. In this manner, a company’s team structure is modelled as a tree (conveniently similar to how its personnel fit into a tree-based org chart):&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/eng-team-tree.jpg&quot; /&gt;&lt;/p&gt;

&lt;p&gt;For instance, “Backend Engineering” may encompass any piece of technology deeper in the stack than user-facing clients, from analytics pipelines and application servers down to databases and operating systems. This model is especially well-suited for &lt;a href=&quot;http://developers.soundcloud.com/blog/building-products-at-soundcloud-part-3-microservices-in-scala-and-finagle&quot;&gt;the development of service-oriented architectures&lt;/a&gt;, in which the components of a product’s backend are encapsulated in network services each maintained by small teams.&lt;/p&gt;

&lt;h2 id=&quot;the-burden-of-coordination&quot;&gt;The burden of coordination&lt;/h2&gt;

&lt;p&gt;A consequence of this organizational complexity is an increase in the amount of coordination required to make progress. Given the subdivision into specialized teams, any work to improve the overall product will necessarily involve multiple teams. For example, the task of adding a recommendations widget may spawn work for the web, iOS, and Android client teams, the creation of a new batch job to be built and maintained by the analytics team, and a new API endpoint to be added by an application services team. The burden imposed by this need for top-down, product-oriented coordination is part of what motivates the widespread criticism of “big companies”. Implicit in the idea of being an early employee at a growing company is the ability to be directly involved in the product. As a workforce grows, the perceived ability of any individual to affect change diminishes. Compared to the freedom and breadth enjoyed by employees of short-staffed small businesses, making an impact within a larger organization may seem like more trouble than it’s worth. This sentiment often manifests in technology-driven companies leaving a trail of “startup people” in their wake who step away from the company once it’s survived the trial by fire of early-stage growth.&lt;/p&gt;

&lt;p&gt;However, well-run large organizations benefit from the higher throughput afforded by a larger workforce to apply to problems. A great example of this on a grand scale is &lt;a href=&quot;http://daringfireball.net/2014/06/only_apple&quot;&gt;Apple&lt;/a&gt;, whose ability to “walk and chew gum at the same time” results in concurrent efforts to drastically reshape both their mobile and desktop offerings.&lt;/p&gt;

&lt;p&gt;This covers the macro-level work that trickles down from high-level product decisions, but not the variety that stems from changes deep in the stack. Infrastructure work results in a separate class of communication overhead.&lt;/p&gt;

&lt;h2 id=&quot;bottom-up-coordination&quot;&gt;Bottom-up coordination&lt;/h2&gt;

&lt;p&gt;The often underestimated counterpart of this top-down coordination is the cost of the &lt;em&gt;bottom-up&lt;/em&gt; coordination imposed on developers working on infrastructure. By “infrastructure” I mean any technology that is depended upon by other developers. In this context, infrastructural work would include library development, database administration, and service ownership. For these kinds of teams, making profound changes implies effort to coordinate with numerous teams. For example, before migrating to a new database or replacing a deprecated library, the initiating team will have to communicate with many others. These scenarios inevitably cause friction with other teams, whether by imposing unplanned work on them or simply adding the operational risk of deploying new code.&lt;/p&gt;

&lt;p&gt;Part of what distinguishes great infrastructure teams is a sense of empathy for those that depend on them. When attempting to move an organization forward with a new technology, such a team will reduce the barrier to entry by addressing any likely concerns and minimizing the amount of work that developers have to do to make the switch. By going the extra mile to ease the lives of others, the team initiating the change improves the likelihood of success and greases the wheels of forward progress.&lt;/p&gt;

&lt;h2 id=&quot;preventing-surprises&quot;&gt;Preventing surprises&lt;/h2&gt;

&lt;p&gt;When rolling out a new technology, the goal is to lessen the likelihood of something unexpected happening. This involves predicting and documenting the things that are unavoidably apt to change as a consequence of the new technology. To those without context, &lt;em&gt;any&lt;/em&gt; change will be unexpected, so the main thing to strive for is increasing the organization’s collective awareness of the change without being annoying.&lt;/p&gt;

&lt;p&gt;Thorough documentation can go a long way, whether it be on a wiki, an email, or whatever communication mechanism the company relies on. A good way to frame migration documentation is in terms of the deficiencies of the old way and how the new hotness will improve the situation. “We’re hitting the safe upper limit of how far we can scale Database Product X within budget and our testing shows that Database Product Y will suit our projected needs for the next year and save us &lt;em&gt;n&lt;/em&gt; dollars per month.”&lt;/p&gt;

&lt;p&gt;Part of this documentation’s purpose is to walk developers through the process of migrating their projects to the new hotness. This will vary depending on the type of migration. For instance, a library change would call for introductory background information, before/after code samples, and links to any relevant API reference documentation. It’s important to mention any operational effects the changes may have. For instance, if the new APIs entail different resource utilization rates (e.g. object allocation, TCP connection churn) or behavioral changes, then the documentation should include specific metrics to keep an eye on when deploying the new code.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Coordinating changes within large software organizations is a necessary evil. There are serious downsides to doing too little or too much, so keeping a manageable number of people informed is a balancing game. Given the definitionally wide reach of “infrastructure”, bottom-up coordination is a key part of introducing new technologies within an organization.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;em&gt;Thanks to &lt;a href=&quot;https://twitter.com/rubeydoo&quot;&gt;Ruben Oanta&lt;/a&gt; and &lt;a href=&quot;https://twitter.com/skr&quot;&gt;Johan Oskarsson&lt;/a&gt; for reading and providing feedback on drafts of this post.&lt;/em&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Survey on Technical Debt Management</title>
   <link href="https://evanm.website/2013/06/survey-on-technical-debt-management/"/>
   <updated>2013-06-04T00:00:00+00:00</updated>
   <id>https://evanm.website/2013/06/survey-on-technical-debt-management</id>
   <content type="html">&lt;p&gt;First coined by &lt;a href=&quot;http://dl.acm.org/citation.cfm?id=157715&quot;&gt;Ward Cunningham in 1992&lt;/a&gt;, the concept of “technical debt” is widely known within the software engineering community. It evokes other colloquialisms such as “code rot”, “cruft”, and “kludge”. The word “hack” is often used synonymously, but its usage is now overloaded and popularized to the point of meaninglessness. From his keynote presentation at the &lt;a href=&quot;http://www.sei.cmu.edu/community/td2013/program/?location=secondary-nav&amp;amp;source=718317&quot;&gt;2013 International Workshop on Managing Technical Debt&lt;/a&gt;, Steve McConnell (of Code Complete fame) provides a good working definition of technical debt:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A design or construction approach that&apos;s expedient in the short term but that creates a technical context in which the same work will cost more to do later than it would cost to do now.&lt;/p&gt;
&lt;cite&gt;&lt;a href=&quot;http://www.sei.cmu.edu/community/td2013/program/upload/TechnicalDebt-ICSE.pdf&quot;&gt;Steve McConnell, &lt;i&gt;Managing Technical Debt&lt;/i&gt;&lt;/a&gt;&lt;/cite&gt;
&lt;/blockquote&gt;

&lt;p&gt;A sizable portion of the work done by my team at Twitter classifies as paying down technical debt. This is by no means meant as a negative. The performance gains from transitioning a Rails-based infrastructure into &lt;a href=&quot;http://blog.oskarsson.nu/post/40196324612/the-twitter-stack&quot;&gt;an ecosystem of JVM services&lt;/a&gt; have been gratifyingly enormous and the work itself is intellectually enriching. However, dealing with technical debt is generally considered to be undesirable in favor of feature development.&lt;/p&gt;

&lt;p&gt;This sentiment is totally understandable. Greenfield work is sexy and fits the trope of the lone hacker cranking out code, fueled by caffeine and the Social Network soundtrack. The harsh reality is that when you’re working on systems of any meaningful scale, building in isolation is rare. There will always be dependencies, requirements, or even simply code you wrote two weeks ago that gets in your way.&lt;/p&gt;

&lt;p&gt;Technical debt is a natural part of the software development process, and is thus unavoidable. There exist software anti-patterns that produce predictable debt, as codified in Michael Duell’s &lt;a href=&quot;http://www.fsfla.org/~lxoliva/fun/prog/resign-patterns&quot;&gt;Resign Patterns&lt;/a&gt;. Through awareness and internalization of sanitary development techniques, one can prevent certain classes of technical debt from occurring in the first place. But for the inevitable cases when it falls through the cracks, a manageable strategy is to be mindful of the debt as it accumulates and to periodically make a concerted effort to pay it down.&lt;/p&gt;

&lt;h2 id=&quot;mindfulness-toward-technical-debt&quot;&gt;Mindfulness toward technical debt&lt;/h2&gt;

&lt;p&gt;Just as with financial debt, there are multiple classes of technical debt with varying levels of insidiousness. There is “high interest” debt that will waste countless future hours of work. An example of this would be an inconsiderate choice of framework, resulting in great expense to port to a different system later on. In contrast, an item of low interest debt could be putting off writing a class’s test suite until after a milestone. If paid down soon after being taken on, this type of debt can be acceptable. However as low interest debt piles up, both in quantity and lifetime, it is increasingly dangerous and more onerous to deal with. If a development team is diligent about avoiding high and reducing low interest debt, they will be much more effective at reaching goals and staying productive in the long term.&lt;/p&gt;

&lt;p&gt;Another axis on which to characterize debt is whether or not it’s taken on intentionally. Teams accrue intentional debt by making conscious decisions about the feasibility of their being able to handle the debt load later on. “We need to ship this feature ASAP, so let’s skip these tests until our next sprint.”&lt;/p&gt;

&lt;p&gt;Unintentional debt is taken on carelessly, either by individuals’ actions or institutional change. On the level of an individual, a junior developer or contractor could introduce changes that render a system less maintainable. Depending on the complexity of the problem, code review is an effective preventative measure for these situations. Harder to deal with are large-scale events that inadvertently introduce vast tracts of debt. For example, the integration of an acquired company’s codebase or a coordinated refactor could leave a system in a less tenable state than it was before. There is no one-size-fits-all solution for such cases and they exemplify the importance of remaining mindful of debt accumulation.&lt;/p&gt;

&lt;p&gt;In addition, it is important to &lt;em&gt;track&lt;/em&gt; debt. With a log of specific debt items, a team can assess their debt load at any point and act accordingly. Without one, they are blindly flying into a minefield, condemned to endlessly fit square pegs into round holes. There is no way to reasonably fix the unmeasured quantity.&lt;/p&gt;

&lt;h2 id=&quot;planned-payment-of-technical-debt&quot;&gt;Planned payment of technical debt&lt;/h2&gt;

&lt;p&gt;Once a team locks down the rate at which they accumulate debt and makes a concerted effort to avoid the high-interest kind, paying down what remains is much more straightforward. From there, it’s simply a matter of prioritizing items in the debt log and chipping away at them.&lt;/p&gt;

&lt;p&gt;The application of positive habit formation tactics can be very effective here. Just as someone wanting to get in better shape can explicitly plan gym visits into their schedule, software development teams can plan debt-reduction periods into your release cycles. This can take many forms, depending on the temperament of the team:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Baking debt-repayment into the sprint cycle. (e.g. devoting a portion of each sprint or one entire sprint per month/quarter to tackling items on the debt log)&lt;/li&gt;
  &lt;li&gt;Having a debt-reduction rotation wherein individuals focus on debt during their duty cycle.&lt;/li&gt;
  &lt;li&gt;Spinning out debt-reduction into its own project with a separate pool of resources. I’m admittedly skeptical of this approach. It seems to be analogous to a garbage collection problem, in which a mutator (the development team) is continuously introducing work items to be fixed by a collector (the debt-reduction squad). This is theoretically feasible if debt introduction is kept at a reasonable rate, but the division seems unmanageable to me.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;McConnell’s viewpoint is abstract and arguably too high level to be of much use for certain development teams. The strategy presented here meshes well with what I’ve experienced at Twitter, but I admittedly may be writing from a BigCo stance. It’s been &lt;a href=&quot;https://gist.github.com/evnm/30617c34575872d3b60d#comments&quot;&gt;pointed out&lt;/a&gt; that McConnell’s principles don’t necessarily suit the realities of smaller companies. It would be interesting to examine this statement in another post, focusing on debt accumulation and fallout as companies grow.&lt;/p&gt;

&lt;p&gt;Technical debt is often preventable, but an inevitable part of the software development process. As much as it hurts one’s pride to hear it, everyone writes unthoughtful code some of the time. In order to keep systems maintainable, teams must adopt a strategic approach to controlling the rate at which debt accumulates, tracking the specific items that are deemed short-term-acceptable, and paying them down. Through this, a team can avoid much of the productivity and morale degradation associated with technical debt buildup.&lt;/p&gt;

&lt;p&gt;If you find this topic interesting, I would encourage you to read through &lt;a href=&quot;http://www.sei.cmu.edu/community/td2013/program/upload/TechnicalDebt-ICSE.pdf&quot;&gt;McConnell’s slides&lt;/a&gt;. My notes on the slides are available in &lt;a href=&quot;https://gist.github.com/evnm/5695408&quot;&gt;this gist&lt;/a&gt;.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;em&gt;Thanks to &lt;a href=&quot;https://twitter.com/trevorbramble&quot;&gt;Trevor Bramble&lt;/a&gt;, &lt;a href=&quot;https://twitter.com/mrb_bk&quot;&gt;Mike Bernstein&lt;/a&gt;, and &lt;a href=&quot;https://twitter.com/falun&quot;&gt;Richard Bailey&lt;/a&gt; for reading and providing feedback on drafts of this post.&lt;/em&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>TTLs for Dropbox</title>
   <link href="https://evanm.website/2011/10/ttls-for-dropbox/"/>
   <updated>2011-10-31T00:00:00+00:00</updated>
   <id>https://evanm.website/2011/10/ttls-for-dropbox</id>
   <content type="html">&lt;p&gt;A bunch of friends and I have a Dropbox shared folder in which we swap files of various (legal) sorts. Most of the folks in the group aren’t Dropbox zealots like myself who find ways to get 9+ GB for free. Thus the size of the directory in question becomes an issue as large forgotten files start to eat up others’ precious 2GB of space.&lt;/p&gt;

&lt;p&gt;As a solution to this problem, I wrote &lt;a href=&quot;https://gist.github.com/1326602&quot;&gt;a Node.js program&lt;/a&gt; that in essence lets you assign &lt;a href=&quot;http://en.wikipedia.org/wiki/Time_to_live&quot;&gt;TTLs&lt;/a&gt; to items within a Dropbox directory. It runs as a daemon and deletes any files older than a specified lifetime.&lt;/p&gt;

&lt;p&gt;For example, to run a daemon that checks the directory &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Dropbox/expirable-items&lt;/code&gt; once a day for items that are older than a week, modify the variable declarations thusly:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;dirToWatch&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;expirable-items&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;ttl&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;604800000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// 7 days&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;interval&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;86400&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// 24 hours&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The program depends on the log.js and dropbox Node modules:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ npm install log dropbox
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Startup and delete events are logged to stdout, so redirect as you see fit:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ node app.js &amp;gt; dropbox-ttl.log
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</content>
 </entry>
 
 <entry>
   <title>Teach Scala to undergrads</title>
   <link href="https://evanm.website/2011/09/teach-scala-to-undergrads/"/>
   <updated>2011-09-26T00:00:00+00:00</updated>
   <id>https://evanm.website/2011/09/teach-scala-to-undergrads</id>
   <content type="html">&lt;p&gt;A symptom of Scala’s growing popularity is the incessant discussion of its place in the bevy of industrial programming languages. This debate is often confusing, as both advocates and detractors of the language at times use the same argument in their favor: that Scala’s complexity renders it unfit for use by the average developer. This talking point may generate votes on Hacker News, but it isn’t remarkably productive at improving the state of software development.&lt;/p&gt;

&lt;p&gt;People have been demonizing the rise of &lt;a href=&quot;http://www.joelonsoftware.com/articles/ThePerilsofJavaSchools.html&quot;&gt;JavaSchools&lt;/a&gt; for years and I believe Scala to be an effective countermeasure. It represents the perfect supplement to a programming languages course, with the ability to show students how powerful functional programming is when applied to “real world problems”. As a single example, seeing how one can use higher order functions to avoid manual iteration through collections is enough to at least show students how much easier life can be with Scala.&lt;/p&gt;

&lt;noscript&gt;&lt;pre&gt;400: Invalid request&lt;/pre&gt;&lt;/noscript&gt;
&lt;script src=&quot;https://gist.github.com/1239014.js&quot;&gt; &lt;/script&gt;

&lt;p&gt;I posit that the outlook of many students coming out of PL courses is akin to this continuum:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/pl-continuum.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;On one end you have “academic” languages like Haskell, ML, and Scheme which are interesting, but esoteric and impractical in that they’re rarely used in production environments due to their difficulty. On the other are the common currency of most software developers: Java and C (and Ruby and Python within more hip circles). The languages on the right are influenced by the research that culminates in the languages on the left in the same way that mainstream musical artists say that they listen to Thelonious Monk and Stravinsky to get ideas.&lt;/p&gt;

&lt;p&gt;Scala fits somewhere in the middle. It’s a reasonably approachable language with a rapidly growing community and ample room for neckbearding. As proven by Foursquare, Tumblr, Twitter, Yammer, etc, Scala is a remarkable language for building the kinds of systems that CS students swoon over. After teaching ML, Haskell, or Scheme (WLOG), one could use Scala to show that many of the most expressive features of functional programming can be harnessed for use in a JVM language. Helping students connect the dots between imperative and functional programming would be a valuable lesson that many students don’t fully understand.&lt;/p&gt;

&lt;p&gt;More emphasis should be placed on experimenting with ways of raising the bar of the “average developer”. While I agree with the sentiments behind the notion that Scala is &lt;a href=&quot;http://goodstuff.im/scala-use-is-less-good-than-java-use-for-at-l&quot;&gt;“too hard for a large portion of the Java community”&lt;/a&gt;, this comes off as more of a statement about Java developers than about Scala. If Scala is going to be pigeonholed into strictly being for a higher class of programmer, then why not enlighten students in their formative years?&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: This argument could just as easily be made in favor of Clojure. The point is to experiment with improving the state of average instead of saying things are too hard.&lt;/em&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Two months in</title>
   <link href="https://evanm.website/2011/09/two-months-in/"/>
   <updated>2011-09-05T00:00:00+00:00</updated>
   <id>https://evanm.website/2011/09/two-months-in</id>
   <content type="html">&lt;p&gt;Like countless others on the internet, I’ve been “meaning to write more” for a long time. Under the assumption that Wordpress puts too much process into the task of blogging, I’ve designed a new personal website using &lt;a href=&quot;https://github.com/mojombo/jekyll&quot;&gt;a simpler tool&lt;/a&gt;. Hopefully the ability to write essays using the same workflow that I use to write code will grease the wheels of expression.&lt;/p&gt;

&lt;p&gt;My old Wordpress site is now accessible at &lt;a href=&quot;http://old.evanmeagher.net&quot;&gt;old.evanmeagher.net&lt;/a&gt;. The new site is hosted on GitHub and its source is available &lt;a href=&quot;https://github.com/evnm/evnm.github.com&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Last friday was the two month mark of my employment at Twitter, Inc. I don’t think that I could be happier with my current situation. Twitter is proving to be exactly the workplace that I was hoping for: a friendly and open atmosphere with brilliant coworkers more than willing to help me learn everything that I can as quickly as possible. Coming out of college, it’s exactly the kind of environment that I want to be in to further my technical education.&lt;/p&gt;

&lt;p&gt;As for the contents of this blog, I intend to write about what I learn. At the moment, this would include things about Scala, functional programming, and distributed systems, but my interests are bound to ebb and flow as I work on different projects and interact with different people.&lt;/p&gt;

&lt;p&gt;To keep up to date with me, you can &lt;a href=&quot;http://evanmeagher.net/atom.xml&quot;&gt;subscribe to this blog&lt;/a&gt; or &lt;a href=&quot;http://twitter.com/evanm&quot;&gt;follow me on Twitter&lt;/a&gt; for more granular updates.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Graduation</title>
   <link href="https://evanm.website/2011/06/graduation/"/>
   <updated>2011-06-27T00:00:00+00:00</updated>
   <id>https://evanm.website/2011/06/graduation</id>
   <content type="html">&lt;p&gt;It’s been a little over two weeks since I graduated from college. Tomorrow I’ll pack my life into a truck and begin the 800-mile journey from Seattle to San Francisco.&lt;/p&gt;

&lt;p&gt;This move has been the light at the end of my tunnel for the past six months. In December, I turned down a job at Google Seattle in favor of one at Twitter, to the bewilderment of many of my friends and family. With a new city and an exciting job looming on the horizon, I’ve spent the first half of 2011 finishing my last two quarters of school and mentally preparing myself for a head-first dive into Silicon Valley.&lt;/p&gt;

&lt;p&gt;As I begin a new chapter of my life, it seems like as good a time as any to take a crack at my lofty, neglected goal of writing more. Thus, I’ve created this blog on which to write about things that interest me. Stay tuned to see if I follow through.&lt;/p&gt;
</content>
 </entry>
 

</feed>
