Source: Amalgamated from Jim Browne Chevy and Bob 'n' Bee. Basically, I took a way nicer, newer version of my truck and Photoshopped someone else's mail icon onto it.

I've gotten into this wonderful rhythm of publishing posts that are tragically untimely. My Spring Cleaning post was five days too late, I'd had the insulation and skylight for weeks before I'd recounted the tale, and I'd successfully picked up and put down my weight goals way before I picked up the pen and put down a post. So it's only fitting that I'm just getting around to talking about a feature I added to the site over eight months ago.

Every so often, I get bored and fidgety and change things around on the site. Sometimes I'll tweak the savings calculation, sometimes I'll move around items on the mobile layout, and yet other times I'll sit down with a coffee and some music and plop a few new features into existence. The title and picture probably provide plenty perspective, but this time around, I added email subscriptions. I noted in this post (a relative eternity ago) that I was thinking about adding them because, in theory, it's pretty simple. Someone gives me their email address and clicks a button, then they get an email every time I write a new post. Unfortunately, like pretty much every problem I've sized up thus far, it wasn't nearly as simple as I was expecting, and I definitely hit a few snags along the way.

Forewarning: this is another post for my fellow nerds. For anyone else, it's a valid substitute for a tranquilizer.

The Nitty Grity Technical Details

Depending on how closely you've been following my various love affairs with trendy web technologies, you may or may not know that my site runs on Google's App Engine platform. Knowing very little about how email works, it logically seemed like the App Engine Mail API documentation could maybe potentially be a good place to start. The more I read though, the more foreign concepts I wandered across. What is DKIM? How does SPF work? Do I need an alias? Whose SMTP server am I using? I started to wonder, how bad do I really want email subscriptions anyway? But I, with ample hesitation, plodded down the path anyway.

DKIM

The ideas behind DKIM are pretty similar to the ones that power TLS and consequently all the important things that happen on the Internet. My understanding of DKIM is that, like, you have a DNS record saying "Yo, this is my public key, use it if you want to see if an email from me is legit" and anyone can see that when they look up records for your domain name (FromInsideTheBox.com in my case). Then, every time I send a message [at] frominsidethebox [dot] com, AppEngine adds a special magic signature in the header that's signed with the corresponding private key, and the recipient can use the public key to verify that the signature makes sense and thus the email must have really been sent by me. Cool stuff.

SPF

Turns out it's not just for sunscreen anymore. SPF works kind of like DKIM, minus all of the fancy encryption stuff. SPF works by adding another DNS record, but this one says "Bro, if you get a message from my buddy App Engine, you can trust it, he's chill." This way, you can send mail from someone else's mail server and still show that it can be trusted.

At this point, you may be wondering a few things, like Why are all of these things necessary? and Why is Brandon personifying computing protocols and making them sound like frat bros? To answer the former question (and ignore the latter), it's because the Internet is a giant pile of dusty, wobbling, unstable, duct-taped together systems stacked on top of each other like some shoddy version of digital Jenga. The underlying protocol for sending emails reared its head in 1982, and offered literally no way to authenticate where the messages are coming from. It makes sense, it evolved at a time when the "Internet" consisted entirely of academics and the military, so you could just trust the network. It wasn't like some drunk researcher was going to send prank emails, like:

From: Ronald Reagan <rreagan@whitehouse.gov>
To: Alexander Haig <ahaig@whitehouse.gov>
Subject: fire the nukes
Date: April 1, 1985

Ay Hags,

Launch one of those suckers at the moon, I wanna make it rain nacho cheese.

LOL,
Ya boy El Prezzo

...so yeah. That'd definitely be a problem today, thus DKIM and SPF.

CAN SPAM

There was one other acronym I had forgotten to take into consideration: CAN SPAM. CAN SPAM is a US law signed in 2003. It's also the reason all of the (legitimate) emails you get have an "Unsubscribe" link. Not wanting to be at the mercy of the US Government (well, any more than my taxes already cause me to be), I figured it prudent to add one of these "Unsubscribe" links myself. That takes work and effort though, now we're not just blindly (and indefinitely) sending out emails to anyone who sends me an address. Instead, now we have to maintain an active database, and remove people when they ask.

I'm making this sound harder and more complicated than it actually was. All I had to do was add a few web endpoints, and add a new type to my Datastore. The end code (removing the extra boring parts) looked something like:

// Email actions
http.HandleFunc("/subscribe", confirmationHandler)
http.HandleFunc("/confirm", subscribeHandler)
http.HandleFunc("/unsubscribe", unsubscribeHandler)

// When someone submits their email
func confirmationHandler(w http.ResponseWriter, r *http.Request) {
  address := strings.TrimSpace(r.PostFormValue("email"))

  // Do a few basic validations

  exists, err := db.EMailExists(address)
  if err != nil || exists{
    // Return an error
  }

  id, err := db.CreateEMail(address)
  if err != nil {
    // Return a different error
  }

  data := struct {
    ID int64
  }{
    id,
  }
  var buf bytes.Buffer
  if err := emailTemplate.ExecuteTemplate(&buf, "confirm.html", data); err != nil {
    // Yet another error
  }
// Send email with data in buffer, that basically says "Click here to subscribe"
}

// Someone clicking the confirm link I sent them
func subscribeHandler(w http.ResponseWriter, r *http.Request) {
  id, err := strconv.ParseInt(r.FormValue("key"), 10, 64)
  if err != nil {
    // Uh oh, looks like nobody is subscribing today
  }

  if err := db.ConfirmEMail(id); err != nil {
    // Experiencing some technical difficulties
  }

  render(w, BasicTemplate{
    Description: "Your subscription has been added.",
    Header:      "You're all set!",
    Message:     "Good to go.",
    Type:        "success",
  })
}

// Someone doesn't want my ramblings in their inbox anymore
func unsubscribeHandler(w http.ResponseWriter, r *http.Request) {
  id, err := strconv.ParseInt(r.FormValue("key"), 10, 64)
  if err != nil {
    // Uh oh, they aren't going to like this
  }

  if err := db.DeleteEMail(id); err != nil {
    // Looks like they're stuck with me until I learn how to program better
  }

 render(w, BasicTemplate{
    Description: "Your subscription has been removed.",
    Header:      "You're all set!",
    Message:     "Good to go.",
    Type:        "success",
  })
}

// The struct used to hold subscriptions
type Subscription struct {
  Address   string
  Confirmed bool
  Added     time.Time
  ID        int64 `datastore:"-"`
}

Woah Brandon, when did you add highlighted code snippets to the site?!

I'm glad you noticed, hypothetical reader! I added it a few months ago, but this is the first post to actually utilize it. It uses highlight.js behind the scenes, and took like five lines of code to set up. But I'm getting sidetracked here. As for the code above, that's really all I needed to satisfy the CAN SPAM act requirements, all in all not too bad. Granted, that doesn't include the code for actually sending emails, but we're getting there.

Actually Sending Mail

Okay, so at this point in the narrative, we've set up DKIM and SPF to work with App Engine, and we've got a storage system set up for subscriptions. According to the documentation, all we need to do now is add:

subs, err := db.Subscriptions(ctx)
if err != nil {
  // Looks like no emails are going out today
}

for _, sub := range subs {
  data := struct {
    ID int64
  }{
    sub.ID,
  }
  var buf bytes.Buffer
  if err := emailTemplate.ExecuteTemplate(&buf, "new_post.html", data); err != nil {
    // Guess we're not sending this one
  }
  mail.Send(ctx, &mail.Message{
    Sender: "post-notifier@frominsidethebox.com",
    To: sub.Address,
    Subject: "New Post on From Inside The Box: " + post.Title,
    Body: buf.String(),
  })
}

Hook that up to some authenticated web endpoint, pass in the post ID as a parameter, and boom, you've got a working subscription system. Shockingly enough, that's pretty much all it took to get working. Not only did it work, it worked on (nearly) the first try, no less. In fact, it was so easy that I was sure something would break in the not-too-distant future, as my experience with trucks and things and life in general has shown me to be universally true.

Mistake #1: Not Reading the Manual

A bit of background: I have a special button I push when I want to send out emails to subscribers. It's separate from the special button for publishing posts, because in the event that I accidentally publish something too early, I'd rather not spam everyone with my half-baked ramblings. And if anything goes wrong in the email-sending process after I push my special button, the server will return a message. For a month or two, this process worked well. Things were going along swimmingly, and then one time I pushed the special email button, and things stopped swimming. I got an error that of my 106 subscription emails, 6 of them didn't send.

Huh, that's a bit suspicious, exactly 100 emails sent successfully...

After the slightest bit of sleuthing, I found out that App Engine has some limits and quotas, a particualrly relevant one being that I can't send more than 100 emails a day. This works fine when ≤100 people are subscribed, but not so well when 106 people are subscribed. Sorry to the 6 people who didn't receive an email when I put up this post, unfortunately my logging was also bad enough that I didn't know which six subscribers didn't get a letter, so the best thing I could do was fix the problem for the future. Enter stage right, SendGrid.

SendGrid is a mail-delivery service. They do lots of other things too, but those aren't quite as relevant or interesting to me. All I care about was that they'd happily send way more than 100 emails. So I ripped out the App Engine mailing code, and pulled in SendGrid's Go client library. It took about an hour to throw together, and the only real difference is that I have to pass the SendGrid API key, which I embed directly in my code because I have no sense for design or regard for security.*

Mistake #2: Just Generally Being Incompetent

If you look at the mail snippet above, you might notice one teensy little problem, mainly that I'm just iterating over all the subscriptions and making a blocking call to send a message. This is fine when you only have a few users, but it scales linearly with the number of subscriptions. Not only that, but most of the time spent sending each message is waiting for the request to trot off to The Internet At Large™ and mosey on back. This is a shame, because Go has all these fancy concurrency primitives that I'm not taking advantage of, and would be particularly well-suited to this embarrassingly parallel problem. Using goroutines, we can fire off all the requests, which will then do all that waiting in the background. Similar to my last performance post, it means we can send all of the emails in (almost, kinda sort if you squint a little bit) constant time, instead of watching it get slower as I get more subscribers.

Sounds great right? Well it would be if I was a less shoddy programmer. Concurrency can be tricky to get right (even in a language built for it) if you aren't being careful, and I wasn't thinking. Here's the problem: each email is slightly different because the unsubscribe link has a unique ID for each subscriber, so I can't fire off the same email for everyone. See if you can spot where I went wrong in this first implementation:

var buf bytes.Buffer
data := struct {
  Unsub  int64
  PostID int64
  Desc   string
}{
  0,
  post.ID,
  post.Desc(),
}

var wg sync.WaitGroup
// Iterate over list of subscribers
for _, email := range emails {
  wg.Add(1)
  go func(email *EMail) {
    defer wg.Done()
    data.Unsub = email.ID
    if err := emailTemplate.ExecuteTemplate(&buf, "new_post.html", data); err != nil {
      // Always check your errors kids
    }

    message := sendgrid.NewMail()
    // Build the rest of the message here

    if err := sg.Send(message); err != nil {
      // Log the errors and whatnot
    }

    buf.Reset()
  }(email)
}
// Wait for all the emails to be sent
wg.Wait()

...did you see the gorilla mistake? I thought I was being clever by using one buffer for the emails to save memory, but I was really setting myself up for an awful and awfully obvious race condition by writing to the same buffer from 100 different goroutines with no synchronization whatsoever. The end result could have been a number of problems of varying unpleasantness, but what happened, in reality, was that every person got an email containing the emails for EVERYONE concatenated together. Aside from just looking silly, it means that anyone who got one of those emails could have (and still can) click each and every one of the unsubscribe links in the email and unsubscribe >100 people from my mailing list. I greatly appreciate everyone continuing to not do that, but I regularly back up the mailing list just in case.

The first thing I did to fix this was to give each goroutine its own buffer. Then, I wrote some beefy unit and integration tests for the mailing system. Once I was satisfied with the passing tests, I ripped out all the mailing code, and replaced it with a pool of mailer threads that get fed subscriber IDs via a channel. That way, I only need as many buffers as workers in the pool. The first few attempts caused the tests to fail for one reason or another (malformed message bodies, deadlocks, etc), but I eventually got it working. I'm going to skip including that code, because this post is already probably too long, but you get the idea.

Last Thing: TLS

All this talk of email is great, but there was one oversight on my part that I'd been avoiding because it was convenient to do so. My site was being served over HTTP, not HTTPS, so if you clicked the "Subscribe" button, it'd be sending your email address over the open Internet. Not a huge deal, but it's 2016 and I can do better than that. So with that in mind (and a bit of prodding from a friend), I started looking up the process for getting TLS on a custom domain with App Engine. I also wasn't ecstatic about the idea of paying a signing authority for a certificate, so I looked into Let's Encrypt. I ended up finding a few great guides on how to set it all up, then I just had to switch my image serving over to HTTPS, and add a "secure: true" in my App Engine app.yaml configuration so that it would always redirect to the HTTPS version of the site and that was it! I don't know about you, but the green lock in the address bar gives me a warm, fuzzy feeling.

*I'm joking, of course. What kind of idiot would mix credentials with code? Kidding again, I'm that kind of idiot and that's exactly what I do, but I swear I have every intention of having a separate Datastore table to store all of the private keys I need for the application. In the mean time, my source code is stored in a private Github repository, only accessible via two-factor or private key authentication. Granted, I'm still putting quite a bit of faith in Github here, but the stakes aren't all that high for this particular case.


Source: Calendar from ClipArtix, truck still from Clker. Slapping them together done by me, a weak first attempt at using Adobe Illustrator.

Staying true to my well-documented inability to write timely posts, here's a post that I probably should have finished three months ago.

I wasn't always the truck-faring degenerate that I am now. Reading some of my earlier posts, I can vividly remember a (roughly four percent) younger, more hesitant Brandon, sitting in an airport terminal, running through the plan over and over in his head, making sure he didn't miss any important details. I'd picked out a class of vehicle, I'd picked out a place to get my private mailbox through, I'd scoped out parking locations. It was all there, I just had to go out and do it. I had some ideas about what truck-life would be like, but no experience to say whether or not my trepidation was justified.

It's hard to believe, at least for me, but I recently celebrated my one-year truckiversary. One whole year. Inside the box. Just a man and his moving truck. And somehow (even in spite of my last post), I managed to survive it without being arrested, abducted, robbed, murdered, or otherwise maimed in some bizarre truck-related incident. Not to say that the intervening year has been a quiet one. On the contrary, it's been pretty eventful. Between surviving my first night, a host of Home Improvement projects, planning the future, my eventual eviction, and all the pseudo-philosophizing along the way, I've been busy.

To celebrate the milestone, I thought it'd be interesting to go back to one of my first posts where I weighed out the pros and cons of adopting my truckly ways, and see how right (or wrong) I was. For your convenience, my dearest reader, I'll quote each pro/con from the original post here.

Pros

  • Money Savings. Even sharing bedrooms, rent in the Bay area is going to cost at least $1,000 a month. That's a bare minimum, it doesn't include utilities or anything else. It's $12,000+ a year that I'm practically just burning. No return, no equity, just gone.

This one definitely held up. Whether it was paying off my student loans or utilizing tax-advantaged accounts, the truck definitely gave me some financial flexibility. What I didn't realize at the time was the different ways those savings would compound. Not only do I get to invest all of that redirected rent money, but I get to invest all the money I'm not spending on furniture, and utilities, and buying food just so my refrigerator doesn't get lonely. Sure, now I spend money on weird truck-improvement projects, but those are comparatively cheap and I usually end up learning something too.

  • Life Experience. I've never truly stepped outside my comfort zone. After living in California for a summer, I realized just how little of the world I've actually seen. If I do plan on travelling the world, I'll need to be comfortable with unconventional living situations, and this is certainly a good place to start. Plus, there is never going to be a better time in my life for me to try this. I'm young, flexible, and I don't have to worry about this decision affecting anyone else in my life.

This one was also spot on. Up until last year, I felt like my life had been pretty tame. I felt like I was following the prescribed course, the one laid out in front of me. You know the one: work hard in high school to get into a good college. Work hard in college to get a good job. Work hard at your job so you can fill your suburban home with stuff you don't need to impress people who don't care. Retire, then figure out what you want to do. I know, I've said all this before. It's true though. And it's also true, I was passively barreling down that exact path, right up to the "fill your suburban home with stuff" part. That's where it kinda lost its appeal for me.

I'm glad to say that the truck has definitely broadened my horizons. I can think of a handful of times where my justification for doing something crazy was, "Hell, I already live in a truck, why not?" Now that my comfort zone can be summed up as "anything that won't definitely kill me", I'm much more open to experiencing everything the world has to offer.

  • Transportation and Proximity. Having a car is very much a necessity, and by living in it on campus, I can cut my commute down to a few seconds instead of hours, which means I can spend my time more productively. Plus, I hate traffic, and my company's 25,000+ employees ensure that there is a whole lot of it in the morning and evening hours.

This actually isn't as big of a deal as a I thought it would be. Since I wake up so early, I wouldn't really deal with traffic even if I was living in an apartment a town or two away. That said, I'd like to think I'm saving resources by not having heating/cooling/electricity and minimizing my driving. I'm no Captain Planet, but it doesn't hurt to do your part.

  • Health Benefits. If I'm living in a van, I have no choice but to go to the gym on campus to shower, so living in a van provides me with a strict daily regimen. In a similar vein, since I'm eating all my meals at work, it means my diet will be organized into three meals a day during the week, without any late-night snacking.

This feels about right, though I might have been a little overly optimistic. I usually exercise 6-7 days a week, but my "strict daily regimen" isn't quite the army drill I made it out to be. I definitely snack a bit at work. I go out to the bar with my friends on occasion, and usually end up dragging myself to the gym an hour behind schedule the next day.

I guess there is a small sorta health-related downside I didn't consider though. I don't get sick very often, but when I do, it's tempting to blame the truck. If I have a sore throat, I'll catch myself thinking "maybe there isn't enough ventilation in the truck", or if I have a runny nose it's something like "maybe the truck is too dusty". I have no way to prove whether or not these things are true, but the fact of the matter is I still get sick less frequently than I did when I lived in an apartment, so even if the truck is occasionally striking down my immune system, it's not often enough to be an issue.

Cons

  • Social Suicide. I will most certainly be "That Guy". No amount of planning or forethought excuses the fact that I'm the psychopath living in a van in the parking lot. People will eventually find out, and it will affect my social life.

This one goes both ways. I was right, people definitely found out. But I was also wrong, too, because I thought it would affect my social life for the worse. Instead, I've been meeting up with like-minded mobile home enthusiasts and I'm more likely to take impromptu trips with friends. Speaking of friends though, mine have no problem filling lulls in conversation by talking about how I'm "the truck guy". And the response I get, without fail, is always, "Oh you're that guy?!"

  • Inconvenience. Living in a car is not convenient. There's no bathroom, shower, or refrigerator in a reasonable distance.

This one ended up being a bit overblown. I don't know if I have superhuman bladder muscles or what, but I've never found myself running to a bathroom at two in the morning or anything ridiculous like that. And as a consequence of my routine, I don't end up missing the lack of shower either, gyms have more than handled that one for me. As for refrigerators, the only reason I could possibly want one is to bring home leftovers after going out for dinner, but I'm a human garbage disposal and my plate is always licked spotless by the end of a meal, so that's a moot point.

  • Stress and Anxiety. The whole process is supremely stressful. Picking out a van, buying it, converting my license, getting insurance, all without a car and all before I've even started working and making money is a lot to deal with. Not to mention the illegality of most of it. Then once all of those things are out of the way, I'm still pretty anxious about being caught, and how I'm going to sneak into and out of my van.

The initial process was stressful, and reading this over I can feel my blood pressure rising at the thought of those early days. I don't worry about being caught anymore. For one, I found out that it is actually legal to sleep in your car where I live, as long as the car is legally parked. For two, I've been doing it so long that it doesn't really phase me anymore, which I talked about a bit in this post. Hell, just last weekend I hopped out of the back of the truck in the middle of the night because there were a bunch of kids sitting on my tailgate. They were talking about tagging up the side of my home and I wanted to let them know that I'm the only one who does any truck decorating. The look on their faces was totally priceless.

  • Upfront Expenses. At least with renting an apartment, I'd be paying gradually, without too much upfront cost. But between buying the car, buying insurance, fixing the car, setting it up, and the taxes and fees on top of all those things, it's a pretty big financial burden for someone who hasn't even started working yet.

It's true, the cost of the truck would have cut my student loans in half if I had spent the money on that instead. However, it's more likely I'd have been using at least a few thousand dollars to pay for a security deposit and a few months rent when trying to land an apartment. At the time, it seemed like I was signing my life away for this box truck, but after a few paychecks it didn't matter anymore.

  • Good luck getting laid. Interestingly enough, it was my mom who asked me about this one. I can only imagine that it's going to be next to impossible to get laid when I'm the van guy. Sure, I can get a hotel for the night, but it's still strange and I still have a bit of explaining and convincing to do. Since I'm not nearly smooth enough for that, I've accepted the fact that I'm going to be celibate for the next who knows how long.

People have always been uncomfortably curious about this one, so I'm sure my continued silence will be disappointing to some. But as it is, my life is not an episode of Keeping Up with the Kardashians. And I can pretty confidently say that I don't want it to become one, either.

I've said before (and will say again now): I'm consistently surprised at how receptive people are to the lifestyle I've chosen. At the very least, very few people treat me like the trailer park-reject I thought I was going to be seen as. Because of how expensive it is to live out here, my housing situation comes up more often than not in casual conversation, even without any coaxing from me. It normally leads to some genuinely interesting conversations around goals and priorities.

Summing it up

Overall, I like to think the truck has changed me for the better. I'm certainly more cognizant of my tendencies to judge, of my work-life balance, and of what simplicity means to me. And looking back over my list, it's good to see I was more wrong about the "Cons" than anything else. I've spent a lot of time thinking about what I would change if I did it all again, and I usually don't come up with much. In fact, if I could go back in time and give my younger self advice, right when his plane had just landed in California, I'd really only have one thing to say: try a smaller truck.


Before I say anything else, let me be clear: this isn't me making up some spooky story, this actually happened to me this morning, Monday August 1st, at 6 am.

I had a series of strange dreams about spies and nuclear war last night. Pretty dramatic, but I have weird dreams all the time. The problem is that things got weirder after I woke up. First, I noticed a bitter taste in my mouth that I have no explanation for. I ate nothing strange last night and washed up using the same products I've been using for as long as I care to remember. That's not a big deal though. What is a big deal is this:

In case it's hard to tell, that's a muddied footprint on my sunroof, which I had installed a few months ago. Half-awake, I wanted to think it was literally anything else. Maybe a bird had dropped a fish or something and it had left that mark. Maybe it was just the imprint of a weird leaf. Highly unlikely (bordering on nonsensical), but I really desperately wanted to believe it wasn't a footprint. Unfortunately, I walked outside and proceeded to find this:


I took pictures like I was cataloging a damned crime scene, because I practically was.

Unfortunately, that confirms my fears pretty concretely. Someone left a trail of hand and footprints as they climbed their way onto the roof of the truck while I was sleeping last night. It's also pretty obvious that I desperately need to wash the truck, but I'm glad I didn't in this one specific instance, because if the truck was clean, the footprints wouldn't have been so visible.

Searching For Answers

I don't remember much out of the ordinary from last night. Sounds from cars leaving a nearby concert, maybe some kids hanging around and talking. The strangest thing I heard was a cop talking to someone and asking what they were doing. I don't know if the person was in a car or not, but the cop asked them for their license. They were slow to respond and seemed confused. I don't remember much else because I was half asleep, but I've never heard of cops hanging around this area, so it's pretty curious that they were there in the first place. While I was taking the above pictures, I noticed a man standing next to his car maybe 50 feet away. I asked him if he saw anything, but he didn't speak much English. I showed him the footprints on the truck and motioned to my feet to try to convey what had happened. He showed me the bottom of his shoes (which had a totally different pattern than the marks on the truck) and said he didn't know anything. Oh, and I checked all of my own shoes to see if the pattern matched, in case I had been sleep-walking or something (couldn't rule anything out). As expected, no match there either.

And that's all I have, leaving me with far more questions than answers. First and foremost:

How the hell did I not wake up? I didn't have ear plugs in and I'm a pretty light sleeper. Usually a person talking or a gust of wind is enough to stir me into something nearing consciousness. The movement of someone jumping onto the truck and walking directly above me should have woken me up, and the truck must have groaned and creaked loudly when they got onto the roof, which isn't meant to support anything nearing the weight of a person.

Why did they leave a footprint on the sunroof too? They couldn't have possibly stood on it, it's slippery, slanted, and has small plastic pieces that would have broken trying to support their weight. That means (barring any better explanations that escape me) they pressed their foot against the sunroof just to leave the print. If I hadn't seen that one, it's unlikely I'd have found the other footprints on the hood and cab.

And what were they even doing up there? Were they watching me sleep? Were they looking for something? I don't even know what they would have seen looking down into the truck. I was sleeping directly under the sunroof and I get the heebie-jeebies thinking about waking up in the middle of the night to see someone looking down at me. I'm not even sure if they'd be able to see me, there's no light in the truck and very little coming in from outside, most of which they'd be blocking with their body, plus the sunroof has a pretty heavy tint on it. Unless they had a flashlight, I don't know if they'd have seen much. I couldn't get any pictures of the roof, because I was unwilling to climb up there myself, but I did pull myself up so I could peek onto the roof. I didn't see any footprints towards the back, so they didn't walk around once they were up there. Maybe it was just some bored kid with a short attention span trying to get a better vantage point. Maybe they were looking for something to steal, and were trying to "case" the truck. If they were, I have bad news for them: I don't really have anything of value in there. In fact, if I came back to the truck to find every single thing missing, it'd hardly change my plans for the day.

I feel like I'm in the world's worst rendition of Cinderella, where the glass slipper has been replaced with a muddy sneaker print, and my Cinderella is a creepy dude who watches people in the middle of the night.


Source: Great Lakes, my loan servicer. Paying off your student loans is apparently such a big deal these days that they literally fill the page with confetti when you manage it.

Student loan debt is, uh…a problem in the good ole US of A, to say the least. It has passed credit cards for the number two spot on the list of "biggest things holding American wallets hostage," behind only mortgages at this point. When millennials wake up in a cold sweat in the dead of night, filled with a deep, overwhelming, and existential sense of dread, it's probably because student loans are haunting their dreams. Okay, hopefully it's not that bad, but it's no wonder student loans get a bad rap, with millions of The Indebted™ buckling in for the long haul, getting ready to work and whittle at the loans for the next decade (or more).*

Looking back through my posts, it's clear I've been pretty active in trying to take my own personal student loan blackhole down a notch (or twenty thousand). Hell, it was one of my inspirations for trying to live more simply; I figured that the sooner I got this cap-and-gown-wearing monkey off my back, the sooner I'd have the financial flexibility to branch out and explore.

Personally, I think a cap-and-gown-wearing monkey is a great metaphor for student loan debt. It's also just adorable.

Indefinitely borrowed from this blog.


I'm happy to say that, as of June 7th, I've officially paid my student loans in full. What follows is my account of everything that made it possible.

My Story

I didn't grow up particularly wealthy. I didn't grow up particularly poor either. "Decidedly Middle Class" is what I'd call it, if you asked me. I'm fortunate enough to have two parents who love me dearly, even if they gave up on each other a long time ago. I never had a college fund, just some Bar Mitzvah money that disappeared with my parents' marriage and my childhood home. Never figured out what happened to the money, but I got this really great shirt when my Dad came back from Las Vegas.**

Anyway, when it came time to apply to colleges, my guidance councilors basically told me the sky was the limit. Accepting their advice with a little too much fresh-faced optimism, I applied to Caltech, Carnegie Mellon, Frank W. Olin, Harvey Mudd, MIT, Stanford, and Yale, in no particular order. Oh, and I applied to UMass Amherst too, almost as an afterthought. They didn't require an extra essay and they waived the application fee, so I figured why not?



I got denied from every single school



...except for UMass.



I wasn't outright denied from all those schools. Some of them waitlisted me first, and then promptly denied me once a more-qualified applicant accepted. I'd argue that this was actually worse. In retrospect, I was definitely a bit too idealistic. Sure, I had good grades, but I wasn't exactly a seven-sport athlete who had cured cancer by the age of four, which feels like the bare minimum these days in the increasingly ridiculous rat race of college admissions. It probably didn't help that my high school is ranked 226th in the state of Massachusetts (at least according to some random website I found). Anyway, the whole experience was wholly ego-crippling for 18-year old Brandon, who didn't realize the blessing in disguise that had been handed to him.

Here's the quite literal deal: UMass Amherst is a state school, and a good state school at that. It's also a Massachusetts state school. And 18-year old Brandon was a Massachusetts resident. This means he could go to school there for over $16,000 less each year than his out-of-state counterparts. This is a nice discount on a school that was already only half the price of the next priciest school he applied to. Further, Brandon's state test scores from like, middle school, qualified him for a state scholarship that covered all tuition for four years.

Wait what, free tuition for your whole college career? That sounds way too good to be true. Also, stop talking in third-person.

It's totally way too good to be true. Tuition is free, but state schools redefine tuition to be a small chunk of the cost of attendance. Still, an $857 discount per semester is icing on the already heavily-discounted cake. And so we're off to a good start.

Onwards, to College

My FAFSA made it clear I'd still be paying a few grand out of pocket each semester (because I was Decidedly Middle Class™ and all). So I applied for the highest-paying job on campus I could find: driving buses. I got the job and started training a few weeks into my college career. I set up a payment plan with the school every semester. I checked the loans I was taking every year and declined them when I thought I could pay the difference, especially when they were unsubsidized. I applied for every scholarship that seemed vaguely relevant. I eventually started developing software systems for the bus company and learned how to build pretty legit web apps. I took that knowledge and used it to do some independent contract-work. I graded Computer Science classes on the side. I paid down the compounding student loan interest whenever I had some extra money.

Driving a bus for perhaps the last time, to my own graduation. As is tradition.

Paying It Back

The party is over. It's June 2015 and I've graduated college. I shook some hands, hopped off the stage, threw my cap-and-gown aside, and hopped on a plane. At this point, I've already purchased and moved into The Box and settled into a nice routine. It's time to face the facts and figure out my finances. My loans have a six-month grace period before I have to start paying them, but since they've been compounding interest the entire time (including some of the subsidized ones as I found out, much to my chagrin), I figure I'll get started right away. Step one is figuring out how much I owe, and who I owe it to. You'd think this would be the simple part, but with all the emails and exit interviews and papers to sign and forms to fill out, it's easy to lose track. I didn't have any private/third-party loans, but I can only imagine it being that much more confusing.

Type Interest Rate Amount
Subsidized Stafford 3.4% $10,000
Subsidized Stafford 3.86% $4,292.50
Subsidized Stafford 4.66% $4,635
Federal Perkins 5% $1,000
Unsubsidized Stafford 6.8% $2,000

After all was said and done, I graduated college with $21,927.50 of debt. A large chunk of change to be sure, but that's not even half a year's tuition at a lot of brand-name schools, so I consider myself fortunate in that regard. I had already paid an additional $27,915.50 out of pocket during my four years, and another $772.29 went to interest. In total, my college education cost me $50,615.29.

My loan balances with respect to time. The large dips generally correspond to stock grants and bonuses.

Once I started working, paying the loans down became a game. Since my monthly expenses were (and still are, for that matter) virtually nil, what wasn't going into tax-advantaged accounts was split between my investment portfolio (75% VTI, 25% VXUS) and loans, in a ratio that changed depending on my mood and desire to see the debt graph (pictured above) head south. I funneled bonuses and stock grants to the cause, which correspond to the larger dips on the chart.

Lessons Learned

I'm incredibly fortunate in that I was able to pay off my debts in a relatively short period of time. Ironically, the largest factor that enabled me to do so was basically out of my control. At 18 years old, I would have chosen any other college on my list, had any of them accepted me. Given that they'd all have been at least twice the price, it follows that it'd have taken me twice as long (or longer). Worse still, I can't see how it would have been any better for me in the long run. It's easy for me to say this now, but I believe that you'll get out of school whatever you're willing to put into it, regardless of the brand name (and accompanying price tag).

After that initial decision of where to go, it really just comes down to looking your debt in the face and knowing everything about it. Who are the loans with? What interest rates do they have? Do they accumulate interest while you're in school? When do their grace periods end? How much will the monthly payment be? Which payment plan options do they offer? How much can you afford to pay? Are there any debt forgiveness programs for your profession? The more you know about the enemy, the more manageable they are.

As a parting note, though this post isn't all that timely given that I paid off my loans almost two months ago, it is timely because my more-symbolic-than-actually-to-be-taken-seriously savings clock has nearly reached the total volume of student debt I started with. So my (very approximate) rent savings alone nearly paid for my education. There's probably some more meaningful, deeply symbolic message to be extracted from that, but I'll leave that as an exercise to the reader.

*More info about the state of student loan debt in the US can be found here.

**I'm not bitter though. If I had had a college fund and hadn't had to work through college, I wouldn't have landed the jobs that gave me the experience that prepared me for my current (dream) job. There's always an upside.


Source: Thomas Carroll, though the fade was added by me. It's supposed to be a metaphor for the desire to shop/acquire an unnecessary gamut of nonsense dwindling away, or something like that.

It's been a while since I last lambasted any of the ideals that keep the American Economic Engine™ chuggin' along. I'm talkin' about things like "Exceptionalism", "Overconsumption", "Materialism", and any other ‑isms and ‑umptions you want to throw into the mix. Given my relative reticence on the topic, I thought it was high time I took some pot shots at Uncle Sam. Subsequently, I've spent a long time staring at this blank expanse of screen, musing over what edgy and Forced Witticisms™ I can put here. Strangely enough, nothing I put down feels particularly pleasing, probably because I don't think I have anything useful to say on the matter.

Making fun of how we do things in America just feels like low hanging fruit, or more fittingly, a cakewalk. It's a lumbering, slow moving target, weighed down by one too many Big Macs.* Plus, Wall-E already did it way better than I could anyway. So instead, I'm hoping it'll be slightly more productive to shift the focus and talk about how I personally make my purchasing decisions. Summing it all up in a flow chart that came out more complicated and less aesthetically-pleasing than I was hoping for:

Should I Buy that ShinyNewThing™?

If the chart is too small, you can find a bigger version here.

Before we get started, let me just say that this grossly idealistic decision-making process only really applies to buying stuff: physical objects that I plan on keeping around. It doesn't make sense for the necessities like food or toiletries, or experiences like trips and concerts. I'll maybe touch on that at the end.

Step 1 - Recognize the Reality

The starting point of my flow chart is:

Will you literally die if you don't make this purchase?

And the answer is No.

I put this at the tippity-top because it's important to go into a potential purchase with a properly prepped and calibrated cash compass. The fact of the matter? Life will go on even if you don't buy yourself that ShinyNewThing. If you're reading this, there's a healthy chance you live in a wealthy, developed nation and are not in any real risk of starving to death, or dying of a untreated illness. Whatever the object of your affections, however ravenously you find yourself drooling and hankering, your heart will not actually stop beating if you don't acquire it. The Earth will keep spinning. The sun will continue to turn hydrogen into heavier elements. And we'll all still be inhabiting a mote of dust, suspended in a sunbeam.

Step 2 - Check your Inventory

Okay, so you've got your heart set on acquiring ShinyNewThing. It glistens like a diamond and you get butterflies any time some of its calculatingly-crafted marketing material flutters past your eyes. It promises to be revolutionary, and improve your life in ways that you can't even begin to understand until you've got your hands wrapped around…whatever it is. But have you taken a good, hard look at what you've already got?

Personal Example: The Samsung Galaxy S7 is out. Compared to my current phone, the S7 has a higher-resolution screen, better cameras, a bigger battery, a faster processor with more cores, twice as much RAM, improved water-resistance, and supports quick charging. Not only will I be able to Snapchat at the speed of light, but this phone will improve my libido and cure most forms of cancer too. And to think, I could buy one with a single week of rent-savings. It seems like a no-brainer, so why haven't I tossed my dusty, worn down, three-year old phone out the (hopefully proverbial) window?

Because it still works.

Not only does it work, but it isn't any less functional just because a newer, better phone came out. It's not like Samsung released the S7 and suddenly every other phone developed crushing feelings of inadequacy and stopped working. If something I own already does the job for me, why would I be in the market for another one? I'm no worse off just because something newer and shinier exists. If I wasn't struggling to make do without it, why get it? Why be complicit an active agitator in a growing E-Waste problem? Why not allocate that money to some other more productive or actually useful area of my life?

But Brandon, what if the thing I already have is broken?

Well in that case, you've just found a great opportunity to learn something new. Do a bit of research and see if it's something you can fix yourself. The Internet is a pretty incredible resource as far as DIY/fix-it projects are concerned. Smartphone took a tumble? There's a decent chance you can fix your phone or laptop screen. Eyeing that new Keurig? See if you can unclog your old coffee maker. A new jacket tickling your fancy? You can probably fix the zipper on the one you just got. Personally, most of what I know about the innards of computers came from replacing dead hard drives and screens and upgrading RAM on my friends' old discarded computers and then using them for my own nefarious purposes. Why not breathe some new life into your possessions and gain a new skill while you're at it?

Brandon, you don't understand. The thing I already have is really, really, irreparably broken.

Perfect, now you have a chance to see if you can live without it. Sometimes you can't, and the answer will unequivocally be "No, I can't live without this because of my job/family/lifestyle/pet tarantula/whatever", and that's fine. But other times, maybe you'll realize that you're actually better off not replacing whatever broke. Maybe your life is simpler without it, or you have more free time because you're not so glued to it, or you just never really needed it in the first place.

A prime example from my life is a pocket projector I had for a few months, which I bought so my friends and I could watch movies in the truck (which we totally did). And that was all fine and dandy, but at the end of the day it was still just another device for me to charge and store and generally have to deal with. It didn't exactly break on me, so this isn't really the best example, but I ended up selling it and felt generally better off for having done it.

Setting up the projector for Truck or Treat™, where I had some friends over to watch Hocus Pocus on Halloween.

Step 3: Just Think About It

Too often we just jump into purchasing things without ever stopping to question what it means to us. We set our sights on some object of our desires, and buy it as soon as we can afford to. That's not hard-coded into our DNA though. It's not like we evolved the desire to buy stuff. We did, however, evolve mushy meat brains vulnerable to being manipulated in lucrative ways by carefully crafted marketing campaigns.** But if we take a step back and look at the decimals and dollars of it all, we can make a more informed decision about how important a purchase is to us.

Where does most of my money come from? Well, since I'm not (yet) retired, it comes from me spending a double-digit number of semi-waking hours each week doing assorted tasks for other people, being just proficient enough that they compensate me for it. I exchange my time for money via my job. Time goes in, money comes out. Simple. Since most of my money comes from my time-commitment to work, it makes sense (at least in my head) to view money as just a loose abstraction over my time, right? Everything I buy takes some non-zero amount of time for me to earn. Thinking about it this way, why would I want to throw my time away for things that aren't worth it? Why would I want to trade weeks or even months of my time for that ShinyNewThing? When will my rant/bombardment of rhetorical questions end?

To clarify: I enjoy my job. I genuinely do. That said, if money was taken out of the equation, it's unlikely I'd continue working the exact same number of hours I do now. If I had unlimited dollar dollar bills y'all, I'd definitely make a few changes in my day to day life, but I'll save those for another post. If you have other plans for your days besides working, why not use the money to make that a reality? As early retirement extraordinaire Mr. Money Mustache will gladly tell you: if you spend a dollar, it's gone forever. But if you invest a dollar, it's now working 24/7 to make you more money, usually through dividends or capital appreciation. And since money is basically time, you're creating more time for future you, which translates to more freedom in your work/life balance. So, at least from my perspective, instead of pouring time into getting that new 52 inch, 4K, 240 Hz, super flat-screen buzzword magic TV, it makes more sense to take those extra dollars and put them to work for me.

The thing is, at the end of the day, a flat-screen TV does nothing to make me a happier person. Neither does having a nicer car, or a shiny, carbon fiber road bicycle. And if it isn't making me happier, healthier, or just plain better as a person, it's not worth wasting my time/money on. Life is horrifically short in the scheme of things, and I'd rather build for my future and invest in experiences. ShinyNewThings eventually become DustyBasementFixtures, but experiences become fond memories. I guess that's my philosophy on spending money: invest in memories, not accessories.

*In my opinion, one Big Mac is approximately one too many Big Macs.

**The color red makes people hungrier. Luxury items cost whole, round number prices; discount items end in "99". Checkout aisles are full of impulsive items. There are entire college degrees dedicated to figuring out how to make people feel a certain way. Etc, etc.



Subscribe

If you want to get emailed when I write a post, add your email here. Don't worry, you can always unsubscribe.