How long will it take for you to deliver my MVP application? May 29, 2017

Ah, the age-old question that eludes anyone who wants to build custom software: How long is this going to take and what will it cost me?

I've been on the receiving end of this question numerous times. And until now, I always butchered the answer. Because in order to properly assess cost when we're building software, it's inadequate to assess the cost of building the software you think your business needs. Instead, a great consultant will analyze your business's unique situation and recommend a path resulting in business outcomes that don't strain your budget and get you to market faster.

Ask yourself: What is the value you hope to deliver to your users? Can you deliver a small part of that value with less effort than you’re envisioning presently, and get it to market faster? Are you operating with invalid assumptions about how your users will behave and what they'll expect?

Imagine you go to a software vendor and tell them "I want to build a car!" They give you a specification for building a car and tell you it'll cost $50,000. You cringe at the price, but go forward with it, because you need to build the car.

A great consultant will ask you why you want to build a car. "Because I want to get across town!" you'll say. And then they'll ask you if a bicycle for $500 will get the job done.

When vetting a consultant to take on your MVP project, it's critical to ensure they possess both the hard skills required to build a working application and the experience to know when what you’re asking them to build isn’t in your best interest.

You're trying to find a consultant who will find the simplest solution to your problem, as opposed to building what you tell them. Building the thing is the easy part. The hard part is defining the thing to build that produces the outcome you desire at the lowest cost.

Rather than building a wireframe specification and handing it to a developer to implement as you've specified, you'd be better off to seek a consultant who can unpack your business, analyze its core needs in the context of technology, and then deliver to you working software week after week.

If you're non-technical, you're probably not in a place to understand the technical consequences of what you want to build. When your ideas are placed under that scrutiny, you might change course because there's a more expedient way you didn't see before.

Are your rituals serving you? May 5, 2017

We knowledge workers love rituals. We're always seeking ways to reduce friction, increase productivity, and increase visibility. There's Agile, XP, Kanban, Pair Programming, and now even Mob Programming. There's an entire industry within an industry devoted to teaching others how to apply these principles.

Some teams hold a daily standup. Most hold some form of an iteration planning meeting. And some apply points-based estimations during their planning meetings.

Both standups and estimation have value, depending on your team. If you have a dedicated project manager who scopes the next sprint's work, they might benefit from points-based estimations because they can measure how much progress to expect next. And if you work on a team building a high-touch customer-oriented product, you might benefit from a daily standup to keep your non-technical stakeholders in the loop.

But I've been on too many teams who did one or both of these rituals even though they didn't provide any tangible value. And in many cases, the maturity of modern network tools has rendered these rituals all but obsolete.

Are your daily standups redundant?

Before the likes of GitHub pull requests, it was difficult to, at a glance, see what your teammates were spending their time on. If they had a question, the daily standup served as a space for making inquiries without feeling like you were interrupting their day.

But now that GitHub pull requests enable a one-click view of ongoing efforts by your team and a vehicle through which questions can be asked and answered on our own time, the daily standup is a relic of a less connected past.

And even if you do commit to a daily standup, does it necessarily need to be a synchronous meeting where everyone is present at the same time? I've worked on a team with a #standup Slack channel. We each post our daily standup in the room. Everyone can read up on what the rest of the team is doing that day and whether they're blocked. And no one has to interrupt their workflow to do it.

Ask yourself: Do you get much or any value from your standup, or is it just another mindless ritual?

Are your estimations meaningless?

Stakeholders want to know how much their software is going to cost. This is a reality with which every software developer must contend. But another reality is that software estimation is a losing game.

We can try, to the best of our ability, to assess a software problem and estimate how long it will take to come up with a solution. Armed with an understanding of a fixed software problem, estimating the time to build a solution is actually relatively easy. But software problems are rarely understood correctly ahead of time, and are rarely ever fixed.

Most software problems are complex enough that they require further inquiry after beginning development. There might be a variable we didn't consider during estimation. We might have misunderstood the original problem and gotten that feedback from the customer halfway into development. When was the last time you developed a piece of software without asking for clarification from your customer in the midst of development?

And even if you're fortunate enough to understand a problem thoroughly enough to implement it to the customer's desires the first time, there's a good chance they'll change their mind about it in the middle of development. Maybe they think of a better way. Or maybe business conditions have changed and it makes more sense to do things differently. Whatever the reason, requirements change. And when requirements change, you can kiss your original estimate's accuracy goodbye.

Okay, then what do we do instead?

Estimation and daily standups attempt to solve a real problem: Making sure everyone involved in your project is held accountable and are aware of the changing conditions of your project.

If your team reports that they find value in these activities, then keep doing them.

But if you really consider the opportunity cost of continuing to live by these rituals, you might find their cost outweighs their benefit.

Does interrupting everyone's flow during ongoing high-value development work to hold a daily standup have a net benefit to your team's productivity and happiness? Or would the team be better informed by committing to reviewing open pull requests and tickets once per day on their own time?

Are your estimations providing your product owner with valuable insight into what progress they should expect in the coming months, or are your estimates so skewed from reality that they're meaningless?

Do you own your rituals, or do your rituals own you?

Only build the bare minimum April 28, 2017

Founders ought to be a bit less ambitious.

When you bring software to the marketplace, you're competing for attention in a cruel world. Where you focus your resources matters immensely. Because complexity in software is a multipler, new features built today will cost time, effort and money tomorrow.

That's why it's critical to build the tiniest product you can first. The sooner your application is humming along in a real person's hands, the sooner they're going to tell you all the reasons they love or hate it.

Feedback from real users as early as possible is the most valuable asset to your team. When the only user feedback comes from an insulated CEO or project manager, it's likely the feedback received, while well-meaning, is going to be at least a few degrees away from the needs of your users.

Complexity is a multiplier April 27, 2017

If there were one sort of interaction I wish I could take back from all my time as a software consultant, it would be every time I nodded my head at a client when they asked me to add one more feature, knowing full well that its addition would be costly and that the client should place their assumptions about its benefit under more scrutiny.

Considering my title of Digital Product Consultant, you'd think I was up to the task. But a point I think deserves being driven home is how we consultants are paid to increase revenue and decrease cost, even though sometimes we act as though we're paid to follow directions.

The fact is, someone who pays money for custom software isn't necessarily going to be aware of the ongoing costs of maintaining a specific software feature. And these costs, depending on the architecture of a given system and its dependencies, can balloon exponentially. That's because added complexity to a software product multiplies cost.

When your application has a single button that, when pressed, shows a predetermined text string on-screen, you've built a simple program. When you make the button show a bit of randomly selected text from a list when pressed, you've built a slightly more complex program.

With each new feature we add to a software program, the resulting complexity increases. It's easy to assume the increase in complexity (and therefore, the inversely correlated decrease in ease of understanding) is a linear progression. But each feature actually increases complexity exponentially.

This means that for each new feature, it's likely you're going to multiply—not add to—the overall cost of maintaining your software.

Therefore, it's prudent to consider the long-term ramifications of implementing a feature. The real cost center is not in its implementation, but in its continued support. How does the new feature play with existing ones? What happens if we later want to remove it? How will our users react?

What are some ways consultants can help their clients better understand the ramifications new features could have on their ongoing maintenance costs? And what are some ways you can protect yourself if you've hired a consultant but are unsure whether you next feature request will balloon into a Great Expensive Ball of Doom?

Is it additive or foundational?

Does the new feature sit beside or on top of other features in a way that doesn't stand to negatively impact other parts of the application? Is the feature orthogonal, meaning it neither creates nor propagates side effects to other parts of your application? If so, the chances are lower that implementing and shipping the feature will result in regressions or service outages. This is what I call an additive feature.

But if your feature involves widespread changes to fundamental components of your application that are in production, mission-critical, and costly should they malfunction, then you're implementing a fundamental feature. In this case, you ought to spend more time analyizing the costs and benefits of building it.

Performing a cost benefit analysis

If you've identified that your new feature will likely have an impact on existing mission-critical infrastructure, you'll want to do a bit of analysis before you give the thumbs-up to have it built.

List the potential externalities that could arise when shipping the new feature. Could it disrupt orders from being processed? Is there a chance that users won't be able to sign in for a brief period of maintenance time? Will you need to perform an intensive migration on your database that could cause downtime and/or integrity concerns?

List each of these and attempt to quantify the best and worst case scenario you can imagine, in terms of the costs to the business.

For instance, if you think there's a chance you could see some downtime to your sales pipeline for 10 minutes up to 1 hour, and on a typical day you see $24,000 in sales, you stand to lose up to $1,000 in sales as a result of implementing the feature. You'll also want to account for the opportunity cost associated with the hours (or days) your team spends resolving the regression.

In addition to the lost dollar value, you should also consider intangible costs like costs to your brand's value, customer perception, and team morale. While these costs are not necessarily measurable, they have a profound effect on your business over time.

When you spend the extra time coming to terms with the potential externalities of implementing a new feature, you'll increase the reliability of your product and reduce stress resulting from outages. While new features stand to make your product more valuable and stand out among your competition, carefully considering how they will affect your existing featureset can save you time, money, and headaches.

The real formula for marketing success April 26, 2017

We read books that purport to uncover the techiques that will propel us to greatness. Some say how to get more followers on social media. Others say to quit social media entirely. Some advocate sending emails to influencers. Others say you should speak to an existing audience instead of trying to create your own.

But really, all of the so-called gurus want the same thing you do. They want success. They want a following. They want admiration. They want business.

There's nothing wrong with following the advice of marketing gurus. But in my experience, success in the marketplace comes down to one factor: Whether or not you add value to someone else's life.

Every single time I've found success in my career, it had little or nothing to do with my Twitter feed, drip marketing campaigns, or my email subscribers. These are all amazing tools when used properly. But at the end of the day, publishing clickbait articles with little substance or value is a waste of your time and the time of your fellow Internet citizens.

I think that instead of spending our time hacking human attention, we ought to be asking ourselves what we can do to truly help and engage others. It's the more difficult path, for sure. But I think it's the only one which ultimately results in lasting, fruitful business relationships.

Learning Elm April 25, 2017

Elm is "a delightful language for reliable webapps."— or so its homepage says. Today, I'm going to dive in head-first to find out what all the fuss is about.

For those of you unacquainted, here are some of Elm's purported features, straight from its homepage:

  • Compiles to JavaScript: The language targets JavaScript specifically
  • No runtime exceptions: Instead of producing runtime exceptions, Elm uses type inference to detect problems during compilation.
  • Great performance: Like React, Elm uses a virtual DOM designed for simplicity and speed.

Sounds cool. Let's fire it up then, shall we?

Installing Elm

If you're on a Mac like I am, Elm has a Mac installer available here. The current stable version is 0.18. The '0' at the beginning doesn't give me much confidence in using Elm in production, but if Pivotal is doing it then maybe it's worth a try?

After completing, the installer tells us:

A bunch of useful programs were just placed in /usr/local/bin/

Installing the Vim plugin

Since I use Vim, I'm going to go ahead and install the elm.vim plugin:

  $ cd ~/.vim/bundle
  $ git clone https://github.com/lambdatoast/elm.vim.git

Easy enough.

Hello World

When learning a new language, there are two benchmarks of expertise: Hello World and Todo.

Elm appears to be no exception. Let's follow this Hello World tutorial on the elm-tutorial.org site.

Create a project folder

First we create a new folder for our Hello World application. I called mine hello-elm:

  $ mkdir hello-elm

Install packages

It looks like first we need to install the package elm-lang/html. Why that's not installed by default I'm hopeful will be revealed later on...

  $ elm package install elm-lang/html
  Some new packages are needed. Here is the upgrade plan.

    Install:
        elm-lang/core 5.1.1
        elm-lang/html 2.0.0
        elm-lang/virtual-dom 2.0.4

 Do you approve of this plan? [Y/n]

Ooh, do I approve? I feel like a boss. Yeah, I approve.

Starting downloads...

  ● elm-lang/virtual-dom 2.0.4
  ● elm-lang/html 2.0.0
  ● elm-lang/core 5.1.1

Packages configured successfully!

First impressions of package management: Elm is pretty freaking mature for a 0.18 release! Would be nice to see NPM/Yarn-style progress bars, but so far this feels solid.

The elm package install command seems to have created the following stuff in the directory:

elm-package.json
elm-stuff

Write some code

Okay, now we're going to create our first Elm module. Exciting. Here's mine:

module Hello exposing (..)

import Html exposing (text)

main =
    text "Hello"

I put that in Hello.elm. Right now it's not clear to me whether that should be in the elm-stuff directory or in the root directory. I put it in the root.

Now we run elm reactor:

  $ elm reactor

Interesting. So it looks like Elm has a sort of "dashboard" view of your files, packages, and dependencies. Clicking on our Hello.elm file takes us to our application, which at this point is just the text "Hello" in the top-left corner of the page.

Some thoughts about what I've seen so far:

  1. There's a module named Html. The fact that Elm treats the DOM as a first-class concept as opposed to relying on class-like abstractions as in standard JavaScript is a welcome change as we move toward functional UI paradigms.
  2. The compile time for a Hello World application seemed awfully long. I'm not sure if it was just a fluke on my machine, but it took 2-3 seconds before my app loaded. I could understand if we had a complex application, but this is Hello World...

Okay, let's keep going...

Rendering complex markup

So far, it looks like we can render text using the text function. I'm digging around in the documentation and found an examples page. I poked around a few of these until I found an example of rendering an unordered list.

It looks like Elm's composition syntax is Lisp-ish, but not Lisp:

import Html exposing (li, text, ul)
import Html.Attributes exposing (class)

main =
  ul [class "carbonated-beverages"]
    [ li [] [text "La Croix"]
    , li [] [text "Zevia"]
    , li [] [text "Pepsi"]
    ]

Some observations here:

  1. Because Elm is functional, even attributes need be imported. Whereas in ES6, we need only import a module in order to gain access to all its getters and setters, Elm requires explicitly importing things like class in order to use them.
  2. It is a welcome change to see a main function that returns a DOM tree. In React, there's a bunch of boilerplate to attach a component to the DOM. In Elm, all of that boilerplate is baked into the language.
  3. The slow compile time appears to have been a fluke. This new example compiled almost instantly.

A word about Elm's architecture

It looks like Elm has its own application architecture that it lovingly calls the ... Elm Architecture.

It consists of:

  • Model: the state of the application
  • Update: a way to update the state of the application
  • View: the resulting view of your state as HTML (or XML, or SVG)

From what I can tell, these roughly correspond to React/Redux concepts thusly:

  • Elm's Model layer is equivalent to Redux's store
  • Elm's Update layer is equivalent to Redux's actions
  • Elm's View layer is equivalent to React itself

These analogies are made even more convincing when you consider the fact every value in Elm is immutable, just like Redux when used with Immutable.js, and that the Elm Architecture makes use of the one-way data flow paradigm made famous by Facebook's Flux.

Responding to user input

Okay, so we've produced a Hello World example and then rendered some slightly more complex markup. That's fine, but how does Elm deal with user input? Let's try creating an example where clicking a button renders the text "Hello Elm" below the button.

According to Lucas Reis's blog, Elm supplies a function Html.App.program which automatically routes an application for the Elm Architecture:

Elm apps use a centralized state pattern, which I've written about in this blog. It's a simple "loop" described as such:

Model > View > Update > Model > View > ...

First you describe a model of your app. It is the skeleton, the data you need to render the application.

The view is then a function of the model. It takes the data and renders it.

After rendering, the application "waits" for user interaction or any other event. When that happens, it triggers the update function. The update function is a function that receives the old model and data of the event, and returns a new model. This model is then rendered, and the loop continues.

Evidently, there's a simpler version of this function supplied with Elm called beginnerProgram. I couldn't find a decent explanation anywhere for what this function does that the regular program doesn't (or vice versa). If you know, please leave a comment!

Here's the full text of the user input example I just created:

import Html exposing (Html, button, div, text, p)
import Html.Events exposing (onClick)

type alias Model =
    String

model : Model
model = ""

type Msg = ShowGreeting

update : Msg -> Model -> Model
update msg model =
    case msg of
        ShowGreeting ->
            "Hello Elm"

view : Model -> Html Msg
view model =
    div [ ]
        [ button
            [ onClick ShowGreeting ]
            [ text "Click Me" ]
        , p [ ] [ text model ]
        ]

main =
    Html.beginnerProgram
        { model = model
        , view = view
        , update = update
        }

Let's walk through this line by line together.

First, we import some HTML functions we'll use to render our markup and listen to the button for clicks:

import Html exposing (Html, button, div, text, p)
import Html.Events exposing (onClick)

Then we'll create a new type called Model which is an alias for a string:

type alias Model =
    String

Next, we'll create an instance of the Model type called model and initialize it to an empty string literal:

model : Model
model = ""

Then, we'll set up our update function. This confused me at first, so maybe my explanation will help you if you come from the Redux universe.

The update function in Elm works essentially like reducers in Redux. It takes a message (an action in Redux-speak) and the model (the state in Redux-speak) and returns a newly mutated model.

Except Elm is much more suited to this paradigm for the following reasons:

  1. Elm's union types make the usage of symbolic enumerations like user actions checkable at compile time instead of relying on runtime checks.
  2. Because Elm data is always immutable, state reduction doesn't require clunky external libraries like Immutable.js.

So our update function takes a msg (in this case, only the value ShowGreeting), and returns a new model state based on whatever msg it received:

type Msg = ShowGreeting

update : Msg -> Model -> Model
update msg model =
    case msg of
        ShowGreeting ->
            "Hello Elm"

Okay, now that we've defined how our model will change in response to user actions, let's define the view. Again, Elm comes to the rescue by allowing us to pass the model directly into the view function. No complex binding a la Redux containers!

view : Model -> Html Msg
view model =
    div [ ]
        [ button
            [ onClick ShowGreeting ]
            [ text "Click Me" ]
        , p [ ] [ text model ]
        ]

Notice how we're passing model to the text function inside the p tag. When we boot the application, the model's value will be an empty string, but as soon as we click the button, we fire the ShowGreeting message and the model changes to the string "Hello Elm".

Finally, we glue everything together via the beginnerProgram function:

main =
    Html.beginnerProgram
        { model = model
        , view = view
        , update = update
        }

My impressions

All in all, I was pretty impressed with Elm after playing with it for an hour or so. While it's clear the framework has a ways to go in terms of documentation and external library support, its philosophy removes a lot of the boilerplate that plagues modern JavaScript tooling. In addition, it takes concepts like immutability, functional programming, one-way data flow, and type safety which are must-haves in today's JavaScript development world, and makes them first-class members of the language.

Would I use Elm in a production project yet? I'm not sure if I'd subject my clients' businesses to that risk just yet. While it's impressive, the idea of relying on a small community for support on complex topics like JavaScript interoperability would make me a bit cautious. But I'll definitely consider Elm the next time I build a personal project.

How to befriend uncertainty April 25, 2017

Yesterday I found out my biggest client will no longer need my services in a couple months.

The last 24 hours have been a bit of a whirlwind of emotions. Part of me is excited. Another part is scared. I have other sources of income and a savings. But I'm still unsure of what I'll be doing in three months' time.

The funny thing is, I've wanted to go off on my own for some time now. I've been frustrated with the monotony of working on one project for years at a time. But now that I'm faced with it, I'm scared and uncomfortable. Why is it that we're so comfortable being unhappy?

Most of us are constantly chasing certainty. We work jobs we may not enjoy so we're certain we'll have food to eat when we get home. We buy health insurance so we're certain we'll be cared for when we're ill. And we invest for the future so we're certain we won't be out in the cold during old age.

But what is certainty, really? You can't see it. You can't reach out and touch it. Maintaining certainty about tomorrow feels good today, but tomorrow it's gone, leaving us hoping for certainty the next day.

And in the face of complete certainty, we're miserable. We become bored. To know that each day will be the same as the last is the definition of a boring existence.

But there's another way. Instead of seeking certainty day to day, we can befriend uncertainty. We can invite it to sit in our corner with us and share its perspective. After all, just think of the things that wouldn't be possible if we had perfect certainty:

Adventure

When we embark on an adventure—whether it's down the street to the cafe to write or to another country for a month of backpacking—the allure of doing it is that we don't know exactly what will happen. We might have a plan or itinerary, but our reason for adventuring is to see the unseen and to take a chance on something new.

Framing each uncertain moment as an adventure can help to ease the struggle of seeking certainty in an uncertain situation. And too, it can help grant meaning to ordinary everyday activities which may have seemed monotonous when framed as such.

Love

In love, we're entering into the most profound uncertainty. We commit our hearts and minds and energy to one person. Expecting nothing in return and knowing it will end in heartbreak or death, we proceed to give ourselves to another person.

No one ever entered into a romantic relationship knowing how it would turn out.

Passion

I'm not sure there was ever once a passionate artist, businessperson, politician, or writer who knew for certain at the start of their endeavor that their efforts would be meaningful and worthwhile in the end.

The reason people do great things is because of this uncertainty—not in spite of it. We are drawn to the idea that we might achieve what others think to be impossible.

The vicious circle April 24, 2017

In modern life we're caught in a vicious circle.

We work long hours at jobs we don't really like because we believe it will result in a better future. Our days are spent in pursuit of a tomorrow that will be oh-so-bright if we just keep our heads down and keep working for it. But then, when tomorrow finally comes, we're befuddled at how inadequate the present suddenly feels. And so we seek yet again for a brighter future, working more and more, until the day we die.

And most of the time, the bright future we're after isn't one where our basic needs are met so that we may pursue some higher artistic calling. No, our hypothetical future has shiny cars and gadgets and a big house and daycare and expensive cocktails and luxurious clothing. It's one where we don't have to deal with life's tedium and we can come and go as we please. It's a future where all our problems are solved and we can finally start living.

It's a future that will never come. It will never come because it cannot exist.

It cannot exist because even when all of life's tedium has been eradicated, more tedium emerges: the tedium of boredom.

Left with nothing to push up against, we create new problems. We continue the habit of looking outward for our gratification. And so, we suffer once more.

It's tempting, but futile to seek a hypothetical future with no problems. Because the nature of a life without problems is problematic itself.

Instead, we might strive to accept life's problems without judgment. To take each passing moment as a blessing, because this moment is the only thing we really have anyway.

The minimalist day planner April 20, 2017

My Minimalist Day Planner

A few months ago, my partner introduced me to the Day Designer. I used their print-at-home version for a few days in an attempt to add some sanity to my busy days.

But I was finding they weren't quite what I was looking for. I wanted my day planner to help codify two habits into my day:

  • Gratitude journaling: The Five Minute Journal from Intelligent Change is all about enriching your day-to-day experience by prompting you to think of what you're grateful for each day. I really appreciated this idea, but wanted to integrate it into my daily planning routine so it would be more or less automatic. So I decided to ask myself each day three things I'm grateful for.

  • Pomodoro technique: I use the Pomodoro Technique religiously when I'm working. Not only does it improve my focus by encouraging me to stay on task for short bursts, but it also helps me frame my tasks into more tangible 25-minute blocks as opposed to the vague notion of minutes and hours. To help track my time, I added two tomato-shaped checkboxes for each hour of my day planner to track 2 25-minute pomodoros and 2 5-minute breaks.

My Minimalist Day Planner

Download the Minimalist Day Planner (PDF)

The freedom of less April 18, 2017

Less

For the past two years I've been devoted to the pursuit of less and fewer: Less debt. Less stuff. Fewer commitments. Less driving. Fewer expenses. Less social media. Less drinking.

And suddenly I'm finding myself with more: More money. More attention. More time. More meaning. More fitness. More freedom.

It hasn't been an easy journey, but it has been a simple one. There are just two principles that have driven me here:

  • Spend less than you earn.
  • Strive to be happy with what you have.

Debt

Rewind back to late 2014. I had just moved to Seattle with my girlfriend at the time and was living the yuppie dream. We had an apartment with a sweet view and we went out drinking a few nights each week. I didn't spend beyond my means, but I generally spent the money I earned each month. I'd buy new computer equipment, recording equipment, or clothes. And what I didn't spend went toward servicing my student loans. Our monthly rent was $2,275/mo, which was pretty standard for our neighborhood.

Then something hit me. I realized I'd been holding my student debt for almost a decade. There was haunting symbolism in that. Each month I made a $400 payment to Sallie Mae. It felt normal—as if that was the way things were and that I'd be paying the loans for another decade. My balance at the time was somewhere around $30,000. The amount was a far cry from the student loan horror stories you hear from graduates nowadays, but it still made me nauseous to think about paying them off.

I decided enough was enough. It was time to rid myself of debt once and for all. I tallied my monthly expenses. I began eliminating all non-essential spending. I told my friends I could only go out one night per week. I took on more client work to help pay down the balance. And before long I paid them down.

Freedom.

It's hard to describe the feeling of being free of the shackles of debt after having known it for so long. I felt like I could breathe again. I knew the money I earned was now mine to keep. I knew I was in control of my time for the first time since before college.

Or was I?

Lifestyle

Despite my temporary hustle to pay down my debt, I realized my living expenses were out of control. My girlfriend at the time and I parted ways, and I was stuck servicing rent at our apartment. I did the math, and realized that if I suddenly lost my income I could only sustain my lifestyle for maybe two months.

For the remainder of my lease, I labored to reduce my expenses where I could. I dined out less. I found a new affinity for lentils. And I took on more client work so I could save and invest at least a little bit.

And then I met my current partner. She and I moved into an apartment in Green Lake, which is a much less expensive Seattle neighborhood than Capitol Hill. My rent dropped from $2,275/month to just $1,067, with my partner covering part of the $1,600/month total. That meant I just reduced my rent by 53% overnight. Woo-hoo!

But you get what you pay for. In Seattle, a 2-bedroom apartment for $1,600 is a steal. But it was right next to a busy street and it sounded like there was a highway in our living room. Our bedroom window faced an alleyway. We didn't have the luxury of laundry in our unit. And the appliances, while working, were outdated. The refrigerator smelled like rotting milk. The apartment had terrible ventilation problems.

All of this would have been tolerable if we had a compelling reason to stay in Seattle. If either of us had a lucrative or meaningful career that was reliant on our physical presence in Seattle, it would have been worth it to tolerate the cost. But I work from home. At the time, my partner was working a part-time retail job. What were we paying for, exactly?

We both love attending cultural events that a big city like Seattle hosts. But we're also both generally homebodies. I can't speak for my partner, but as I've gotten older I've found myself valuing a nice home. Not a big home or a flashy home or anything like that. I value a home that feels like home. A place that's comfortable. A sanctuary. And our place in Seattle was anything but that.

Then we took a trip to Eugene, Oregon. And it was right then I knew I'd found my new home. I just had to convince my partner it was the right move. After a few long discussions, we decided upon a cozy house in the hills. Rents in Eugene make me feel rich! Here's the cost breakdown for my last three apartments. Notice the precipitous drop in price per square foot:

Location Monthly Rent My Share $/sqft
Capitol Hill, Seattle $2,275 $2,275 $3.79
Green Lake, Seattle $1,600 $1,067 $1.60
Eugene $1,395 $930.00 $1.27

My partner and I cook almost every day and eat most of our meals in. We have a morning coffee and breakfast ritual. We own only one small car.

Because of all this, my mandatory monthly spend is only around $2,000. That covers rent, food, and utilities.

For every $2,000 I have in the bank, I can sustain myself comfortably for a month without working.

Work

I'm not sure there was a specific moment when it happened, but it changed my relationship with work forever.

It was the moment when I realized the psychological power of capital. The power of money is hardly in the material things it can buy. No, the true power of money is in the way knowing you have it changes your behavior.

Because I know I'll be able to pay my bills for the foreseeable future without working, the way I treat my client work has changed dramatically.

No longer am I desperate to please clients in the short-term. I remember bending over backwards, compromising my values and my health in order to make sure I'd continue to get paid.

Now instead of engaging with clients purely to get paid, I do it to serve them and their interests. Conveniently, money tends to be a byproduct of this service.

The beauty in having capital is that you're free to walk away from toxic client relationships. And you're in a position to vet new relationships with more scrutiny before it's too late and you've made promises you cannot keep.

The irony too, is that by maintaining a low-expense lifestyle I'm able to charge more for my services because I know I don't need the work. This doesn't mean I don't respect my clients' needs and constraints. In fact, minimalism has led me to respect them more because when I work with clients, I treat them like people instead of paychecks.

My desire to make it in my career has subsided as a result. If you're ambitious you probably know what I mean by wanting to make it. It's that sense that if only you had a few more markers of success, you'd finally be happy. You know what? I've acquired a few of those markers over the past decade and none of them made me happy. I've had luxury apartments and fancy dinners and $15 cocktails. I've been lured by big salaries and bonuses. None of it made me happy. Truth is, most of the things that make me happy don't require money. So why do we keep chasing more of it?

Happiness

So what do I live for now?

I live for meaning. For cups of coffee with my partner in the morning. For quiet bicycle rides. For losing myself in complex programming problems. For being a disciplined learner. For the pursuit of art. For excellence.

I live to be curious. To be valuable. To serve others. To contribute. To live each day like it's my last, but knowing what that means for me.

I live to be free. To recognize that money is important not because of the stuff it can buy but because of the freedom it can buy. The freedom to breathe. The freedom to spend an afternoon writing an article for my blog instead of working to pay off a BMW.

To me, happiness is knowing if I died tomorrow I'd die with dignity. I'd die knowing that up until this moment I spent my days in accordance with my values.

A luxurious lifestyle would be nice, but it's not necessary for a life well lived.